This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix an issue with the gdb step-over aka. "n" command


Hi,

this fixes an issue with the gdb step-over aka. "n" command.

Apologies, the motivation for this patch was from sub-optimal
debug experience using some gcc code involving inlined functions,
and initially I tried to convince gcc folks that it is in fact a
gcc bug, but...

It can be seen when you debug an optimized stage-3 cc1
it does not affect -O0 code, though.

Note: you can use "gcc -S hello.c -wrapper gdb,--args" to invoke cc1 with
debugger attached.

This example debug session will explain the effect.

(gdb) b get_alias_set
Breakpoint 5 at 0xa099f0: file ../../gcc-trunk/gcc/alias.c, line 837.
(gdb) r
Breakpoint 5, get_alias_set (t=t@entry=0x7ffff7ff7ab0) at ../../gcc-trunk/gcc/alias.c:837
837	  if (t == error_mark_node
(gdb) n
839		  && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
(gdb) n
3382	  return __t;  <-- now we have a problem: wrong line info here
(gdb) bt
#0  get_alias_set (t=t@entry=0x7ffff7ff7ab0) at ../../gcc-trunk/gcc/tree.h:3382
#1  0x0000000000b25dfe in set_mem_attributes_minus_bitpos (ref=0x7ffff746f990, t=0x7ffff7ff7ab0, objectp=1, bitpos=...)
    at ../../gcc-trunk/gcc/emit-rtl.c:1957
#2  0x0000000001137a55 in make_decl_rtl (decl=0x7ffff7ff7ab0) at ../../gcc-trunk/gcc/varasm.c:1518
#3  0x000000000113b6e8 in assemble_variable (decl=0x7ffff7ff7ab0, top_level=<optimized out>, at_end=<optimized out>, 
    dont_output_data=0) at ../../gcc-trunk/gcc/varasm.c:2246
#4  0x000000000113f0ea in varpool_node::assemble_decl (this=0x7ffff745b000) at ../../gcc-trunk/gcc/varpool.c:584
#5  0x000000000113fa17 in varpool_node::assemble_decl (this=0x7ffff745b000) at ../../gcc-trunk/gcc/varpool.c:750

The reason for this is a line number information that is exactly at
the end of the inlined function, but there is no code at that place,
only variable values (views) are declared there.  Unfortunately
the next instruction is again in the main program, but due to -gstatement-frontiers
those do not have the is_stmt and are completely ignored by gdb at the moment.


This patch fixes the effect by rewriting the is_stmt attribute of the next
location info under certain conditions.

I have no idea how to write a test case for this since it happens only in optimized code,
and only under very special conditions.


Thanks
Bernd.
From 18017c39f9598dcd8e3204afd624afd2ac723301 Mon Sep 17 00:00:00 2001
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
Date: Sat, 23 Nov 2019 20:59:25 +0100
Subject: [PATCH] Fix an issue with the gdb step-over aka. "n" command

When debugging optimized code with inlined functions built
with -gstatement-frontiers debug info, it may happen that
an inline function has a line location exactly at the
end of a block which has the is_stmt attribute set, followed
by a location info which is at the call site but has the
is_stmt attribute cleared and is therefore ignored.

The visual effect is that "n" does sometimes not step over
the inlined function but instead jumps to the last line of
the inline function, but the inline function has already
returned, hence the line number information is inconsistent
at this point.

This patch detects a is_stmt location info followed by
a location info in a different file at the same address,
but without is_stmt location set, and forces the second
location info to replace the previous one.
---
 gdb/dwarf2read.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 1ca801c..a7c4c8e 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -20915,6 +20915,7 @@ private:
      example, when discriminators are present.  PR 17276.  */
   unsigned int m_last_line = 0;
   bool m_line_has_non_zero_discriminator = false;
+  CORE_ADDR m_last_address = (CORE_ADDR) -1;
 };
 
 void
@@ -21097,7 +21098,10 @@ lnp_state_machine::record_line (bool end_sequence)
   else if (m_op_index == 0 || end_sequence)
     {
       fe->included_p = 1;
-      if (m_record_lines_p && (producer_is_codewarrior (m_cu) || m_is_stmt))
+      if (m_record_lines_p
+	  && (producer_is_codewarrior (m_cu) || m_is_stmt || end_sequence
+	      || (m_last_subfile != m_cu->get_builder ()->get_current_subfile ()
+		  && m_last_address == m_address)))
 	{
 	  if (m_last_subfile != m_cu->get_builder ()->get_current_subfile ()
 	      || end_sequence)
@@ -21120,6 +21124,7 @@ lnp_state_machine::record_line (bool end_sequence)
 		}
 	      m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
 	      m_last_line = m_line;
+	      m_last_address = m_address;
 	    }
 	}
     }
-- 
1.9.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]