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]

[rfc] fbreak (Finish Breakpoints by Name)


I would like to canvas for comments on this patch.  It is not being
formally submitted as a patch as it has no documentation or GDB tests.
We'll get to that later.

This patch idea was something that came up on irc.  Finish breakpoints
currently take a frame argument.  But it was discussed, and we thought
it would be neat, if it could take a location argument instead.  I
thought about modifying finish breakpoints that already exist, but
decided against this.

This command is a usability skin for finish breakpoints.  The command,
"fbreak" takes a location, and sets a breakpoint on that location.
When the breakpoint is hit, the "stop" callback on the initial
breakpoint is called.  This initial breakpoint then turns on process
record, and places a finish breakpoint in that function to catch
function exit.  When the function completes, the finish breakpoint
will print a message.  Here is an example:

(gdb) fbreak func4 
Breakpoint 5 at 0x4004f0: file test.c, line 3.
(gdb) r
Starting program: /home/pmuldoon/projects/test 
The finish breakpoint has triggered.  If the target
supports it, the process execution has been recorded from the
entry-point of the function where the breakpoint was placed.
Please remember to turn process record off with: 'record stop'
when you have completed debugging.

Temporary breakpoint -46, func3 () at test.c:9
9	}

(gdb) reverse-step
func4 () at test.c:4
4	}

(gdb) reverse-step
No more reverse-execution history.
func4 () at test.c:3
3	  return;

Finish breakpoints, as documented in that patch when it was submitted
some months ago, are useful for catching function exits. Think of a
scenario where you have a long complex function to debug.  This
function has multiple exit points.  Traditionally you would set a
breakpoint on each exit point, or just step through the function
manually.  This command, in conjunction with finish breakpoints,
simplifies that scenario.  And because it turns on process recording
only at the entry point of the function, you can step back and find
the exact path traversed through that function if you so require.

I am submitting this for [rfc] because I am not sure if this command
has utility for other people, or whether it even belongs in GDB (it
does some pretty heavy duty things like enabling reverse debugging),
and makes some assumptions on the linespec (it does not check if the
linespec is a function, for example, or a line in a function).

If we decide it is useful, I'll go ahead and document it, test it,
build ChangeLogs and so forth.

What do you think?

Cheers,

Phil

--

--- blank	2013-09-18 10:48:52.457034035 +0100
+++ fbreak.py	2013-09-18 10:48:29.928111023 +0100
@@ -1 +1,74 @@
- 
+# fbreak command.
+# Copyright (C) 2013 Free Software Foundation, Inc.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import gdb
+
+class FinishBP (gdb.FinishBreakpoint):
+    """Set a finish breakpoint and prints a message when hit."""
+    
+    def stop (self):
+        gdb.write("The finish breakpoint has triggered.  If the target\n\
+supports it, the process execution has been recorded from the\n\
+entry-point of the function where the breakpoint was placed.\n\
+Please remember to turn process record off with: 'record stop'\n\
+when you have completed debugging.\n")
+        return True
+          
+    def out_of_scope (self):
+        gdb.write("The finish breakpoint could not stop at the end of\n\
+the function, and has fallen out of scope.  If the target\n\
+supports it, the process execution has been recorded from\n\
+the entry-point of the function where the breakpoint was placed.\n\
+Please remember to turn process record off with: 'record stop'\n\
+when you have completed debugging.\n")
+
+class BuildFinishBP (gdb.Breakpoint):
+    """Set a breakpoint on entry point of a function, provided as an
+argument to the class.  When this breakpoint is hit, turn on
+process record and set a finish breakpoint for function exit."""
+
+    def __init__(self, function):
+        super(BuildFinishBP, self).__init__(function)
+        self.function = function
+        
+    def stop (self):
+        frame = gdb.selected_frame()
+        if str(frame.function()) == self.function:
+            fbp = FinishBP(frame, True)
+            cli_out = gdb.execute("record", to_string=True)
+
+        return False
+        
+class FBreakByName (gdb.Command):
+       """fbreak LOCATION: Set a Finish breakpoint by name.  Takes a
+location as a mandatory argument."""
+
+       def __init__ (self):
+         super(FBreakByName, self).__init__ ("fbreak", gdb.COMMAND_DATA,
+                                             gdb.COMPLETE_LOCATION)
+       def invoke (self, arg, from_tty):
+           if arg != "":
+               linespec = gdb.decode_line (str(arg))
+
+               # Before we set the breakpoint, warn if there was anything
+               # unparsed.
+               if linespec[0] != None:
+                   gdb.write("Warning: parts of the expression are unparsed.\n")
+               
+               nbp = BuildFinishBP(str(arg))
+           else:
+               raise gdb.GdbError("You must provide a location.")
+               
+FBreakByName()


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