Re: [patch] Re: longjmp handling vs. glibc LD_POINTER_GUARD problems

Pedro Alves
2008-05-21T22:40:12Z

A Wednesday 21 May 2008 23:15:48, Daniel Jacobowitz wrote:
>> This is the same problem as software watchpoints... I just don't think
> we're going to be able to get it to work. I certainly had to do
> horrible things on powerpc-linux when I wanted to be able to backtrace
> from epilogues without a symbol table.

> Which frame IDs are we comparing here?

I tried comparing the frame id of longjmp itself with with the
current frame first:

- record the longjmp frame when the longjmp breakpoint is hit.
- single-step until that frame is gone from the frame stack

Then (the logs I posted) tried comparing the longjmp's caller with
the the current frame while single stepping.

- record the longjmp's caller frame when the longjmp breakpoint
is hit.
- single-step until that frame is either current, or gone from the
frame stack.

Both gave the same results.

> I think we can assume that longjmp is not going to change
> stacks until it's about to return,
> although the return might be on a different stack entirely.

> I suspect we'll be prone to stopping in the last instruction or two of
> longjmp, instead of returning the compiler.

The point where the stepping stops is exactly the point
where the stacks change on x86_64.

(gdb) up
#1 0x00007fab4b544ee3 in siglongjmp () from /lib/libc.so.6
(gdb)
#2 0x000000000040069f in main ()
at ../../../src/gdb/testsuite/gdb.base/longjmp.c:99
99 longjmp (env, 1); /* patt1 */
(gdb) si
0x00007fab4b544f33 in ?? () from /lib/libc.so.6
(gdb) up
#1 0x000000000040067d in main ()
at ../../../src/gdb/testsuite/gdb.base/longjmp.c:96
96 if (setjmp (env) == 0)

With the patch installed, it's stopping exactly at
0x00007fab4b544f33.

Seeing this, I was thinking of:
- recording the longjmp frame when the longjmp breakpoint is hit
- single-step until the longjmp frame is gone (going to return to setjmp --
SP/FP changing)
- single-step until this new current frame is gone.

But, x86 doesn't show any promise on that... The first time
we stop seeing the longjmp frame on the frame stack is much
earlier than the exit of longjmp:

#0 0xf7e201d8 in ?? () from /lib32/libc.so.6
#1 0x00000001 in ?? ()
#2 0xf7e201c9 in ?? () from /lib32/libc.so.6
#3 0xf7f3fff4 in ?? () from /lib32/libc.so.6
#4 0xfff7bbe8 in ?? ()
#5 0xf7e2013c in siglongjmp () from /lib32/libc.so.6
Backtrace stopped: frame did not save the PC

Looks like a dead end.

--
Pedro Alves