|
From: | Johan Walles |
Subject: | Re: [libunwind] Unwinding using the context passed to a signal handler (doesn't work) |
Date: | Thu, 25 Mar 2004 17:00:52 +0100 |
User-agent: | Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 |
Matthieu Delahaye wrote:
On Thu, Mar 25, 2004 at 11:04:34AM +0100, Johan Walles wrote:David Mosberger wrote:On Wed, 24 Mar 2004 10:53:12 +0100, Johan Walles <address@hidden> said:Johan> 1 foo() { Johan> 2 getcontext(); Johan> 3 } Johan> 4 Johan> 5 main() { Johan> 6 foo(); Johan> 7 } Johan> Inside of foo(), b0 will point to line 7. Wrong. On _entry_ to foo() b0 will point to line 7. After the call to getcontext(), b0 will point to line 3.My point is that "getcontext(&ctxt); ctxt.uc_mcontext.sc_br[0]" gives me the value 3 that b0 has inside of getcontext(), not the value 7 that b0 has inside of foo() (aka "the call site").This is false. At the return of getcontext() b0 is still to 3. AFAIK, b0 should be restored by the callee [It is a scratch register, not a preserved]. The only garanty that b0 is to 7 is at the _entry_ of the function, and at the return.
The value of b0 when getcontext() returns doesn't matter.My interpretation of "b0's value at the call site" is "the value of b0 just before the call was made". Right before getcontext() is called, b0 contains 7.
Johan> case UNW_IA64_IP: addr = &uc->uc_mcontext.sc_br[0]; break; This says is that the IP of the caller of getcontext() is stored in sc_br[0]. Could it be stored in sc_ip instead? Sure. What would it change? Absolutely nothing.What it would change is that I could then take a signal context that I get from the Linux kernel, fill in the missing registers, pass the result to unw_init_local() and get a complete stack trace, including the first stack frame. If this doesn't matter to you, could you please change it for my sake?There is something I don't understand. First you are complaining that the context you get is a machine-state you say is corresponding to a state inside of getcontext()
Yes.
[And thus after a step you get the one from foo()]
Yes.
, and now you want to use the context sended by the kernel,
Yes.
and add yourself the missing information so that by unwinding, you get foo() inside?
I don't understand this question. My problem is only this:When my program receives a SIGSEGV, the Linux kernel passes a sigcontext struct to my signal handler. Passing the contents of that struct to unw_init_local() makes libunwind miss / skip / whatever the function where the signal was received.
I want to know what I have to do to the sigcontext before I pass it to unw_init_local() if I want libunwind to give me a complete stack trace.
So far, the two suggestion I have gotten has been to fill in the rest of the registers (which either I'm doing wrong or doesn't help), and to use getcontext() and step using libunwind every time a signal is received (which I don't want to for performance reasons). There *must* be some sort of relation between the signal context I get from the kernel and the context I'm supposed to pass to libunwind.
So far, nobody has been able to explain that relation to me. Regards //Johan
[Prev in Thread] | Current Thread | [Next in Thread] |