Bug 52160 - gdb ignores line "bar: if(foo)goto bar;"
Summary: gdb ignores line "bar: if(foo)goto bar;"
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.4.5
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-02-07 21:15 UTC by Askar Safin
Modified: 2013-04-12 18:59 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Askar Safin 2012-02-07 21:15:07 UTC
foo.c:
-----------------------------------
#include <stdio.h>

int main()
{
        int foo;
        printf("Enter foo: ");
        scanf("%d", &foo);
bar:    if(foo)goto bar;
        return 0;
}
-----------------------------------
0:~# gcc -g foo.c
0:~# gdb a.out
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 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 "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/a.out...done.
(gdb) start
Temporary breakpoint 1 at 0x804842d: file foo.c, line 6.
Starting program: /root/a.out 

Temporary breakpoint 1, main () at foo.c:6
6               printf("Enter foo: ");
(gdb) n
7               scanf("%d", &foo);
(gdb) 
Enter foo: 0
9               return 0;
(gdb) q
A debugging session is active.

        Inferior 1 [process 21382] will be killed.

Quit anyway? (y or n) y
-----------------------------------
But gdb must say:

6               printf("Enter foo: ");
(gdb) n
7               scanf("%d", &foo);
(gdb) 
Enter foo: 0
8       bar:    if(foo)goto bar; 
(gdb) 
9               return 0;
-----------------------------------
0:~# gdb a.out
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 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 "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/a.out...done.
(gdb) start
Temporary breakpoint 1 at 0x804842d: file foo.c, line 6.
Starting program: /root/a.out 

Temporary breakpoint 1, main () at foo.c:6
6               printf("Enter foo: ");
(gdb) n
7               scanf("%d", &foo);
(gdb) 
Enter foo: 1
^C
Program received signal SIGINT, Interrupt.
0x08048458 in main () at foo.c:8
8       bar:    if(foo)goto bar;
(gdb) q
A debugging session is active.

        Inferior 1 [process 21399] will be killed.

Quit anyway? (y or n) y
-----------------------------------
But gdb must say:

6               printf("Enter foo: ");
(gdb) n
7               scanf("%d", &foo);
(gdb) 
Enter foo: 1
8       bar:    if(foo)goto bar; 
(gdb) 
^C
-----------------------------------
0:~# uname -a
Linux debian 2.6.32-5-686 #1 SMP Sat Oct 30 22:47:19 UTC 2010 i686 GNU/Linux
0:~# gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.4 --enable-shared --enable-multiarch
--enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls
--enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc
--enable-targets=all --with-arch-32=i586 --with-tune=generic
--enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu
--target=i486-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8)

Bug moved from http://sourceware.org/bugzilla/show_bug.cgi?id=12257
Comment 1 Andrew Pinski 2012-02-07 21:44:42 UTC
Here is what GCC produces:
	.loc 1 7 0
	leaq	-4(%rbp), %rax
	movq	%rax, %rsi
	movl	$.LC1, %edi
	movl	$0, %eax
	call	__isoc99_scanf
	jmp	.L2
.L5:
	.loc 1 8 0
	nop
.L2:
	.loc 1 8 0 is_stmt 0 discriminator 1
	movl	-4(%rbp), %eax
	testl	%eax, %eax
	jne	.L5

This looks fine to me.
Which might mean this is an interesting issue with debugging info.
Comment 2 Jan Kratochvil 2012-09-16 07:09:26 UTC
The same problem with IMO more minimal reproducer:
------------------------------------------------------------------------------
int i;
void f (void)
{
 redo:
  if (i)
    goto redo;
}
int main (void)
{
  f ();
  return 0;
}
------------------------------------------------------------------------------
(gdb) break f
Breakpoint 1 at 0x4004c2: file 123.c, line 6.
(gdb) run
Starting program: /home/jkratoch/t/123 
[Inferior 1 (process 308) exited normally]
------------------------------------------------------------------------------
f:
.LFB0:
        .file 1 "123.c"
        .loc 1 3 0
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        jmp     .L2
.L4:
        .loc 1 6 0
<-- GDB places breakpoint here
        nop
.L2:
        .loc 1 5 0
Comment 3 Jan Kratochvil 2012-09-16 07:10:39 UTC
FAIL: gcc (GCC) 4.4.7
FAIL: gcc (GCC) 4.5.4
FAIL: gcc (GCC) 4.6.4 20120916 (prerelease)
FAIL: gcc (GCC) 4.7.2 20120916 (prerelease)
FAIL: gcc (GCC) 4.8.0 20120916 (experimental)
Comment 4 Pedro Alves 2013-04-12 18:59:23 UTC
GDB PR15360 at <http://sourceware.org/bugzilla/show_bug.cgi?id=15360>
shows another reproducer:

 (gdb) b function
 Breakpoint 1 at 0x400569: file pr15360.c, line 9.
 (gdb) r
 ...
 ...exited normally.

GDB wants to put the breakpoint after the prologue of 'function', but:

(gdb) disassemble /m function
Dump of assembler code for function function():
8       {
   0x000000000040055c <+0>:     push   %rbp
   0x000000000040055d <+1>:     mov    %rsp,%rbp
   0x0000000000400560 <+4>:     push   %r12
   0x0000000000400562 <+6>:     push   %rbx
   0x0000000000400563 <+7>:     sub    $0x10,%rsp
   0x0000000000400567 <+11>:    jmp    0x40056a <function()+14>

9         do{
   0x0000000000400569 <+13>:    nop

10          int i = 0;
   0x000000000040056a <+14>:    movl   $0x0,-0x14(%rbp)

...
  Extended opcode 2: set Address to 0x40055c
  Special opcode 12: advance Address by 0 to 0x40055c and Line by 7 to 8
  Special opcode 188: advance Address by 13 to 0x400569 and Line by 1 to 9
...

Why is the jmp in the prologue's line?  That's what causes the issue.  GDB has long (since ever?) skipped the line where the prologue is to find the first instruction of "user code".