[RFC] stept, nextt, finisht, untilt, continuet

Doug Evans
2011-08-30T01:49:14Z

Hi.

Sometimes I want to run with scheduler-locking on, but having to turn it on,
perform the command, and remember to turn it off afterwards is annoying.

Another way to go would be to add a "-t" option to these commands.

Comments?
[NEWS and doc and testsuite completeness still todo, but no point yet]

2011-08-29 Doug Evans <dje@google.com>

* data-directory/Makefile.in (PYTHON_FILES): Add stept.py.
* python/lib/gdb/command/stept.py: New file.
* testsuite/gdb.python/stept-commands.exp: New file.
* testsuite/gdb.python/stept-commands.c: New file.

Index: data-directory/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/data-directory/Makefile.in,v
retrieving revision 1.9
diff -u -p -r1.9 Makefile.in
--- data-directory/Makefile.in 17 Aug 2011 10:41:20 -0000 1.9
+++ data-directory/Makefile.in 30 Aug 2011 01:40:20 -0000
@@ -58,7 +58,8 @@ PYTHON_FILES = \
gdb/prompt.py \
gdb/command/__init__.py \
gdb/command/pretty_printers.py \
- gdb/command/prompt.py
+ gdb/command/prompt.py \
+ gdb/command/stept.py

