|
From: Tom H. <to...@co...> - 2006-03-07 14:28:28
|
In message <114...@po...>
Patrick Ohly <pat...@in...> wrote:
> In gdb, I see:
>
> #0 0x04148034 in __libc_write () from /lib/i686/libc.so.6
> #1 0x040469b8 in __DTOR_END__ () from /lib/i686/libpthread.so.0
> #2 0x0403f37d in __pthread_create_2_1 (thread=0xbefe9e30, attr=0x0,
> start_routine=0x8048520 <threadhandler>, arg=0x0) at pthread.c:673
I wonder how it is doing that...
> I'm not sure about this _DTOR_END__ and how the program ended up there.
> 0x403aa1c contains:
> 0x0403aa1c: jmp *0x18(%ebx)
That's the PLT entry that links the two shared libraries together
at a guess.
> These are the standard libraries as included in RH AS2.1 and I
> am not sure how exactly those are built, but the gcc 2.96 in that
> release does not use DWARF by default. I suppose readelf should
> be able to tell me what is really contained in
> /lib/i686/libpthread-0.9.so but I need some guidance what to
> watch out for - I have never dealt with debug information at
> that level.
>
> Regarding frame pointers, __pthread_create_2_1 starts with the
> usual code for frame pointers:
> #2 0x0403f37d in __pthread_create_2_1 (thread=0xbefe9e30, attr=0x0,
> start_routine=0x8048520 <threadhandler>, arg=0x0) at pthread.c:673
> Line number 673 out of range; pthread.c has 15 lines.
> (gdb) disass
> Dump of assembler code for function __pthread_create_2_1:
> 0x0403f2f0 <__pthread_create_2_1+0>: push %ebp
> 0x0403f2f1 <__pthread_create_2_1+1>: mov %esp,%ebp
> 0x0403f2f3 <__pthread_create_2_1+3>: push %esi
> 0x0403f2f4 <__pthread_create_2_1+4>: push %ebx
> 0x0403f2f5 <__pthread_create_2_1+5>: sub $0xa0,%esp
> ...
>
> libc however apparently is not compiled with frame pointers,
> unless I misinterpret something here:
> (gdb) disass __libc_write
> Dump of assembler code for function __libc_write:
> 0x04148020 <__libc_write+0>: push %ebx
> 0x04148021 <__libc_write+1>: mov 0x10(%esp,1),%edx
> 0x04148025 <__libc_write+5>: mov 0xc(%esp,1),%ecx
> 0x04148029 <__libc_write+9>: mov 0x8(%esp,1),%ebx
> 0x0414802d <__libc_write+13>: mov $0x4,%eax
> 0x04148032 <__libc_write+18>: int $0x80
> 0x04148034 <__libc_write+20>: pop %ebx
> ...
That is the problem then - as __libc_write does not construct a
stack frame, the PC will appear to be in that routine but when the
stack is unwound we will wind up in the caller of __pthread_create_2_1.
When there are no frame pointers unwinding the stack is hard (there
are tricks but I didn't realise gdb used them) unless the debug
info tells you how, and stabs can't do that (DWARF can).
The debugger we use (ups) does have tricks for unwinding the stack
when there is no frame pointer by searching the stack looking for
an address which appears to map to a call instruction targeting
the current routine - my colleague wrote the code in question and
it has been maintained by me more recently. That is really horrible
stuff though.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|