[committed][gdb/breakpoints] Workaround missing line-table entry

Tom de Vries tdevries@suse.de
Tue Apr 6 13:15:29 GMT 2021


On 3/5/21 7:35 AM, Tom de Vries wrote:
> On 2/5/21 11:07 AM, Tom de Vries wrote:
>> On 1/22/21 10:15 AM, Tom de Vries wrote:
>>> Hi,
>>>
>>> When running test-case gdb.opt/inline-cmds.exp, we run into this KFAIL with
>>> gcc:
>>> ...
>>> Breakpoint 7, main () at gdb.opt/inline-cmds.c:71^M
>>> 71        result = 0; /* set breakpoint 3 here */^M
>>> (gdb) PASS: gdb.opt/inline-cmds.exp: continue to breakpoint: consecutive func1
>>> next^M
>>> 73        func1 (); /* first call */^M
>>> (gdb) PASS: gdb.opt/inline-cmds.exp: next to first func1
>>> next^M
>>> 75        marker ();^M
>>> (gdb) KFAIL: gdb.opt/inline-cmds.exp: next to second func1 (PRMS: gdb/25884)
>>> ...
>>> while with clang we have instead:
>>> ...
>>> next^M
>>> 74        func1 (); /* second call */^M
>>> (gdb) PASS: gdb.opt/inline-cmds.exp: next to second func1
>>> ...
>>>
>>> The relevant bit of the test source is here in inline-cmds.c:
>>> ...
>>>     71    result = 0; /* set breakpoint 3 here */
>>>     72
>>>     73    func1 (); /* first call */
>>>     74    func1 (); /* second call */
>>>     75    marker ();
>>> ...
>>> with func1 defined as:
>>> ...
>>>     33  inline __attribute__((always_inline)) int func1(void)
>>>     34  {
>>>     35    bar ();
>>>     36    return x * y;
>>>     37  }
>>> ...
>>>
>>> The corresponding insns are:
>>> ...
>>>   40050b:       movl   $0x0,0x200b1f(%rip)        # 601034 <result>
>>>   400515:       callq  40057b <bar>
>>>   40051a:       callq  40057b <bar>
>>>   40051f:       callq  400596 <marker>
>>> ...
>>> and the line number info is:
>>> ...
>>> Line number    Starting address    View    Stmt
>>>          71            0x40050b               x
>>>          35            0x400515               x
>>>          75            0x40051f               x
>>> ...
>>>
>>> The line number info is missing an entry for the insn at 40051a, and that is
>>> causing the FAIL.  This is a gcc issue, filed as PR gcc/98780 -" Missing line
>>> table entry for inlined stmt at -g -O0".
>>>
>>> [ For contrast, with clang we have an extra entry:
>>> ...
>>> Line number    Starting address    View    Stmt
>>>          71            0x40050b               x
>>>          35            0x400515               x
>>>          35            0x40051a
>>>          75            0x40051f               x
>>> ...
>>> though it appears to be missing the start-of-statement marker. ]
>>>
>>> However, there is debug info that indicates that the insn at 40051a is not
>>> part of the line table entry for the insn at 400515:
>>> ...
>>> <2><1c4>: Abbrev Number: 8 (DW_TAG_inlined_subroutine)
>>>     <1c5>   DW_AT_abstract_origin: <0x2a2>
>>>     <1c9>   DW_AT_low_pc      : 0x400515
>>>     <1d1>   DW_AT_high_pc     : 0x5
>>>     <1d9>   DW_AT_call_file   : 1
>>>     <1da>   DW_AT_call_line   : 73
>>>  <2><1db>: Abbrev Number: 8 (DW_TAG_inlined_subroutine)
>>>     <1dc>   DW_AT_abstract_origin: <0x2a2>
>>>     <1e0>   DW_AT_low_pc      : 0x40051a
>>>     <1e8>   DW_AT_high_pc     : 0x5
>>>     <1f0>   DW_AT_call_file   : 1
>>>     <1f1>   DW_AT_call_line   : 74
>>> ...
>>> and indeed lldb manages to "next" from line 73 to line 74.
>>>
>>> Work around the missing line table entry, by using the inline frame info to
>>> narrow the stepping range in prepare_one_step.
>>>
>>> Tested on x86_64-linux.
>>>
>>> Any comments?
>>>
> 
> Ping.
> 

