[RFC/RFA?] Should break FILE:LINENO skip prologue?

Joel Brobecker
2008-01-09T15:18:15Z

[-- Attachment #1: Type: text/plain, Size: 2936 bytes --]

Hello,

I would like to revive a discussion that started sometime in 2002.
The idea is the following: When breaking on a given source line, if
that line is inside a function prologue, skip the prologue (using
the linetable to do so).

In our experience, we have found that most users are not aware of
the existence of function prologues. When they break on the line
where a function is defined, they think the debugger is doing the
same thing than it would do if it inserted the breakpoint using
that function name. Unfortunately, it doesn't and they end up
having problems trying to print parameter values [1].

When we discussed this back in 2002, there wasn't an overwhelming
support for this proposal, but I think that we had mild support.
Both Apple and AdaCore have decided to implement this, and JimB
was also supporting the idea. I searched the archives, and I didn't
really find any negative support. I personally think that it's
friendlier and is usually what the typical user expects.

The only counter argument, IMO, is the fact that we're changing a
behavior that has been there for a long time... But the current
behavior is currently undocumented (or at least it wasn't in 2002
:-), and users can use the "break *FUNC_NAME" syntax if they don't
want the prologue to be skipped. Like Jim, I think this syntax
makes better sense - in fact, I have always naturally used the
*FUNC_NAME syntax in these cases, never really used line numbers.

So I am making this proposal again, with the hope of reaching
a decision, either yes or no. Or, as a compromise, we can control
the behavior through as setting. I would argue for the default value
to change the behavior, since: Deliberately breaking inside the
prologue is a relatively uncommon operation; and the users who expect
to break inside the prologue know what they are doing and will quickly
find a way around.

Here is a prototype that implements the proposal without the switch.
Surprisingly, the code has evolved in a way that it is now very
easy to implement. Adding the switch would be very simple too.

2008-01-09 Joel Brobecker <brobecker@adacore.com>

* breakpoint.c (skip_prologue_sal): New function.
(resolve_sal_pc): Adjust SAL past prologue if the SAL was
computed from a line number.

I can write a dedicated testcase or test for this, but I don't think
this will be necessary. A couple of testcases (ending-run.exp and
mi-break.exp) insert breakpoints on the line where a function is
defined, so they already test that this patch has some effect
(understand the testcases will need to be adjusted or they will
have some FAILS).

Tested on x86-linux. All the changes in the testsuite are expected.

Thoughts?

Thanks,
--
Joel

[1]: I think we have made some progress with parameter/variable
tracking with DWARF, but I think it's not activated by default
and we also still support platforms where DWARF is not available.

[-- Attachment #2: skip-prologue.diff --]
[-- Type: text/plain, Size: 1275 bytes --]

Index: breakpoint.c
===================================================================
--- breakpoint.c (revision 117)
+++ breakpoint.c (revision 118)
@@ -5446,6 +5446,25 @@ gdb_breakpoint (char *address, char *con
0);
}

+/* Adjust SAL to the first instruction past the function prologue.
+ The end of the prologue is determined using the line table from
+ the debugging information.
+
+ If SAL is already past the prologue, then do nothing. */
+
+static void
+skip_prologue_sal (struct symtab_and_line *sal)
+{
+ struct symbol *sym = find_pc_function (sal->pc);
+ struct symtab_and_line start_sal;
+
+ if (sym == NULL)
+ return;
+
+ start_sal = find_function_start_sal (sym, 1);
+ if (sal->pc < start_sal.pc)
+ *sal = start_sal;
+}

/* Helper function for break_command_1 and disassemble_command. */

@@ -5460,6 +5479,11 @@ resolve_sal_pc (struct symtab_and_line *
error (_("No line %d in file \"%s\"."),
sal->line, sal->symtab->filename);
sal->pc = pc;
+
+ /* If this SAL corresponds to a breakpoint inserted using
+ a line number, then skip the function prologue if necessary. */
+ if (sal->explicit_line)
+ skip_prologue_sal (sal);
}

if (sal->section == 0 && sal->symtab != NULL)