Bug 9436

Summary: gdb cannot break on entry point for statically linked binaries
Product: gdb Reporter: xt28
Component: breakpointsAssignee: Jan Kratochvil <jan.kratochvil>
Status: RESOLVED FIXED    
Severity: normal CC: drow, gdb-prs, jan.kratochvil, stephenma, xt28
Priority: P3    
Version: 7.1   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description xt28 2007-10-11 09:38:01 UTC
[Converted from Gnats 2331]

When debugging a statically linked binary, setting a breakpoint at the program's entry point does not work, i.e. the breakpoint is set, but execution does not stop at the breakpoint.

Release:
gdb 6.7.50_20071011

Environment:
$ uname -a
Linux x20 2.6.20-16-generic #2 SMP Sun Sep 23 19:50:39 UTC 2007 i686 GNU/Linux

$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 (Ubuntu 4.1.2-0ubuntu4)

GDB config line:
This GDB was configured as "i686-pc-linux-gnu"...

How-To-Repeat:
See the following transcript:

$ ./gdb /sbin/ldconfig 
GNU gdb 6.7.50_20071011
Copyright (C) 2007 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 "i686-pc-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) info files
Symbols from "/sbin/ldconfig".
Local exec file:
        `/sbin/ldconfig', file type elf32-i386.
        Entry point: 0x8048110
        0x080480d4 - 0x080480f4 is .note.ABI-tag
        0x080480f4 - 0x0804810b is .init
        0x08048110 - 0x080b84c8 is .text
        [...]
        0x080d7400 - 0x080d7ba8 is .data
        0x080d7bc0 - 0x080d9b68 is .bss
        0x080d9b68 - 0x080d9b7c is __libc_freeres_ptrs
(gdb) break *0x8048110
Breakpoint 1 at 0x8048110
(gdb) run
Starting program: /sbin/ldconfig 
(no debugging symbols found)
/sbin/ldconfig: Can't create temporary cache file /etc/ld.so.cache~: Permission denied

Program exited with code 01.
(gdb) quit

====

I compiled the current gdb from source, but did not install it or any libraries.

$ ldd ./gdb
        linux-gate.so.1 =>  (0xffffe000)
        libncurses.so.5 => /lib/libncurses.so.5 (0xb7eae000)
        libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7e87000)
        libexpat.so.1 => /usr/lib/libexpat.so.1 (0xb7e66000)
        libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7e62000)
        libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d21000)
        /lib/ld-linux.so.2 (0xb7f01000)
        libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7d0a000)
Comment 1 drow@false.org 2007-10-11 13:44:38 UTC
From: Daniel Jacobowitz <drow@false.org>
To: xt28@gmx.de
Cc: gdb-gnats@sources.redhat.com
Subject: Re: breakpoints/2331: gdb cannot break on entry point for
	statically linked binaries
Date: Thu, 11 Oct 2007 09:44:38 -0400

 On Thu, Oct 11, 2007 at 09:32:23AM -0000, xt28@gmx.de wrote:
 > When debugging a statically linked binary, setting a breakpoint at
 > the program's entry point does not work, i.e. the breakpoint is set,
 > but execution does not stop at the breakpoint.
 
 Unfortunately, this is a known problem.  GDB does not check for
 breakpoints before the first resume.
 
 -- 
 Daniel Jacobowitz
 CodeSourcery

Comment 2 xt28 2007-10-12 12:42:03 UTC
From: Philipp Kohlbecher <xt28@gmx.de>
To: Daniel Jacobowitz <drow@false.org>
Cc: gdb-gnats@sources.redhat.com
Subject: Re: breakpoints/2331: gdb cannot break on entry point for	statically
 linked binaries
Date: Fri, 12 Oct 2007 14:42:03 +0200

 Daniel Jacobowitz wrote:
 > On Thu, Oct 11, 2007 at 09:32:23AM -0000, xt28@gmx.de wrote:
 >   
 >> When debugging a statically linked binary, setting a breakpoint at
 >> the program's entry point does not work, i.e. the breakpoint is set,
 >> but execution does not stop at the breakpoint.
 >>     
 >
 > Unfortunately, this is a known problem.  GDB does not check for
 > breakpoints before the first resume.
 >   
 
 I am not sure if that is the issue. Even if the program is running and
 jumps back to its entry point, a breakpoint will not stop execution.
 
 See the following transcript:
 
 $ cat /tmp/helloloop.S
 .text
 .globl _start
 _start:
         movl $4, %eax           # code for 'write(2)' syscall
         movl $1, %ebx           # fd = stdout
         movl $message, %ecx     # string to write
         movl $len, %edx         # length of that string
         int $0x80               # syscall
         jmp _start              # loop forever
 .data
         message: .ascii "Hello, World!\n"
         len = . - message
 
 $ gdb/gdb /tmp/helloloop
 GNU gdb 6.7.50_20071011
 Copyright (C) 2007 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 "i686-pc-linux-gnu"...
 (no debugging symbols found)
 Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
 (gdb) info files
 Symbols from "/tmp/helloloop".
 Local exec file:
         `/tmp/helloloop', file type elf32-i386.
         Entry point: 0x8048074
         0x08048074 - 0x0804808f is .text
         0x08049090 - 0x0804909e is .data
 (gdb) break *0x8048074
 Breakpoint 1 at 0x8048074
 (gdb) run
 Starting program: /tmp/helloloop
 (no debugging symbols found)
 Hello, World!
 Hello, World!
 [...]
 Hello, World!
 
 Program received signal SIGINT, Interrupt.
 0x08048079 in _start ()
 (gdb) quit
 The program is running.  Exit anyway? (y or n) y