Well, let's commit then :)

Thanks,
- Tom

>>> [gdb/breakpoints] Workaround missing line-table entry
>>>
>>> gdb/ChangeLog:
>>>
>>> 2021-01-22  Tom de Vries  <tdevries@suse.de>
>>>
>>> 	PR breakpoints/25884
>>> 	* infcmd.c (prepare_one_step): Using inline frame info to narrow
>>> 	stepping range.
>>>
>>> gdb/testsuite/ChangeLog:
>>>
>>> 2021-01-22  Tom de Vries  <tdevries@suse.de>
>>>
>>> 	PR breakpoints/25884
>>> 	* gdb.opt/inline-cmds.exp: Remove kfail.
>>>
>>> ---
>>>  gdb/infcmd.c                          | 14 ++++++++++++++
>>>  gdb/testsuite/gdb.opt/inline-cmds.exp | 17 +----------------
>>>  2 files changed, 15 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
>>> index 6f0ed952de6..ecb3de31879 100644
>>> --- a/gdb/infcmd.c
>>> +++ b/gdb/infcmd.c
>>> @@ -1009,6 +1009,20 @@ prepare_one_step (thread_info *tp, struct step_command_fsm *sm)
>>>  				 &tp->control.step_range_start,
>>>  				 &tp->control.step_range_end);
>>>  
>>> +	  /* There's a problem in gcc (PR gcc/98780) that causes missing line
>>> +	     table entries, which results in a too large stepping range.
>>> +	     Use inlined_subroutine info to make the range more narrow.  */
>>> +	  if (inline_skipped_frames (tp) > 0)
>>> +	    {
>>> +	      symbol *sym = inline_skipped_symbol (tp);
>>> +	      if (SYMBOL_CLASS (sym) == LOC_BLOCK)
>>> +		{
>>> +		  const block *block = SYMBOL_BLOCK_VALUE (sym);
>>> +		  if (BLOCK_END (block) < tp->control.step_range_end)
>>> +		    tp->control.step_range_end = BLOCK_END (block);
>>> +		}
>>> +	    }
>>> +
>>>  	  tp->control.may_range_step = 1;
>>>  
>>>  	  /* If we have no line info, switch to stepi mode.  */
>>> diff --git a/gdb/testsuite/gdb.opt/inline-cmds.exp b/gdb/testsuite/gdb.opt/inline-cmds.exp
>>> index 17720c46795..981dcbb4a29 100644
>>> --- a/gdb/testsuite/gdb.opt/inline-cmds.exp
>>> +++ b/gdb/testsuite/gdb.opt/inline-cmds.exp
>>> @@ -222,22 +222,7 @@ gdb_breakpoint $line3
>>>  gdb_continue_to_breakpoint "consecutive func1"
>>>  
>>>  gdb_test "next" ".*func1 .*first call.*" "next to first func1"
>>> -set msg "next to second func1"
>>> -gdb_test_multiple "next" $msg {
>>> -    -re ".*func1 .*second call.*$gdb_prompt $" {
>>> -	pass $msg
>>> -    }
>>> -    -re ".*marker .*$gdb_prompt $" {
>>> -	# This assembles to two consecutive call instructions.
>>> -	# Both appear to be at the same line, because they're
>>> -	# in the body of the same inlined function.  This is
>>> -	# reasonable for the line table.  GDB should take the
>>> -	# containing block and/or function into account when
>>> -	# deciding how far to step.  The single line table entry
>>> -	# is actually two consecutive instances of the same line.
>>> -	kfail gdb/25884 $msg
>>> -    }
>>> -}
>>> +gdb_test "next" ".*func1 .*second call.*" "next to second func1"
>>>  
>>>  # It is easier when the two inlined functions are not on the same line.
>>>  set line4 [gdb_get_line_number "set breakpoint 4 here"]
>>>


More information about the Gdb-patches mailing list