[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libunwind] comments on libunwind proposal
Re: [libunwind] comments on libunwind proposal
Mon, 14 Jan 2002 22:46:23 -0800
>>>>> 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> 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> 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
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
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
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
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).