Comment 3 drow@false.org 2007-10-12 12:57:02 UTC
From: Daniel Jacobowitz <drow@false.org>
To: Philipp Kohlbecher <xt28@gmx.de>
Cc: gdb-gnats@sources.redhat.com
Subject: Re: breakpoints/2331: gdb cannot break on entry point for
	statically linked binaries
Date: Fri, 12 Oct 2007 08:57:02 -0400

 On Fri, Oct 12, 2007 at 02:42:03PM +0200, Philipp Kohlbecher wrote:
 > I am not sure if that is the issue. Even if the program is running and
 > jumps back to its entry point, a breakpoint will not stop execution.
 
 Interesting.  Thank you for the excellent test case.  This particular
 one is a little atypical; there is no "main" and no "_dl_debug_state"
 so _start is used for the shared library event breakpoint.  GDB does
 not correctly detect a second breakpoint at the same location.
 
 (gdb) set debug infrun 1
 (gdb) run
 ...
 Hello, World!
 infrun: infwait_normal_state
 infrun: TARGET_WAITKIND_STOPPED
 infrun: stop_pc = 0x8048074
 infrun: BPSTAT_WHAT_CHECK_SHLIBS
 infrun: no stepping, continue
 infrun: resume (step=1, signal=0)
 infrun: prepare_to_wait
 infrun: infwait_normal_state
 infrun: TARGET_WAITKIND_STOPPED
 infrun: stop_pc = 0x8048079
 infrun: trap expected
 infrun: no stepping, continue
 infrun: resume (step=0, signal=0)
 infrun: prepare_to_wait
 Hello, World!
 
 At the shared library breakpoint we should detect another present
 breakpoint and stop.  This may be hard to fix :-(  I'm not going to
 work on it right now, but hopefully my explanation will help if
 someone else tackles it.
 
 -- 
 Daniel Jacobowitz
 CodeSourcery
Comment 4 Jan Kratochvil 2010-04-04 21:52:53 UTC
*** Bug 9341 has been marked as a duplicate of this bug. ***
Comment 5 Jan Kratochvil 2010-04-04 21:54:57 UTC
Fix:
http://sourceware.org/ml/gdb-patches/2010-04/msg00059.html
Comment 6 Pedro Alves 2010-04-04 21:58:03 UTC
No, not a complete fix for this one.  That patch doesn't fix the case of
a user breakpoint on top of a shared library event
breakpoint (BPSTAT_WHAT_CHECK_SHLIBS).
Comment 7 Jan Kratochvil 2010-04-04 22:14:56 UTC
OK, sorry, closed only PR 9341 now.
Comment 8 Jan Kratochvil 2010-05-17 21:47:16 UTC
Fix of this PR (+associated 1/3 and 2/3):
Re: [patch 3/3] bpstat_what removal
http://sourceware.org/ml/gdb-patches/2010-05/msg00370.html
Comment 9 cvs-commit@gcc.gnu.org 2010-06-24 15:17:56 UTC
Subject: Bug 9436

CVSROOT:	/cvs/src
Module name:	src
Changes by:	jkratoch@sourceware.org	2010-06-24 15:17:32

Modified files:
	gdb            : ChangeLog breakpoint.c breakpoint.h inferior.h 
	                 infrun.c 
	gdb/testsuite  : ChangeLog 
Added files:
	gdb/testsuite/gdb.base: nostdlib.c nostdlib.exp 

Log message:
	gdb/
	Fix PR 9436.
	* breakpoint.c (handle_jit_event): New function.
	(bpstat_what): Remove enum class, kc, ss, sn, sgl, slr, clr, sr, shl,
	jit, err, table and bs_class.  New variables shlib_event, jit_event,
	this_action and bptype.  Change bs_class assignments to this_action
	assignments.  new unhandled bptype internal error.  Move here
	shlib_event and jit_event handling from handle_inferior_event.
	* breakpoint.h (enum bpstat_what_main_action): Extend the comment.
	Reorder items.  Remove BPSTAT_WHAT_CHECK_SHLIBS and
	BPSTAT_WHAT_CHECK_JIT.
	* inferior.h (debug_infrun, stop_on_solib_events): New declarations.
	* infrun.c (debug_infrun, stop_on_solib_events): Remove static.
	(handle_inferior_event): Reinitialize frame and gdbarch after
	bpstat_what call.  Move BPSTAT_WHAT_CHECK_SHLIBS and
	BPSTAT_WHAT_CHECK_JIT handling to bpstat_what.  Reinitialize even
	gdbarch when frame gets reinitialized.
	
	gdb/testsuite/
	Test PR 9436.
	* gdb.base/nostdlib.exp, gdb.base/nostdlib.c: New.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.11920&r2=1.11921
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/breakpoint.c.diff?cvsroot=src&r1=1.492&r2=1.493
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/breakpoint.h.diff?cvsroot=src&r1=1.120&r2=1.121
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/inferior.h.diff?cvsroot=src&r1=1.144&r2=1.145
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/infrun.c.diff?cvsroot=src&r1=1.443&r2=1.444
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.2347&r2=1.2348
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/nostdlib.c.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/nostdlib.exp.diff?cvsroot=src&r1=NONE&r2=1.1

Comment 10 Jan Kratochvil 2010-06-24 15:19:50 UTC
http://sourceware.org/ml/gdb-cvs/2010-06/msg00160.html

gdb/
	Fix PR 9436.
	* breakpoint.c (handle_jit_event): New function.
	(bpstat_what): Remove enum class, kc, ss, sn, sgl, slr, clr, sr, shl,
	jit, err, table and bs_class.  New variables shlib_event, jit_event,
	this_action and bptype.  Change bs_class assignments to this_action
	assignments.  new unhandled bptype internal error.  Move here
	shlib_event and jit_event handling from handle_inferior_event.
	* breakpoint.h (enum bpstat_what_main_action): Extend the comment.
	Reorder items.  Remove BPSTAT_WHAT_CHECK_SHLIBS and
	BPSTAT_WHAT_CHECK_JIT.
	* inferior.h (debug_infrun, stop_on_solib_events): New declarations.
	* infrun.c (debug_infrun, stop_on_solib_events): Remove static.
	(handle_inferior_event): Reinitialize frame and gdbarch after
	bpstat_what call.  Move BPSTAT_WHAT_CHECK_SHLIBS and
	BPSTAT_WHAT_CHECK_JIT handling to bpstat_what.  Reinitialize even
	gdbarch when frame gets reinitialized.
	
gdb/testsuite/
	Test PR 9436.
	* gdb.base/nostdlib.exp, gdb.base/nostdlib.c: New.
Comment 11 Jan Kratochvil 2010-06-24 15:20:37 UTC
$ ./gdb -nx /sbin/ldconfig
(gdb) info files 
...
	Entry point: 0x400360
...
(gdb) b *0x400360
Breakpoint 1 at 0x400360: file ../sysdeps/x86_64/elf/start.S, line 65.
(gdb) r
Starting program: /sbin/ldconfig 
Breakpoint 1, _start () at ../sysdeps/x86_64/elf/start.S:65
65		xorl %ebp, %ebp
(gdb) p/x $pc
$1 = 0x400360