FLAGS_TO_PASS = \
"prefix=$(prefix)" \
--- /dev/null 2011-07-06 10:10:38.263079702 -0700
+++ python/lib/gdb/command/stept.py 2011-08-29 18:35:29.000000000 -0700
@@ -0,0 +1,123 @@
+# stept, nextt, untilt, finisht, continuet commands
+# Copyright (C) 2011 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/>.
+
+""" stept, nextt, untilt, finisht, continuet commands."""
+
+# TODO: st, nt aliases? others?
+# nt is ok, not a prefix of anything, st may be problematic
+# Another way to go is tstep with alias ts, but the current scheme follows
+# the stepi,nexti pattern, and tfoo is heavily used by tracepoints.
+
+import gdb
+
+
+def _run_command_locked(command, arg):
+ """Run a command with scheduler-locking on."""
+ previous = gdb.parameter("scheduler-locking")
+ gdb.execute("set scheduler-locking on")
+ try:
+ gdb.execute("%s %s" % (command, arg))
+ finally:
+ gdb.execute("set scheduler-locking %s" % previous)
+
+
+class Stept(gdb.Command):
+ """Same as the "step" command, but with scheduler-locking temporarily on.
+
+Usage: stept [N] - same as "step" command
+
+While the program is running, scheduler-locking is on, only
+the current thread runs."""
+
+ def __init__(self):
+ super(Stept, self).__init__("stept", gdb.COMMAND_RUNNING)
+
+ def invoke(self, arg, from_tty):
+ """GDB calls this to perform the command."""
+ _run_command_locked("step", arg)
+
+
+class Nextt(gdb.Command):
+ """Same as the "next" command, but with scheduler-locking temporarily on.
+
+Usage: nextt [N] - same as "next" command
+
+While the program is running, scheduler-locking is on, only
+the current thread runs."""
+
+ def __init__(self):
+ super(Nextt, self).__init__("nextt", gdb.COMMAND_RUNNING)
+
+ def invoke(self, arg, from_tty):
+ """GDB calls this to perform the command."""
+ _run_command_locked("next", arg)
+
+
+class Finisht(gdb.Command):
+ """Same as the "finish" command, but with scheduler-locking temporarily on.
+
+Usage: finisht - same as "finish" command
+
+While the program is running, scheduler-locking is on, only
+the current thread runs."""
+
+ def __init__(self):
+ super(Finisht, self).__init__("finisht", gdb.COMMAND_RUNNING)
+
+ def invoke(self, arg, from_tty):
+ """GDB calls this to perform the command."""
+ _run_command_locked("finish", arg)
+
+
+class Untilt(gdb.Command):
+ """Same as the "until" command, but with scheduler-locking temporarily on.
+
+Usage: untilt [location] - same as "until" command
+
+While the program is running, scheduler-locking is on, only
+the current thread runs."""
+
+ def __init__(self):
+ super(Untilt, self).__init__("untilt", gdb.COMMAND_RUNNING)
+
+ def invoke(self, arg, from_tty):
+ """GDB calls this to perform the command."""
+ _run_command_locked("until", arg)
+
+
+class Continuet(gdb.Command):
+ """Same as the "continue" command, but with scheduler-locking temporarily on.
+
+Usage: continuet [N]
+
+Note: In non-stop mode, "continue" also continues only the current thread.
+
+While the program is running, scheduler-locking is on, only
+the current thread runs."""
+
+ def __init__(self):
+ super(Continuet, self).__init__("continuet", gdb.COMMAND_RUNNING)
+
+ def invoke(self, arg, from_tty):
+ """GDB calls this to perform the command."""
+ _run_command_locked("continue", arg)
+
+
+Stept()
+Nextt()
+Finisht()
+Untilt()
+Continuet()
--- /dev/null 2011-07-06 10:10:38.263079702 -0700
+++ testsuite/gdb.python/stept-commands.exp 2011-08-29 17:49:14.000000000 -0700
@@ -0,0 +1,79 @@
+# Copyright (C) 2011 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/>.
+
+# Test the stept, nextt, finisht, untilt, continuet commands.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "stept-commands"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+clean_restart ${testfile}
+runto_main
+
+# Skip all tests if Python scripting is not enabled.
+# stept/nextt are implemented in python, but that's just
+# an implementation detail.
+if { [skip_python_tests] } { continue }
+
+gdb_test "break break_me" \
+ "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on break_me"
+gdb_test "continue" \
+ ".*Breakpoint 2, break_me ().*" \
+ "run to break_me"
+
+gdb_test "thread 2" "Switching to thread 2 .*"
+
+gdb_test_no_output "set continue_thread = 1"
+
+proc verify_not_main { test_name } {
+ global gdb_prompt
+
+ gdb_test_multiple "f 0" "verify not main" {
+ -re "break_me ().*$gdb_prompt $" {
+ fail "main not run ($test_name)"
+ }
+ -re ".*$gdb_prompt $" {
+ pass "main not run ($test_name)"
+ }
+ }
+}
+
+set break_line [gdb_get_line_number "Break here"]
+gdb_test "b $break_line" ".*"
+gdb_test "continuet" "Break here.*"
+verify_not_main "continuet"
+
+set loop_count 10
+
+# Stept the thread, main should not run.
+for { set i 0 } { $i < $loop_count } { incr i } {
+ gdb_test "stept"
+ verify_not_main "stept #$i"
+}
+
+# Nextt the thread, main should not run.
+for { set i 0 } { $i < $loop_count } { incr i } {
+ gdb_test "nextt"
+ verify_not_main "nextt #$i"
+}
--- /dev/null 2011-07-06 10:10:38.263079702 -0700
+++ testsuite/gdb.python/stept-commands.c 2011-08-29 17:49:14.000000000 -0700
@@ -0,0 +1,65 @@
+/* Test program for stept, nextt, finisht, untilt, continuet.
+
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+/* Set by stept-nextt.exp. */
+volatile int continue_thread = 0;
+
+static void
+sleep_10th_second (void)
+{
+ const struct timespec ts = { 0, 100000000 }; /* 0.1 sec */
+
+ nanosleep (&ts, NULL);
+}
+
+void *
+forever_pthread (void *unused)
+{
+ while (! continue_thread)
+ sleep_10th_second ();
+
+ for (;;)
+ sleep_10th_second (); /* Break here. */
+}
+
+void
+break_me (void)
+{
+ /* Just an anchor to help putting a breakpoint. */
+}
+
+int
+main (void)
+{
+ pthread_t forever;
+
+ pthread_create (&forever, NULL, forever_pthread, NULL);
+ break_me ();
+
+ for (;;)
+ break_me ();
+
+ return 0;
+}
+