[patch] Workaround gcc bug 49906

Jan Kratochvil jan.kratochvil@redhat.com
Fri Oct 28 22:15:00 GMT 2011


On Fri, 28 Oct 2011 22:59:48 +0200, Aleksandar Ristovski wrote:
> On 11-10-28 04:51 PM, Jan Kratochvil wrote:
> >Hello Aleksandar,
> >
> >the problem is that for this testcase:
> >/*1*/	static int i;
> >/*2*/	static void
> >/*3*/	f (int q)
> >/*4*/	{
> >/*5*/	  for (;; i--)
> >/*6*/	    if (i++)
> >/*7*/	      break;
> >/*8*/	}
> >/*9*/	int main (void) { f (5); return 0; }
> >
> >Built with:
> >	gcc -o f2 f2.c -Wall -g -Werror
> >	gcc (GCC) 4.6.3 20111028 (prerelease) -- the version should not matter
> >	x86_64
> >
> >it has a regression
> >	gdb ./f2 -ex 'b f' -ex r
> >FSF GDB HEAD:
> >	Breakpoint 1, f (q=5) at f2.c:6
> >	                   ^
> >	6	    if (i++)
> >with your patch:
> >	Breakpoint 1, f (q=0) at f2.c:4
> >	                   ^
> >	4	{
> >
> 
> I think that if you dump line info for your test you will find that
> line info is broken as well. Correct line info would yield answer
> "line 5" after skipping prologue.

There is no code to produce for that line - for the before-part
of `for (;; anything)'.

If "line 5" should have code (="nop") after prologue even the "do {" line
should have "nop" in:

void f (void)
{
  do	/* It seems you suggest a "nop" here.  */
    {
      i++;	/* The first line after prologue is here now.  */
    }
  while (i--);
}

If you think there should be that "nop" I think GCC PR debug/49906 needs to be
extended (and/or filed a new GCC PR) as GCC PR debug/49906 probably is not
going to implement this "nop" there.


> IMO, with the fix, the result is better (beginning of the function
> block is better IMO than first statement inside 'for' block).

Without the fix it stops on the first executable statement.  This is
a perfectly defined behavior.  Not if you noticed your patch breaks access to
function parameters (and probably also affects local variables some way).


> >For reader's convenience attaching objdump at the bottom of this mail.
> 
> Could you do
> 
> objdump -W
> 
> and post the output?

Not sure which part do you look for but including below, it is not so long.


Thanks,
Jan

------------------------------------------------------------------------------

static int i;
static void
f (int q)
{
  for (;; i--)
    if (i++)
      break;
}
int main (void) { f (5); return 0; }

------------------------------------------------------------------------------

0000000000400454 <f>:
f():
/home/jkratoch/t/f2.c:4
  400454:	55                   	push   %rbp
  400455:	48 89 e5             	mov    %rsp,%rbp
  400458:	89 7d fc             	mov    %edi,-0x4(%rbp)
/home/jkratoch/t/f2.c:6
  40045b:	8b 05 27 04 20 00    	mov    0x200427(%rip),%eax        # 600888 <i>
  400461:	85 c0                	test   %eax,%eax
  400463:	0f 95 c2             	setne  %dl
  400466:	83 c0 01             	add    $0x1,%eax
  400469:	89 05 19 04 20 00    	mov    %eax,0x200419(%rip)        # 600888 <i>
  40046f:	84 d2                	test   %dl,%dl
  400471:	75 11                	jne    400484 <f+0x30>
/home/jkratoch/t/f2.c:5
  400473:	8b 05 0f 04 20 00    	mov    0x20040f(%rip),%eax        # 600888 <i>
  400479:	83 e8 01             	sub    $0x1,%eax
  40047c:	89 05 06 04 20 00    	mov    %eax,0x200406(%rip)        # 600888 <i>
/home/jkratoch/t/f2.c:8
  400482:	eb d7                	jmp    40045b <f+0x7>
/home/jkratoch/t/f2.c:7
  400484:	90                   	nop
/home/jkratoch/t/f2.c:8
  400485:	5d                   	pop    %rbp
  400486:	c3                   	retq   

------------------------------------------------------------------------------

f2:     file format elf64-x86-64

Contents of the .eh_frame section:

00000000 00000014 00000000 CIE
  Version:               1
  Augmentation:          "zR"
  Code alignment factor: 1
  Data alignment factor: -8
  Return address column: 16
  Augmentation data:     1b

  DW_CFA_def_cfa: r7 (rsp) ofs 8
  DW_CFA_offset: r16 (rip) at cfa-8
  DW_CFA_nop
  DW_CFA_nop

00000018 00000024 0000001c FDE cie=00000000 pc=fffffffffffffd90..fffffffffffffdb0
  DW_CFA_def_cfa_offset: 16
  DW_CFA_advance_loc: 6 to fffffffffffffd96
  DW_CFA_def_cfa_offset: 24
  DW_CFA_advance_loc: 10 to fffffffffffffda0
  DW_CFA_def_cfa_expression (DW_OP_breg7 (rsp): 8; DW_OP_breg16 (rip): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit11; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus)
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

00000040 0000001c 00000044 FDE cie=00000000 pc=fffffffffffffe94..fffffffffffffec7
  DW_CFA_advance_loc: 1 to fffffffffffffe95
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r6 (rbp) at cfa-16
  DW_CFA_advance_loc: 3 to fffffffffffffe98
  DW_CFA_def_cfa_register: r6 (rbp)
  DW_CFA_advance_loc: 46 to fffffffffffffec6
  DW_CFA_def_cfa: r7 (rsp) ofs 8
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

00000060 0000001c 00000064 FDE cie=00000000 pc=fffffffffffffec7..fffffffffffffedc
  DW_CFA_advance_loc: 1 to fffffffffffffec8
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r6 (rbp) at cfa-16
  DW_CFA_advance_loc: 3 to fffffffffffffecb
  DW_CFA_def_cfa_register: r6 (rbp)
  DW_CFA_advance_loc: 16 to fffffffffffffedb
  DW_CFA_def_cfa: r7 (rsp) ofs 8
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

00000080 00000024 00000084 FDE cie=00000000 pc=fffffffffffffee0..ffffffffffffff69
  DW_CFA_advance_loc: 17 to fffffffffffffef1
  DW_CFA_offset: r12 (r12) at cfa-40
  DW_CFA_offset: r6 (rbp) at cfa-48
  DW_CFA_advance_loc: 31 to ffffffffffffff10
  DW_CFA_def_cfa_offset: 64
  DW_CFA_offset: r3 (rbx) at cfa-56
  DW_CFA_offset: r15 (r15) at cfa-16
  DW_CFA_offset: r14 (r14) at cfa-24
  DW_CFA_offset: r13 (r13) at cfa-32
  DW_CFA_advance_loc1: 88 to ffffffffffffff68
  DW_CFA_def_cfa_offset: 8
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

000000a8 00000014 000000ac FDE cie=00000000 pc=ffffffffffffff70..ffffffffffffff72
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

000000c0 ZERO terminator


Contents of the .debug_aranges section:

  Length:                   44
  Version:                  2
  Offset into .debug_info:  0x0
  Pointer Size:             8
  Segment Size:             0

    Address            Length
    0000000000400454 0000000000000048 
    0000000000000000 0000000000000000 

Contents of the .debug_info section:

  Compilation Unit @ offset 0x0:
   Length:        0x90 (32-bit)
   Version:       2
   Abbrev Offset: 0
   Pointer Size:  8
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_producer    : (indirect string, offset: 0x0): GNU C 4.6.3 20111028 (prerelease)	
    <10>   DW_AT_language    : 1	(ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0x22): f2.c	
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x27): /home/jkratoch/t	
    <19>   DW_AT_low_pc      : 0x400454	
    <21>   DW_AT_high_pc     : 0x40049c	
    <29>   DW_AT_stmt_list   : 0x0	
 <1><2d>: Abbrev Number: 2 (DW_TAG_subprogram)
    <2e>   DW_AT_name        : f	
    <30>   DW_AT_decl_file   : 1	
    <31>   DW_AT_decl_line   : 3	
    <32>   DW_AT_prototyped  : 1	
    <33>   DW_AT_low_pc      : 0x400454	
    <3b>   DW_AT_high_pc     : 0x400487	
    <43>   DW_AT_frame_base  : 0x0	(location list)
    <47>   DW_AT_sibling     : <0x58>	
 <2><4b>: Abbrev Number: 3 (DW_TAG_formal_parameter)
    <4c>   DW_AT_name        : q	
    <4e>   DW_AT_decl_file   : 1	
    <4f>   DW_AT_decl_line   : 3	
    <50>   DW_AT_type        : <0x58>	
    <54>   DW_AT_location    : 2 byte block: 91 6c 	(DW_OP_fbreg: -20)
 <1><58>: Abbrev Number: 4 (DW_TAG_base_type)
    <59>   DW_AT_byte_size   : 4	
    <5a>   DW_AT_encoding    : 5	(signed)
    <5b>   DW_AT_name        : int	
 <1><5f>: Abbrev Number: 5 (DW_TAG_subprogram)
    <60>   DW_AT_external    : 1	
    <61>   DW_AT_name        : (indirect string, offset: 0x38): main	
    <65>   DW_AT_decl_file   : 1	
    <66>   DW_AT_decl_line   : 9	
    <67>   DW_AT_prototyped  : 1	
    <68>   DW_AT_type        : <0x58>	
    <6c>   DW_AT_low_pc      : 0x400487	
    <74>   DW_AT_high_pc     : 0x40049c	
    <7c>   DW_AT_frame_base  : 0x60	(location list)
 <1><80>: Abbrev Number: 6 (DW_TAG_variable)
    <81>   DW_AT_name        : i	
    <83>   DW_AT_decl_file   : 1	
    <84>   DW_AT_decl_line   : 1	
    <85>   DW_AT_type        : <0x58>	
    <89>   DW_AT_location    : 9 byte block: 3 88 8 60 0 0 0 0 0 	(DW_OP_addr: 600888)

Contents of the .debug_abbrev section:

  Number TAG
   1      DW_TAG_compile_unit    [has children]
    DW_AT_producer     DW_FORM_strp
    DW_AT_language     DW_FORM_data1
    DW_AT_name         DW_FORM_strp
    DW_AT_comp_dir     DW_FORM_strp
    DW_AT_low_pc       DW_FORM_addr
    DW_AT_high_pc      DW_FORM_addr
    DW_AT_stmt_list    DW_FORM_data4
   2      DW_TAG_subprogram    [has children]
    DW_AT_name         DW_FORM_string
    DW_AT_decl_file    DW_FORM_data1
    DW_AT_decl_line    DW_FORM_data1
    DW_AT_prototyped   DW_FORM_flag
    DW_AT_low_pc       DW_FORM_addr
    DW_AT_high_pc      DW_FORM_addr
    DW_AT_frame_base   DW_FORM_data4
    DW_AT_sibling      DW_FORM_ref4
   3      DW_TAG_formal_parameter    [no children]
    DW_AT_name         DW_FORM_string
    DW_AT_decl_file    DW_FORM_data1
    DW_AT_decl_line    DW_FORM_data1
    DW_AT_type         DW_FORM_ref4
    DW_AT_location     DW_FORM_block1
   4      DW_TAG_base_type    [no children]
    DW_AT_byte_size    DW_FORM_data1
    DW_AT_encoding     DW_FORM_data1
    DW_AT_name         DW_FORM_string
   5      DW_TAG_subprogram    [no children]
    DW_AT_external     DW_FORM_flag
    DW_AT_name         DW_FORM_strp
    DW_AT_decl_file    DW_FORM_data1
    DW_AT_decl_line    DW_FORM_data1
    DW_AT_prototyped   DW_FORM_flag
    DW_AT_type         DW_FORM_ref4
    DW_AT_low_pc       DW_FORM_addr
    DW_AT_high_pc      DW_FORM_addr
    DW_AT_frame_base   DW_FORM_data4
   6      DW_TAG_variable    [no children]
    DW_AT_name         DW_FORM_string
    DW_AT_decl_file    DW_FORM_data1
    DW_AT_decl_line    DW_FORM_data1
    DW_AT_type         DW_FORM_ref4
    DW_AT_location     DW_FORM_block1

Raw dump of debug contents of section .debug_line:

  Offset:                      0x0
  Length:                      57
  DWARF Version:               2
  Prologue Length:             27
  Minimum Instruction Length:  1
  Initial value of 'is_stmt':  1
  Line Base:                   -5
  Line Range:                  14
  Opcode Base:                 13

 Opcodes:
  Opcode 1 has 0 args
  Opcode 2 has 1 args
  Opcode 3 has 1 args
  Opcode 4 has 1 args
  Opcode 5 has 1 args
  Opcode 6 has 0 args
  Opcode 7 has 0 args
  Opcode 8 has 0 args
  Opcode 9 has 1 args
  Opcode 10 has 0 args
  Opcode 11 has 0 args
  Opcode 12 has 1 args

 The Directory Table is empty.

 The File Name Table:
  Entry	Dir	Time	Size	Name
  1	0	0	0	f2.c

 Line Number Statements:
  Extended opcode 2: set Address to 0x400454
  Special opcode 8: advance Address by 0 to 0x400454 and Line by 3 to 4
  Special opcode 105: advance Address by 7 to 0x40045b and Line by 2 to 6
  Advance PC by constant 17 to 0x40046c
  Special opcode 102: advance Address by 7 to 0x400473 and Line by -1 to 5
  Special opcode 218: advance Address by 15 to 0x400482 and Line by 3 to 8
  Special opcode 32: advance Address by 2 to 0x400484 and Line by -1 to 7
  Special opcode 20: advance Address by 1 to 0x400485 and Line by 1 to 8
  Special opcode 34: advance Address by 2 to 0x400487 and Line by 1 to 9
  Special opcode 61: advance Address by 4 to 0x40048b and Line by 0 to 9
  Advance PC by constant 17 to 0x40049c
  Extended opcode 1: End of Sequence


Contents of the .debug_str section:

  0x00000000 474e5520 4320342e 362e3320 32303131 GNU C 4.6.3 2011
  0x00000010 31303238 20287072 6572656c 65617365 1028 (prerelease
  0x00000020 29006632 2e63002f 686f6d65 2f6a6b72 ).f2.c./home/jkr
  0x00000030 61746f63 682f7400 6d61696e 00       atoch/t.main.

Contents of the .debug_loc section:

    Offset   Begin    End      Expression
    00000000 0000000000400454 0000000000400455 (DW_OP_breg7 (rsp): 8)
    00000000 0000000000400455 0000000000400458 (DW_OP_breg7 (rsp): 16)
    00000000 0000000000400458 0000000000400486 (DW_OP_breg6 (rbp): 16)
    00000000 0000000000400486 0000000000400487 (DW_OP_breg7 (rsp): 8)
    00000000 <End of list>
    00000060 0000000000400487 0000000000400488 (DW_OP_breg7 (rsp): 8)
    00000060 0000000000400488 000000000040048b (DW_OP_breg7 (rsp): 16)
    00000060 000000000040048b 000000000040049b (DW_OP_breg6 (rbp): 16)
    00000060 000000000040049b 000000000040049c (DW_OP_breg7 (rsp): 8)
    00000060 <End of list>



More information about the Gdb-patches mailing list