* Gdb, PIE and scan_dyntag(DT_DEBUG)
@ 2014-03-25 20:43 Robert Jarzmik
2014-03-31 18:47 ` Jan Kratochvil
0 siblings, 1 reply; 5+ messages in thread
From: Robert Jarzmik @ 2014-03-25 20:43 UTC (permalink / raw)
To: gdb; +Cc: robert.jarzmik
Hello,
I'm pretty sure this was already covered somewhere, so a pointer would be great.
I have a problem with gdb not finding the shared library list when analyzing a
core dump of an ELF-X86-64 binary on Linux.
After putting traces here and there, it boils down to :
- the executable is placed at a random address (ASLR in linux)
- the displacement is correctly input in AUXV
- the linker base is not correctly computed
The trouble lies in the scan_dyntag(DT_DEBUG) called by elf_locate_base() for me
:
- it tries first target_ops=core_ops, and looks at non-displaced address of
.dynamic => failure => that's great
- it then tries target_ops=exec_ops, and looks at non-displaced address of
.dynamic => it succeeds, returning 0 => that's my problem
As the call succeeded, elf_locate_base() won't call scan_dyntag_auxv()
I manually "forced" elf_locate_base() to call scan_dyntag_aux() and then all my
shared libraries appear.
Could somebody tell me what's wrong in my core/executable/whatever, and why GDB
is looking at the executable file .dynamic section before attempting AUXV
AT_BASE reading and memory read accordingly ?
Cheers.
--
Robert
PS: I'm using GDB 7.6. If it was fixed later I'll happily cherry-pick the patch.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Gdb, PIE and scan_dyntag(DT_DEBUG)
2014-03-25 20:43 Gdb, PIE and scan_dyntag(DT_DEBUG) Robert Jarzmik
@ 2014-03-31 18:47 ` Jan Kratochvil
2014-03-31 22:57 ` Robert Jarzmik
0 siblings, 1 reply; 5+ messages in thread
From: Jan Kratochvil @ 2014-03-31 18:47 UTC (permalink / raw)
To: Robert Jarzmik; +Cc: gdb, robert.jarzmik
On Tue, 25 Mar 2014 21:43:22 +0100, Robert Jarzmik wrote:
> I have a problem with gdb not finding the shared library list when analyzing a
> core dump of an ELF-X86-64 binary on Linux.
The problem is it works for me. Tested on Fedora 20 x86_64 although I am not
aware of any distro-specific stuff which could affect this functionality.
It is also relevant to know prelink status but I have tested this
functionality now even with unprelinked ld.so and libc.so:
$ echo 'int main(void) { return *(volatile int *)0=0; }'|gcc -o segv -Wall -g -fPIE -pie -x c -;rm -f core.*;(ulimit -c unlimited;./segv);mv core.* segv.core;.../gdb -batch ./segv{,.core} -ex 'info sharedlibrary'
[...]
From To Syms Read Shared Object Library
0x00007f7ceda53560 0x00007f7cedb94bb4 Yes /lib64/libc.so.6
0x00007f7ceddf3b10 0x00007f7cede0cc70 Yes /lib64/ld-linux-x86-64.so.2
> The trouble lies in the scan_dyntag(DT_DEBUG) called by elf_locate_base() for me
> :
> - it tries first target_ops=core_ops, and looks at non-displaced address of
> .dynamic => failure => that's great
> - it then tries target_ops=exec_ops, and looks at non-displaced address of
> .dynamic => it succeeds, returning 0 => that's my problem
It returns the proper displacement for me. exec_bfd gets relocated to its
proper address during:
#1 in objfile_relocate1 (objfile=0x602c00003680, new_offsets=0x7fffffffcec0) at objfiles.c:819
#2 in objfile_relocate (objfile=0x602c00003680, new_offsets=0x7fffffffcec0) at objfiles.c:843
#3 in svr4_relocate_main_executable () at solib-svr4.c:2882
#4 in svr4_solib_create_inferior_hook (from_tty=1) at solib-svr4.c:2926
#5 in solib_create_inferior_hook (from_tty=1) at solib.c:1200
#6 in post_create_inferior (target=0x3d9e9a0 <core_ops>, from_tty=1) at infcmd.c:442
#7 in core_open (filename=0x6006000138a0 "/home/jks", from_tty=1) at corelow.c:412
#8 in core_file_command (filename=0x7fffffffdd5d "./segv.core", from_tty=1) at corefile.c:81
You should check why svr4_exec_displacement() does not work in your case.
> As the call succeeded, elf_locate_base() won't call scan_dyntag_auxv()
>
> I manually "forced" elf_locate_base() to call scan_dyntag_aux() and then all my
> shared libraries appear.
Yes but exec_bfd probably remains wrongly (=not) relocated.
> why GDB is looking at the executable file .dynamic section before attempting
> AUXV AT_BASE reading and memory read accordingly ?
I do not know answer to this question now but it should work anyway.
Jan
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Gdb, PIE and scan_dyntag(DT_DEBUG)
2014-03-31 18:47 ` Jan Kratochvil
@ 2014-03-31 22:57 ` Robert Jarzmik
2014-04-01 6:48 ` Jan Kratochvil
0 siblings, 1 reply; 5+ messages in thread
From: Robert Jarzmik @ 2014-03-31 22:57 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb, robert.jarzmik
Jan Kratochvil <jan.kratochvil@redhat.com> writes:
> On Tue, 25 Mar 2014 21:43:22 +0100, Robert Jarzmik wrote:
>> I have a problem with gdb not finding the shared library list when analyzing a
>> core dump of an ELF-X86-64 binary on Linux.
>
> The problem is it works for me. Tested on Fedora 20 x86_64 although I am not
> aware of any distro-specific stuff which could affect this functionality.
> It is also relevant to know prelink status but I have tested this
> functionality now even with unprelinked ld.so and libc.so:
OK, you're right.
I finally found the culprit : in my case, it was the linker and strip
discrepency.
To be more precise, the ELF program headers of the unstripped binary and the
stripped binary didn't match, as in the unstripped one the .bss section was
aligned (fileoffset wise) on 8 bytes, while in the stripped version it was
aligned on 4 (as the .bss section alignement).
This was creating different filesizes for the segment containing the .bss
section, and therefore gdb's svr4_relocate_*() function was lost and did not
relocate my PIE executable.
GDB was right, it's the linker which was faulty in my case.
Cheers.
--
Robert
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Gdb, PIE and scan_dyntag(DT_DEBUG)
2014-03-31 22:57 ` Robert Jarzmik
@ 2014-04-01 6:48 ` Jan Kratochvil
2014-04-01 21:00 ` Robert Jarzmik
0 siblings, 1 reply; 5+ messages in thread
From: Jan Kratochvil @ 2014-04-01 6:48 UTC (permalink / raw)
To: Robert Jarzmik; +Cc: gdb, robert.jarzmik
On Tue, 01 Apr 2014 00:56:59 +0200, Robert Jarzmik wrote:
> To be more precise, the ELF program headers of the unstripped binary and the
> stripped binary didn't match,
In general eu-strip (from elfutils; compared to binutils strip) is more
preserving the binaries when they still should match each other.
And Fedora is using eu-strip for the debug info packages separation.
IIRC I have seen some other distro using regular strip for it.
Jan
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Gdb, PIE and scan_dyntag(DT_DEBUG)
2014-04-01 6:48 ` Jan Kratochvil
@ 2014-04-01 21:00 ` Robert Jarzmik
0 siblings, 0 replies; 5+ messages in thread
From: Robert Jarzmik @ 2014-04-01 21:00 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb, robert.jarzmik
Jan Kratochvil <jan.kratochvil@redhat.com> writes:
> On Tue, 01 Apr 2014 00:56:59 +0200, Robert Jarzmik wrote:
>> To be more precise, the ELF program headers of the unstripped binary and the
>> stripped binary didn't match,
>
> In general eu-strip (from elfutils; compared to binutils strip) is more
> preserving the binaries when they still should match each other.
> And Fedora is using eu-strip for the debug info packages separation.
> IIRC I have seen some other distro using regular strip for it.
And you're damn right about it. I checked the Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
*** unstripped app_process ***
[Requesting program interpreter: /system/bin/linker64]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000001788 0x0000000000001788 R E 1000
LOAD 0x0000000000001c20 0x0000000000002c20 0x0000000000002c20
0x00000000000003e0 0x00000000000003e8 RW 1000
*** binutils strip passed app_process ***
[Requesting program interpreter: /system/bin/linker64]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000001788 0x0000000000001788 R E 1000
LOAD 0x0000000000001c20 0x0000000000002c20 0x0000000000002c20
0x00000000000003d8 0x00000000000003e8 RW 1000
*** elfutils eu-strip passed app_process ***
[Requesting program interpreter: /system/bin/linker64]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000001788 0x0000000000001788 R E 1000
LOAD 0x0000000000001c20 0x0000000000002c20 0x0000000000002c20
0x00000000000003e0 0x00000000000003e8 RW 1000
So eu-strip makes my day :)
Thanks for the info, I didn't know there was a difference in strip between
binutils and elfutils.
Cheers.
--
Robert
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-04-01 21:00 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-25 20:43 Gdb, PIE and scan_dyntag(DT_DEBUG) Robert Jarzmik
2014-03-31 18:47 ` Jan Kratochvil
2014-03-31 22:57 ` Robert Jarzmik
2014-04-01 6:48 ` Jan Kratochvil
2014-04-01 21:00 ` Robert Jarzmik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox