From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13883 invoked by alias); 30 Aug 2011 01:49:14 -0000 Received: (qmail 13444 invoked by uid 22791); 30 Aug 2011 01:49:11 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 30 Aug 2011 01:48:54 +0000 Received: from hpaq12.eem.corp.google.com (hpaq12.eem.corp.google.com [172.25.149.12]) by smtp-out.google.com with ESMTP id p7U1mram007117 for ; Mon, 29 Aug 2011 18:48:53 -0700 Received: from ruffy.mtv.corp.google.com (ruffy.mtv.corp.google.com [172.18.110.50]) by hpaq12.eem.corp.google.com with ESMTP id p7U1mpeN009337 for ; Mon, 29 Aug 2011 18:48:52 -0700 Received: by ruffy.mtv.corp.google.com (Postfix, from userid 67641) id 78030246131; Mon, 29 Aug 2011 18:48:51 -0700 (PDT) To: gdb-patches@sourceware.org Subject: [RFC] stept, nextt, finisht, untilt, continuet Message-Id: <20110830014851.78030246131@ruffy.mtv.corp.google.com> Date: Tue, 30 Aug 2011 01:49:00 -0000 From: dje@google.com (Doug Evans) X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-08/txt/msg00581.txt.bz2 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 * 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 . + +""" 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 . + +# 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 . */ + +#include +#include +#include +#include + +/* 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; +} +