[Top][All Lists]

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

Re: [libunwind] Unwinding using the context passed to a signal handler (

From: David Mosberger
Subject: Re: [libunwind] Unwinding using the context passed to a signal handler (doesn't work)
Date: Thu, 25 Mar 2004 09:29:56 -0800

>>>>> On Thu, 25 Mar 2004 11:04:34 +0100, Johan Walles <address@hidden> said:

  Johan> If I re-phrase my question thusly; if I have a signal
  Johan> context, what should I do with it to be able to pass it to
  Johan> libunwind and have libunwind give me all stack frames,
  Johan> including the first one?

This is simply not possible at the moment.

  Johan> Filling in all the missing registers doesn't help, as
  Johan> libunwind expects to find the IP in sc_br[0], but the Linux
  Johan> kernel gives me a context where the IP is stored in sc_ip.
  Johan> How do I convert between a struct sigcontext and an
  Johan> ucontext_t?

It's not possible.  The signal-context will contain the scratch
registers, which libunwind's unw_init_local() would happily ignore.
This is why I have been saying that all this discussion about sc_ip vs
sc_br[0] are futile.  The real issue is deeper and has to do with the
funddamental differences between a synchronous and asynchronous

  Johan> Could you post an example of how my unwind.c could be
  Johan> modified to do that very conversion correctly?

It would require a non-trivial extension of libunwind.  What we
_could_ do is to extend the meaning of the sc_flags member so it
indicates whether it is a synchronous (think getcontext()) or
asynchronous (think signal) context.  In the latter case, there would
also have to be an implicit or explicit way of telling that the
preserved registers are also in the context.

With this in place, it would then be possible to extend
unw_init_local() so it works for both synchronous and asynchronous

In addition to this complexity, maintaining backwards compatibility
would be challenging.  For example, the libc's getcontext() doesn't
touch sc_flags at all.

In contrast, the clean, working, and fully supported method of
starting unwind in a signal context is to do unw_getcontext() at the
beginning of the signal handler and then to do one extra unw_step().

>>>>> On Thu, 25 Mar 2004 17:00:52 +0100, Johan Walles <address@hidden> said:

  Johan> I want to know what I have to do to the sigcontext before I
  Johan> pass it to unw_init_local() if I want libunwind to give me a
  Johan> complete stack trace.

  Johan> So far, the two suggestion I have gotten has been to fill in
  Johan> the rest of the registers (which either I'm doing wrong or
  Johan> doesn't help),

It doesn't help.

  Johan> and to use getcontext() and step using libunwind every time a
  Johan> signal is received (which I don't want to for performance
  Johan> reasons).

Can you tell me what the performance issue is?  Is it that you get
lots of signals but need to unwind only occasionally?  If so,
unw_getcontext() would be the performance-critical operation (not
unw_init_local()).  I already sped up unw_getcontext() in the latest
source code by removing the unnecessary sigprocmask() system call.
Another thing that I'm likely to do is to add some prefetch
instructions to improve the performance when the memory for
unw_context_t is not in cache.  Another tweak that might be possible
is to move the "flushrs" instruction out of unw_getcontext() and into


reply via email to

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