[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libunwind] comments on libunwind proposal

From: David Mosberger
Subject: Re: [libunwind] comments on libunwind proposal
Date: Mon, 14 Jan 2002 22:46:23 -0800

Hi Jim,

>>>>> On Mon, 14 Jan 2002 21:32:56 -0800, Jim Wilson <address@hidden> said:

  Jim> The terminology is confusing.  The C++ ABI and IA-64 psABI both
  Jim> define an Unwind Library interface.  I have never heard the
  Jim> term "unwind API" used to refer to anything but that, but now
  Jim> you are using it for something else.

Not really.  The proposed API provides a superset of the functionality
defined by the C++/psABI unwind interface.  But since it's much more
flexible, it is (slightly) architecture specific (i.e., a small amount
of platform-specific glue logic is required to implement the C++/psABI
interface on top of the proposed API).

But if you have a suggestion for a better name, I'm all ears.

  Jim> The Unwind API defined by
  Jim> the C++ ABI and IA-64 psABI is a high level interface designed
  Jim> to be called by a C++ language front end.  It contains
  Jim> functions like _Unwind_RaiseException and _Unwind_Resume.


  Jim> What
  Jim> you have implemented is a low level library that is intended to
  Jim> read IA-64 unwind info sections, and use this info for stack
  Jim> unwinding.  In gcc, we call this the IA-64 (stack) unwinder.

No, the proposed API is 99% independent of the architecture.  The
current implementation *is* IA-64 specific, but that's just because I
can't do everything on my own.  I'd love to see, e.g., x86 and Alpha

  Jim> Gcc incidentally already uses the (C++ ABI) Unwind API for all
  Jim> targets.


  Jim> But that is irrelevant, since you aren't implementing
  Jim> the Unwind API.

It's not irrelevant. Like I said in the announcement, implementing the
C++ Unwind API based on the proposed lower-level API is one of the
next steps.

  Jim> Beneath the Unwind API, we have 3 different
  Jim> unwinders, the setjmp/longjmp unwinder, the dwarf2 unwinder,
  Jim> and the IA-64 unwinder.  The last one is comparable to what you
  Jim> are implementing.  A generic unwinder library will be more
  Jim> useful if it supports all unwind info formats, and not just the
  Jim> IA-64 unwind info format.

Of course.  I'm not sure setjmp/longjmp can be supported, but any
unwind format that describes the full "preserved" state of the machine
can be.

  Jim> Your current implementation looks like you just took the kernel
  Jim> unwinder you wrote and made it into a library.

You make it sound like that's a bad thing! ;-)

I certainly tried to leverage as much as possible from existing code
(both the kernel unwinder and the current GCC unwinder), but
unfortunately, libunwind will be sufficiently different from the
kernel unwinder that it may not make sense to use libunwind as the
kernel unwinder (I think it would be possible to do so, but the code
would become so abstract that it would be difficult to comprehend;
perhaps I'm wrong, but for now I'm not making an effort to make
libunwind usable by the kernel).

  Jim> The current gcc
  Jim> IA-64 unwinder is based on your kernel unwinder, with
  Jim> modifications and additions necessaary to make it work with the
  Jim> Unwind API.

Yes, unfortunately the GCC IA-64 unwinder doesn't have all the
facilities needed for the *other* applications of stack unwinding,
such as backtrace() generation, debugging (via ptrace()), and so on.

  Jim> I think it would be worthwhile for you to look the
  Jim> gcc implementation.

I'm well aware of the GCC unwinder and its limitations (and strengths).

  Jim> Incidentally, the hardest part of the gcc
  Jim> implmentation was restoring an old stack state sufficiently to
  Jim> resume execution using it.  This is something that your current
  Jim> kernel unwinder does not support.

The kernel unwinder doesn't, but libunwind does.  Actually, I haven't
decided yet how to handle r14-r17, which are treated specially by the
C++ ABI (to pass arguments to the landing pad).

  Jim> Since we already have the
  Jim> code in gcc, it may not be worth the effort of writing another
  Jim> one.

libunwind-0.0 has that code, too.  Just look for unw_resume().

  Jim> The gcc one is about 200 lines of IA-64 assembly code.

In libunwind, it is all in C, isn't that nicer?  (OK, it relies on
setcontext(), but writing that code once is enough, IMHO.)

  Jim> The gcc IA-64 unwinder incidentally has already been
  Jim> extensively tested.  Richard Henderson did most of the work for
  Jim> the current gcc IA-64 unwinder implementation.

And Hans Boehm has uncovered several problems when using GCJ.  For
example, NaT bits are not handled properly.  Unwinding across signals
is another issue that's difficult to get right (in the general case).
There were some serious bugs which made the unwinder fail completely.
As far as we could tell, the GCC IA-64 unwinder is effectively
unmaintained.  This is not surprising, but I'm pointing it out because
it shows that there really is the need for a single, maintained unwind
library that can be used for more than just exception handling.

  Jim> Putting the unwinder library in glibc is problematic, since
  Jim> glibc does not exist everywhere we need it.

I'm not planning on putting it in glibc.  I considered that but
concluded that it would only complicate matters.  I'm not sure what
the best solution for GCC is.  I know that there were long discussions
as to whether libgcc could be made a shared library.  I don't know
what the exact issues where, but I imagine libunwind would have
similar issues.  Your suggestions would definitely be welcome.

  Jim> Gcc still needs
  Jim> the unwinder, even when we compile it on HPUX, BSD, and other
  Jim> non-linux operating systems that do not use glibc.

Absolutely.  And it's not just GCC.  For example, I'd like to use the
library in the Ski simulator, so it can do backtraces in simulated

  Jim> It would be
  Jim> useful to have an IA-64 unwinder outside gcc so that gdb can
  Jim> use it too; it just doesn't work to put it in glibc.


  Jim> Your current unwinder implementation defines routines like
  Jim> "unw_get_reg".  Making these routines available to the user
  Jim> means exporting them, and that means we have conflicts with the
  Jim> user namespace.  You may want to consider using names outside
  Jim> the user namespace, like the Unwind API does.  These functions
  Jim> will be present in most applications since the IA-64 unwinder
  Jim> gets pulled into almost everything by the compiler.  The user
  Jim> can't avoid name space clashes by choosing not to use the IA-64
  Jim> unwinder library, so we are better off if these function names
  Jim> aren't in the user namespace to begin with.

Yes, naming is one of the issues that has not been settled yet.  The
challenge is that I expect there to be at least two implementations of
the unwind API: one will support only local unwinding (i.e.,
unw_init_remote() would return an error) and the other will support
both local and "remote" unwinding (both unw_init_local() and
unw_init_remote() are supported).  Apart from naming, multiple
implementations also raise the issue of how to handle global state
(such as an unwind info cache) when an application ends up linking in
both implementations.

Another issue that is not fully addressed yet is thread-safety.  I
believe this is mostly an implementation issue, though there may be
some deadlock issues (e.g., when managing a global cache) which may
affect the API.

A final issue is memory management: stack unwinding sometimes requires
allocating additional memory and it may not be possible to use
malloc() or the like for this purpose because the unwinding may have
been triggered by an out-of-memory condition.  For the ia64
implementation, my plan is to use mmap() to allocate memory with page
granularity so as to minimize dependencies on other libraries (and the
locking-constraints that may come with it).


reply via email to

[Prev in Thread] Current Thread [Next in Thread]