libunwind-devel
[Top][All Lists]
Advanced

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

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


From: Johan Walles
Subject: Re: [libunwind] Unwinding using the context passed to a signal handler (doesn't work)
Date: Tue, 23 Mar 2004 13:15:09 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624

Johan Walles wrote:
I'm trying to create a stack dump from inside a signal handler. The context I'm using is the one passed as the third parameter to the signal handler. I'm doing this on Linux / ia64 using libunwind 0.96.

This is the output from the program:
"
printStackTrace(): Got context at 0x60000fffffffae50
  0: 0x4000000000001f30: main()
  1: 0x200000000008c560: __libc_start_main()
  2: 0x4000000000001500: _start()
printStackTrace(): Got context at 0x60000fffffffa310
  0: 0x4000000000001ce0: crashhandler()
  1: 0xa0000000000040d0: Unknown
  2: 0x4000000000001ec0: crash()
  3: 0x4000000000001f30: main()
  4: 0x200000000008c560: __libc_start_main()
  5: 0x4000000000001500: _start()
"

Note that the function that crashes (crash()) isn't part of the first stack trace (initialized using the context passed to the signal handler).

Why isn't it? And if I want that, what should I do? Am I using libunwind correctly?

To answer my own question, what happens here is the following (this has nothing to do with what registers are filled in or not):

1. Calling unw_getcontext() is the same as just calling libc's getcontext().

2. getcontext() on Linux / ia64 returns the context *inside the getcontext() function*, not the context at the place from where getcontext() is called (which is what I always thought it did).

3. To compensate for this, unw_init_local() starts by unwinding the context it receives by one frame. Thus, unwinding the stack after doing unw_init_local(getcontext()) will get me a backtrace starting from the current frame, rather than from the inside of getcontext().

In the signal handler case, the signal handler receives as parameter the context as it looked at the time the signal was received. If you pass that to unw_init_local(), it'll start by skipping the frame where the signal was received. This (rather than all registers not being filled in) is why the attached program didn't work.

So some things that I think should be changed are:

1. The unw_getcontext() man page says:

"The unw_getcontext() routine initializes the context structure pointed to by ucp with the machine-state of the call-site."

This is how I think it should be working, but isn't in fact how it works in reality. IMO, the man page is correct, and the implementation should be fixed.

2. The unw_init_local() man page says:

"The unw_init_local() routine initializes the unwind cursor pointed to by c with the machine-state in the context structure pointed to by ctxt. As such, the machine-state pointed to by ctxt identifies the initial stack frame at which unwinding starts."

Again, this is how I think it should be working, but isn't in fact how it works in reality. IMO, this man page is correct as well, and the implementation should be fixed.

  Regards //Johan



reply via email to

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