http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47471
--- Comment #2 from Dodji Seketeli <dodji at gcc dot gnu.org> 2011-03-29 15:24:07 UTC --- I believe the issue is that for that source code, GCC emits two identical .loc asm directives for line 3. In theory I don't thing doing that would be wrong. But in practise the second .loc directive triggers a special opcode in the generated line program that increments the line with an increment of zero; it also increments the current program address with a increment of zero. And that happens before the first line that doesn't belong to the prologue. That seems to break GDB's heuristic, and is also a bit of bloat. The patch below avoids emitting two identical consecutive line number debug information and seems to fix the issue for me. I am currently regression-testing it. >From eb1450a263a4e50b43132ef9b914f49a971c8e9d Mon Sep 17 00:00:00 2001 From: Dodji Seketeli <do...@redhat.com> Date: Tue, 29 Mar 2011 16:56:20 +0200 Subject: [PATCH] PR debug/47471 gcc/ * dwarf2out.c (dwarf2out_source_line): Avoid emitting two identical contiguous .loc asm directive. gcc/testsuite/ * gcc.dg/debug/dwarf2/line-prog-1.c: New test. --- gcc/dwarf2out.c | 33 +++++++++++++++------- gcc/testsuite/gcc.dg/debug/dwarf2/line-prog-1.c | 25 +++++++++++++++++ 2 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/line-prog-1.c diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 7803ab7..b350f43 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -22068,6 +22068,8 @@ dwarf2out_source_line (unsigned int line, const char *filename, && line != 0) { int file_num = maybe_emit_file (lookup_filename (filename)); + static int prev_file_num; + static unsigned int prev_line; switch_to_section (current_function_section ()); @@ -22078,19 +22080,28 @@ dwarf2out_source_line (unsigned int line, const char *filename, if (DWARF2_ASM_LINE_DEBUG_INFO) { - /* Emit the .loc directive understood by GNU as. */ - fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line); - if (is_stmt != last_is_stmt) + static int prev_file_num; + static unsigned int prev_line; + if (prev_file_num != file_num + || prev_line != line) { - fprintf (asm_out_file, " is_stmt %d", is_stmt ? 1 : 0); - last_is_stmt = is_stmt; - } - if (SUPPORTS_DISCRIMINATOR && discriminator != 0) - fprintf (asm_out_file, " discriminator %d", discriminator); - fputc ('\n', asm_out_file); + /* Emit the .loc directive understood by GNU as. */ + fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line); + if (is_stmt != last_is_stmt) + { + fprintf (asm_out_file, " is_stmt %d", is_stmt ? 1 : 0); + last_is_stmt = is_stmt; + } + if (SUPPORTS_DISCRIMINATOR && discriminator != 0) + fprintf (asm_out_file, " discriminator %d", discriminator); + fputc ('\n', asm_out_file); + + /* Indicate that line number info exists. */ + line_info_table_in_use++; - /* Indicate that line number info exists. */ - line_info_table_in_use++; + prev_file_num = file_num; + prev_line = line; + } } else if (function_section (current_function_decl) != text_section) { diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/line-prog-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/line-prog-1.c new file mode 100644 index 0000000..63637dc --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/line-prog-1.c @@ -0,0 +1,25 @@ +/* + Origin: PR debug/47471 + { dg-options "-g -dA" } + */ + +int v; +void f (int i, ...) +{ + v++; +} + +int +main (void) +{ + f (1); + return 0; +} + +/* We want to have only one .loc directive that points to the opening + curly bracket of the definition of function f, at line 8. */ + +/* + { dg-final { scan-assembler-times "\.loc 1 8 0" 1 } } + + */ -- 1.7.3.4