Bug 1022193 - Unable to debug dynamic loader when LD_TRACED_LOADED_OBJECTS env var is set.
Unable to debug dynamic loader when LD_TRACED_LOADED_OBJECTS env var is set.
Status: CLOSED NOTABUG
Product: Fedora
Classification: Fedora
Component: gdb (Show other bugs)
19
Unspecified Unspecified
unspecified Severity unspecified
: ---
: ---
Assigned To: Jan Kratochvil
Fedora Extras Quality Assurance
: Reopened
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2013-10-22 12:42 EDT by Carlos O'Donell
Modified: 2013-10-22 15:42 EDT (History)
6 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2013-10-22 15:42:53 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Carlos O'Donell 2013-10-22 12:42:48 EDT
Description of problem:
Unable to debug dynamic loader when LD_TRACED_LOADED_OBJECTS env var is set. The breakpoint set at _start is not stopped at.

Version-Release number of selected component (if applicable):
gdb-7.6.1-42.fc19.x86_64

How reproducible:
Attempt to debug the dynamic loader startup with the environment variable LD_TRACE_LOADED_OBJECTS defined. In this case I'm debugging a newly built dynamic loader from upstream glibc.

Steps to Reproduce:
bash-4.2$ gdb /home/carlos/build/glibc/elf/ld.so 
GNU gdb (GDB) Fedora 7.6.1-42.fc19
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/carlos/build/glibc/elf/ld.so...done.
(gdb) break _start
Breakpoint 1 at 0x11e0
(gdb) r
Starting program: /home/carlos/build/glibc/elf/ld.so 

Breakpoint 1, 0x00005555555551e0 in _start ()
(gdb) set env LD_TRACE_LOADED_OBJECTS 1
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/carlos/build/glibc/elf/ld.so 
	linux-vdso.so.1 =>  (0x00007ffff7ffd000)
	libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003d6e000000)
	libdl.so.2 => /lib64/libdl.so.2 (0x0000003d58800000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003d58000000)
	/lib64/ld-linux-x86-64.so.2 (0x0000003d57c00000)
During startup program exited normally.
(gdb) unset env LD_TRACE_LOADED_OBJECTS
(gdb) r
Starting program: /home/carlos/build/glibc/elf/ld.so 

Breakpoint 1, 0x00005555555551e0 in _start ()
(gdb) quit
A debugging session is active.

	Inferior 1 [process 32132] will be killed.

Quit anyway? (y or n) y
bash-4.2$ 

Actual results:
The breakpoint at _start is not hit when trace mode is enabled.

Expected results:
The breakpoint at _start should always be hit regardless of the mode it's the entry point to the loader.


Additional info:
This prevents me from debugging all of the startup modes in the dynamic loader.
Comment 1 Carlos O'Donell 2013-10-22 12:55:21 EDT
Working around this by not setting the env var, breaking in process_envvars in the loader and manually manipulating the mode state. It's not what I'd like to do since it requires touching the internal state of the loader, but this is well contained code at this point.
Comment 2 Jan Kratochvil 2013-10-22 13:07:10 EDT
Use exec-wrapper env.  You are modifying the shell used to start the inferior, GDB at least expects the shell will behave sane.


$ gdb -q /lib64/ld-linux-x86-64.so.2 
done.
(gdb) set exec-wrapper env LD_TRACE_LOADED_OBJECTS=1
(gdb) b _start
Breakpoint 1 at 0x3000001420
(gdb) run /bin/true
Starting program: /lib64/ld-linux-x86-64.so.2 /bin/true
Breakpoint 1, 0x0000555555555420 in _start ()
(gdb) c
Continuing.
	linux-vdso.so.1 =>  (0x00007ffff7ffd000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003030400000)
	/lib64/ld-linux-x86-64.so.2 (0x0000555555554000)
[Inferior 1 (process 29183) exited normally]
(gdb)
Comment 3 Carlos O'Donell 2013-10-22 14:54:51 EDT
Reopening to ask some more questions.

(In reply to Jan Kratochvil from comment #2)
> Use exec-wrapper env.  You are modifying the shell used to start the
> inferior, GDB at least expects the shell will behave sane.

Talking about a shell is an implementation defined detail for gdb.

The result of `help set env' says:
"Set environment variable value to give the program."

Why does this impact my ability to debug the inferior?

I appreciate the use of the exec-wrapper workaround, but it's still a workaround.

What expectations does gdb have that aren't being met?

As an upstream glibc maintainer I'd be more than happy to work out something where it's *easy* to debug the dynamic loader rather than requiring anything complicated.
Comment 4 Jan Kratochvil 2013-10-22 15:08:44 EDT
(In reply to Carlos O'Donell from comment #3)
> The result of `help set env' says:
> "Set environment variable value to give the program."

This is true for normal users.  GDB users are not expected to be ld.so developers.


> Why does this impact my ability to debug the inferior?
+
> What expectations does gdb have that aren't being met?

Shell compiled into GDB due to its compile-time configuration
  #define STARTUP_WITH_SHELL 1
failed to start the inferior.

When you build your own GDB having this symbol undefined it may work without the env wrapper.


> As an upstream glibc maintainer I'd be more than happy to work out something
> where it's *easy* to debug the dynamic loader rather than requiring anything
> complicated.

Before GDB supported PIE it really was not easy to debug ld.so.  Using one "set exec-wrapper env" command for debugging something so special like ld.so I do not find anyhow bad. Moreover the reasons are known and it seems correct to me.


Leaving the Bug open but I do not plan to work on it myself.
Comment 5 Carlos O'Donell 2013-10-22 15:42:53 EDT
(In reply to Jan Kratochvil from comment #4)
> (In reply to Carlos O'Donell from comment #3)
> > The result of `help set env' says:
> > "Set environment variable value to give the program."
> 
> This is true for normal users.  GDB users are not expected to be ld.so
> developers.
 
The difference is pedantic, we should still strive to make it easy to debug any program including the dynamic loader.
 
> > Why does this impact my ability to debug the inferior?
> +
> > What expectations does gdb have that aren't being met?
> 
> Shell compiled into GDB due to its compile-time configuration
>   #define STARTUP_WITH_SHELL 1
> failed to start the inferior.

Thanks, I read the code and understand now what STARTUP_WITH_SHELL does and what implications it has for debugging with environment variables that modify the runtime.

> When you build your own GDB having this symbol undefined it may work without
> the env wrapper.

... and that also has it's own problems.
 
> > As an upstream glibc maintainer I'd be more than happy to work out something
> > where it's *easy* to debug the dynamic loader rather than requiring anything
> > complicated.
> 
> Before GDB supported PIE it really was not easy to debug ld.so.  Using one
> "set exec-wrapper env" command for debugging something so special like ld.so
> I do not find anyhow bad. Moreover the reasons are known and it seems
> correct to me.

After reading the code and the features STARTUP_WITH_SHELL enables, I agree with you, even if I wish I didn't need the extra step.

I'll document this in the glibc wiki.

Thanks for talking it through Jan, I appreciate your time and knowledge.

Note You need to log in before you can comment on or make changes to this bug.