Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* 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