From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18638 invoked by alias); 4 May 2008 14:38:45 -0000 Received: (qmail 18624 invoked by uid 22791); 4 May 2008 14:38:42 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 04 May 2008 14:38:19 +0000 Received: (qmail 17635 invoked from network); 4 May 2008 14:38:16 -0000 Received: from unknown (HELO localhost) (vladimir@127.0.0.2) by mail.codesourcery.com with ESMTPA; 4 May 2008 14:38:16 -0000 From: Vladimir Prus To: Daniel Jacobowitz , Eli Zaretskii Subject: Re: [RFA] Implement *running. Date: Sun, 04 May 2008 16:33:00 -0000 User-Agent: KMail/1.9.6 (enterprise 0.20070907.709405) Cc: gdb-patches@sources.redhat.com References: <200805011735.52447.vladimir@codesourcery.com> <20080502155719.GT29202@caradoc.them.org> In-Reply-To: <20080502155719.GT29202@caradoc.them.org> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_4ocHINAKUsxuvKG" Message-Id: <200805041837.44909.vladimir@codesourcery.com> 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: 2008-05/txt/msg00172.txt.bz2 --Boundary-00=_4ocHINAKUsxuvKG Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 1835 On Friday 02 May 2008 19:57:19 Daniel Jacobowitz wrote: > On Thu, May 01, 2008 at 04:35:52PM +0300, Vladimir Prus wrote: > > This has no regressions in default and async modes on x86. OK? > > Just minor concerns. Docs - yes, I know very well that you know this > - but making sure we see docs before the code change goes in makes > sure that no one forgets in the crush of other patches. So, sorry, > but expect to keep getting this reply :-) I've added the docs. Eli, are those OK? > Also, what are the expected changes in async and non-async? Will we > start generating this for non-async and is that likely to break any > frontend? The expected change than any command that resumes a target will produce *running, in either all-stop or non-stop mode. I don't expect this to break any frontend, as frontends are supposed to ignore things they don't understand. > > > * doc/observer.texi (target_resumed): New observer. > > Doc has its own changelog. > > > diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp > > index 48527fd..b895020 100644 > > --- a/gdb/testsuite/gdb.mi/mi-break.exp > > +++ b/gdb/testsuite/gdb.mi/mi-break.exp > > @@ -174,11 +174,11 @@ proc test_error {} { > > # containing function call, the internal breakpoint created to handle > > # function call would be reported, messing up MI output. > > mi_gdb_test "-var-create V * return_1()" \ > > - "\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \ > > + ".*\\^done,name=\"V\",numchild=\"0\",value=\"1\",type=\"int\"" \ > > "create varobj for function call" > > The comment suggests this test is supposed to fail if there is stray > output... adding a leading .* is not nice. Right. In fact, this test no longer has to be changed. Here's a revised patch, OK? - Volodya --Boundary-00=_4ocHINAKUsxuvKG Content-Type: text/x-diff; charset="iso-8859-1"; name="0001-Implement-running.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Implement-running.patch" Content-length: 24724 =46rom c269adfcba95237ead4911a3498e82d822275707 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Fri, 14 Mar 2008 13:12:37 +0300 Subject: [RFA] Implement *running. To: gdb-patches@sources.redhat.com X-KMail-Transport: CodeSourcery X-KMail-Identity: 901867920 * Makefile.in: Update dependencies. * gdbthread.h (struct thread_info): New field running_. (set_running, is_running): New. * thread.c (set_running, is_running): New. * inferior.h (suppress_normal_stop_observer): Rename to... (suppress_run_stop_observers): ..this. * infcmd.c (suppress_normal_stop_observer): Rename to... (suppress_run_stop_observers): ..this. (finish_command_continuation, finish_command): Adjust. * infcall.c (call_function_by_hand): Adjust. * infrun.c (normal_stop): Call set_running. * target.c (target_resume): New. Call set_running. * target.h (target_resume): Convert from macro to a function. * mi/mi-interp.c (mi_on_resume): New. (mi_interpreter_init): Register mi_on_resume. [doc] * observer.texi (target_resumed): New observer. * gdb.texinfo (GDB/MI Output Records): Document *running. [testsuite] * gdb.mi/mi-console.exp: Adjust. * gdb.mi/mi-syn-frame.exp: Adjust. * gdb.mi/mi2-console.exp: Adjust. * gdb.mi/mi2-syn-frame.exp: Adjust. * lib/mi-support.exp (mi_run_cmd): Adjust. (mi_send_resuming_command): Adjust. --- gdb/Makefile.in | 2 +- gdb/doc/gdb.texinfo | 8 ++++ gdb/doc/observer.texi | 5 +++ gdb/gdbthread.h | 11 ++++++ gdb/infcall.c | 2 +- gdb/infcmd.c | 9 +++-- gdb/inferior.h | 2 +- gdb/infrun.c | 3 +- gdb/mi/mi-interp.c | 15 ++++++++ gdb/target.c | 9 +++++ gdb/target.h | 6 +--- gdb/testsuite/gdb.mi/mi-console.exp | 2 +- gdb/testsuite/gdb.mi/mi-syn-frame.exp | 12 +++---- gdb/testsuite/gdb.mi/mi2-console.exp | 2 +- gdb/testsuite/gdb.mi/mi2-syn-frame.exp | 12 +++---- gdb/testsuite/lib/mi-support.exp | 6 ++-- gdb/thread.c | 61 ++++++++++++++++++++++++++++= ++++ 17 files changed, 135 insertions(+), 32 deletions(-) diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 6bf3a55..e618ae2 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2919,7 +2919,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h= ) $(gdbcore_h) \ target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \ $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \ $(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \ - $(exceptions_h) $(target_descriptions_h) $(gdb_stdint_h) + $(exceptions_h) $(target_descriptions_h) $(gdb_stdint_h) $(gdbthread_h) target-descriptions.o: target-descriptions.c $(defs_h) $(arch_utils_h) \ $(target_h) $(target_descriptions_h) $(vec_h) $(xml_tdesc_h) \ $(gdbcmd_h) $(gdb_assert_h) $(gdbtypes_h) $(reggroups_h) \ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f4b9417..14eaf43 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -18154,6 +18154,14 @@ The following is the list of possible async record= s: =20 @table @code =20 +@item *running,thread-id=3D"@var{thread}" +The target is now running. The @var{thread} field tells which +specific thread is now running, and can be @samp{all} if all threads +are running. The frontend should assume that no interaction with a=20 +running thread is possible after this notification is produced. +@value{GDBN} may emit this notification several times for a given +thread, and the frontend should handle this gracefully. + @item *stopped,reason=3D"@var{reason}" The target has stopped. The @var{reason} field can have one of the following values: diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi index af3835b..7d4d808 100644 --- a/gdb/doc/observer.texi +++ b/gdb/doc/observer.texi @@ -137,3 +137,8 @@ The thread specified by @var{t} has been created. The thread specified by @var{t} has exited. @end deftypefun =20 +@deftypefun void target_resumed (ptid_t @var{ptid}) +The target was resumed. The @var{ptid} parameter specifies which +thread was resume, and may be RESUME_ALL if all threads are resumed. +@end deftypefun + diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index 56cbd51..8e0da6f 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -69,6 +69,10 @@ struct thread_info =20 int proceed_to_finish; =20 + /* This field is internal for thread.c. Never access it directly, + use is_running instead. */ + int running_; + /* Private data used by the target vector implementation. */ struct private_thread_info *private; }; @@ -162,6 +166,13 @@ extern void load_infrun_state (ptid_t ptid, /* Switch from one thread to another. */ extern void switch_to_thread (ptid_t ptid); =20 +/* Marks thread PTID is running, or stopped.=20 + If PIDGET (PTID) is -1, marks all threads. */ +extern void set_running (ptid_t ptid, int running); + +/* Reports if thread PTID is know to be running right now. */ +extern int is_running (ptid_t ptid); + /* Commands with a prefix of `thread'. */ extern struct cmd_list_element *thread_cmd_list; =20 diff --git a/gdb/infcall.c b/gdb/infcall.c index 3b5f5ba..b580ecc 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -721,7 +721,7 @@ call_function_by_hand (struct value *function, int narg= s, struct value **args) saved_async =3D target_async_mask (0); =20 old_cleanups2 =3D make_cleanup_restore_integer=20 - (&suppress_normal_stop_observer, 1); + (&suppress_run_stop_observers, 1); proceed (real_pc, TARGET_SIGNAL_0, 0); do_cleanups (old_cleanups2); =20=20=20=20=20 diff --git a/gdb/infcmd.c b/gdb/infcmd.c index db0bfaf..b7f6435 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -207,8 +207,9 @@ int step_multi; =20 struct gdb_environ *inferior_environ; =20 -/* When set, normal_stop will not call the normal_stop observer. */ -int suppress_normal_stop_observer =3D 0; +/* When set, normal_stop will not call the normal_stop observer. + Resume observer likewise will not be called. */ +int suppress_run_stop_observers =3D 0; =0C /* Accessor routines. */ =20 @@ -1288,7 +1289,7 @@ finish_command_continuation (struct continuation_arg = *arg, int error_p) observer_notify_normal_stop (stop_bpstat); } =20 - suppress_normal_stop_observer =3D 0; + suppress_run_stop_observers =3D 0; delete_breakpoint (breakpoint); } =20 @@ -1355,7 +1356,7 @@ finish_command (char *arg, int from_tty) } =20 proceed_to_finish =3D 1; /* We want stop_registers, please... */ - make_cleanup_restore_integer (&suppress_normal_stop_observer, 1); + make_cleanup_restore_integer (&suppress_run_stop_observers, 1); proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); =20 arg1 =3D diff --git a/gdb/inferior.h b/gdb/inferior.h index 630cc52..8958aef 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -401,7 +401,7 @@ void displaced_step_dump_bytes (struct ui_file *file, =20 =20 /* When set, normal_stop will not call the normal_stop observer. */ -extern int suppress_normal_stop_observer; +extern int suppress_run_stop_observers; =0C /* Possible values for gdbarch_call_dummy_location. */ #define ON_STACK 1 diff --git a/gdb/infrun.c b/gdb/infrun.c index c061a16..1f8e9b3 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3757,11 +3757,12 @@ Further execution is probably impossible.\n")); =20 done: annotate_stopped (); - if (!suppress_normal_stop_observer && !step_multi) + if (!suppress_run_stop_observers && !step_multi) observer_notify_normal_stop (stop_bpstat); /* Delete the breakpoint we stopped at, if it wants to be deleted. Delete any breakpoint that is to be deleted at the next stop. */ breakpoint_auto_delete (stop_bpstat); + set_running (pid_to_ptid (-1), 0); } =20 static int diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index a9a5ffc..4ba1ce1 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -69,6 +69,7 @@ static void mi_on_normal_stop (struct bpstats *bs); =20 static void mi_new_thread (struct thread_info *t); static void mi_thread_exit (struct thread_info *t); +static void mi_on_resume (ptid_t ptid); =20 static void * mi_interpreter_init (int top_level) @@ -94,6 +95,7 @@ mi_interpreter_init (int top_level) observer_attach_new_thread (mi_new_thread); observer_attach_thread_exit (mi_thread_exit); observer_attach_normal_stop (mi_on_normal_stop); + observer_attach_target_resumed (mi_on_resume); } =20 return mi; @@ -317,6 +319,19 @@ mi_on_normal_stop (struct bpstats *bs) gdb_flush (raw_stdout); } =20 +static void +mi_on_resume (ptid_t ptid) +{ + if (PIDGET (ptid) =3D=3D -1) + fprintf_unfiltered (raw_stdout, "*running,thread-id=3D\"all\"\n"); + else + { + struct thread_info *ti =3D find_thread_pid (ptid); + gdb_assert (ti); + fprintf_unfiltered (raw_stdout, "*running,thread-id=3D\"%d\"\n", ti-= >num); + } +} + extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototype= s */ =20 void diff --git a/gdb/target.c b/gdb/target.c index a8f1afb..159b0fe 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -40,6 +40,7 @@ #include "exceptions.h" #include "target-descriptions.h" #include "gdb_stdint.h" +#include "gdbthread.h" =20 static void target_info (char *, int); =20 @@ -1714,6 +1715,14 @@ target_disconnect (char *args, int from_tty) tcomplain (); } =20 +void +target_resume (ptid_t ptid, int step, enum target_signal signal) +{ + dcache_invalidate (target_dcache); + (*current_target.to_resume) (ptid, step, signal); + set_running (ptid, 1); + +} /* Look through the list of possible targets for a target that can follow forks. */ =20 diff --git a/gdb/target.h b/gdb/target.h index 8822a40..9339d00 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -575,11 +575,7 @@ extern void target_disconnect (char *, int); the target, or TARGET_SIGNAL_0 for no signal. The caller may not pass TARGET_SIGNAL_DEFAULT. */ =20 -#define target_resume(ptid, step, siggnal) \ - do { \ - dcache_invalidate(target_dcache); \ - (*current_target.to_resume) (ptid, step, siggnal); \ - } while (0) +extern void target_resume (ptid_t ptid, int step, enum target_signal signa= l); =20 /* Wait for process pid to do something. PTID =3D -1 to wait for any pid to do something. Return pid of child, or -1 in case of error; diff --git a/gdb/testsuite/gdb.mi/mi-console.exp b/gdb/testsuite/gdb.mi/mi-= console.exp index 7d093dc..70d9342 100644 --- a/gdb/testsuite/gdb.mi/mi-console.exp +++ b/gdb/testsuite/gdb.mi/mi-console.exp @@ -52,7 +52,7 @@ mi_run_to_main =20 # Next over the hello() call which will produce lots of output mi_gdb_test "220-exec-next" \ - "220\\^running" \ + "220\\^running(\r\n\\*running,thread-id=3D\"all\")?" \ "Testing console output" \ "Hello \\\\\"!\[\r\n\]+" =20 diff --git a/gdb/testsuite/gdb.mi/mi-syn-frame.exp b/gdb/testsuite/gdb.mi/m= i-syn-frame.exp index 208678b..59b8e44 100644 --- a/gdb/testsuite/gdb.mi/mi-syn-frame.exp +++ b/gdb/testsuite/gdb.mi/mi-syn-frame.exp @@ -46,7 +46,7 @@ mi_create_breakpoint "foo" 2 keep foo ".*mi-syn-frame.c" = $decimal $hex \ # Call foo() by hand, where we'll hit a breakpoint. # =20 -mi_gdb_test "401-data-evaluate-expression foo()" "401\\^error,msg=3D\"The = program being debugged stopped while in a function called from GDB.\\\\nWhe= n the function \\(foo\\) is done executing, GDB will silently\\\\nstop \\(i= nstead of continuing to evaluate the expression containing\\\\nthe function= call\\).\"" "call inferior's function with a breakpoint set in it" +mi_gdb_test "401-data-evaluate-expression foo()" ".*401\\^error,msg=3D\"Th= e program being debugged stopped while in a function called from GDB.\\\\nW= hen the function \\(foo\\) is done executing, GDB will silently\\\\nstop \\= (instead of continuing to evaluate the expression containing\\\\nthe functi= on call\\).\"" "call inferior's function with a breakpoint set in it" =20 =20 mi_gdb_test "402-stack-list-frames" "402\\^done,stack=3D\\\[frame=3D\{leve= l=3D\"0\",addr=3D\"$hex\",func=3D\"foo\",file=3D\".*mi-syn-frame.c\",line= =3D\"$decimal\"\},frame=3D\{level=3D\"1\",addr=3D\"$hex\",func=3D\"\"\},frame=3D\{level=3D\"2\",addr=3D\"$hex\",func=3D\"mai= n\",file=3D\".*mi-syn-frame.c\",line=3D\"$decimal\"\}.*\\\]" "backtrace fro= m inferior function stopped at bp, showing gdb dummy frame" @@ -54,9 +54,7 @@ mi_gdb_test "402-stack-list-frames" "402\\^done,stack=3D\= \\[frame=3D\{level=3D\"0\",ad # # Continue back to main() # -mi_gdb_test "403-exec-continue" \ - "403\\^running" \ - "testing exec continue" +mi_send_resuming_command "exec-continue" "testing exec continue" =20 mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue" =20 @@ -73,7 +71,7 @@ mi_create_breakpoint "subroutine" 3 keep subroutine ".*mi= -syn-frame.c" $decimal "insert breakpoint subroutine" =20 mi_gdb_test "406-data-evaluate-expression have_a_very_merry_interrupt()" \ - "406\\^error,msg=3D\"The program being debugged stopped while in a funct= ion called from GDB.\\\\nWhen the function \\(have_a_very_merry_interrupt\\= ) is done executing, GDB will silently\\\\nstop \\(instead of continuing to= evaluate the expression containing\\\\nthe function call\\).\"" \ + ".*406\\^error,msg=3D\"The program being debugged stopped while in a fun= ction called from GDB.\\\\nWhen the function \\(have_a_very_merry_interrupt= \\) is done executing, GDB will silently\\\\nstop \\(instead of continuing = to evaluate the expression containing\\\\nthe function call\\).\"" \ "data evaluate expression" =20 # We should have both a signal handler and a call dummy frame @@ -84,7 +82,7 @@ mi_gdb_test "407-stack-list-frames" \ "list stack frames" =20 =20 -mi_gdb_test "408-exec-continue" "408\\^running" +mi_send_resuming_command "exec-continue" "testing exec continue" =20 mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue" =20 @@ -97,7 +95,7 @@ mi_gdb_test "409-stack-list-frames 0 0" \ #=20 =20 mi_gdb_test "410-data-evaluate-expression bar()" \ - "410\\^error,msg=3D\"The program being debugged was signaled while in a = function called from GDB.\\\\nGDB remains in the frame where the signal was= received.\\\\nTo change this behavior use \\\\\"set unwindonsignal on\\\\\= "\\\\nEvaluation of the expression containing the function \\(bar\\) will b= e abandoned.\"" \ + ".*410\\^error,msg=3D\"The program being debugged was signaled while in = a function called from GDB.\\\\nGDB remains in the frame where the signal w= as received.\\\\nTo change this behavior use \\\\\"set unwindonsignal on\\\= \\"\\\\nEvaluation of the expression containing the function \\(bar\\) will= be abandoned.\"" \ "call inferior function which raises exception" =20 mi_gdb_test "411-stack-list-frames" "411\\^done,stack=3D\\\[frame=3D\{leve= l=3D\"0\",addr=3D\"$hex\",func=3D\"bar\",file=3D\".*mi-syn-frame.c\",fullna= me=3D\"${fullname_syntax}${srcfile}\",line=3D\"$decimal\"},frame=3D\{level= =3D\"1\",addr=3D\"$hex\",func=3D\"\"\},frame=3D\{= level=3D\"2\",addr=3D\"$hex\",func=3D\"main\",file=3D\".*mi-syn-frame.c\",f= ullname=3D\"${fullname_syntax}${srcfile}\",line=3D\"$decimal\"}.*\\\]" "bac= ktrace from inferior function at exception" diff --git a/gdb/testsuite/gdb.mi/mi2-console.exp b/gdb/testsuite/gdb.mi/mi= 2-console.exp index 88b4fdd..c5f6f81 100644 --- a/gdb/testsuite/gdb.mi/mi2-console.exp +++ b/gdb/testsuite/gdb.mi/mi2-console.exp @@ -53,7 +53,7 @@ mi_run_to_main # Next over the hello() call which will produce lots of output send_gdb "220-exec-next\n" gdb_expect { - -re "220\\^running\r\n$mi_gdb_prompt" { + -re "220\\^running\r\n(\\*running,thread-id=3D\"all\"\r\n)?$mi_gdb_pro= mpt" { pass "Started step over hello" } timeout { diff --git a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp b/gdb/testsuite/gdb.mi/= mi2-syn-frame.exp index b69812f..948e98d 100644 --- a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp +++ b/gdb/testsuite/gdb.mi/mi2-syn-frame.exp @@ -48,7 +48,7 @@ mi_create_breakpoint "foo" 2 keep foo ".*mi-syn-frame.c" = $decimal $hex \ # Call foo() by hand, where we'll hit a breakpoint. # =20 -mi_gdb_test "401-data-evaluate-expression foo()" "401\\^error,msg=3D\"The = program being debugged stopped while in a function called from GDB.\\\\nWhe= n the function \\(foo\\) is done executing, GDB will silently\\\\nstop \\(i= nstead of continuing to evaluate the expression containing\\\\nthe function= call\\).\"" "call inferior's function with a breakpoint set in it" +mi_gdb_test "401-data-evaluate-expression foo()" ".*401\\^error,msg=3D\"Th= e program being debugged stopped while in a function called from GDB.\\\\nW= hen the function \\(foo\\) is done executing, GDB will silently\\\\nstop \\= (instead of continuing to evaluate the expression containing\\\\nthe functi= on call\\).\"" "call inferior's function with a breakpoint set in it" =20 mi_gdb_test "402-stack-list-frames" "402\\^done,stack=3D\\\[frame=3D\{leve= l=3D\"0\",addr=3D\"$hex\",func=3D\"foo\",file=3D\".*mi-syn-frame.c\",line= =3D\"$decimal\"\},frame=3D\{level=3D\"1\",addr=3D\"$hex\",func=3D\"\"\},frame=3D\{level=3D\"2\",addr=3D\"$hex\",func=3D\"mai= n\",file=3D\".*mi-syn-frame.c\",line=3D\"$decimal\"\}.*\\\]" "backtrace fro= m inferior function stopped at bp, showing gdb dummy frame" =20 @@ -56,9 +56,7 @@ mi_gdb_test "402-stack-list-frames" "402\\^done,stack=3D\= \\[frame=3D\{level=3D\"0\",ad # Continue back to main() # =20 -mi_gdb_test "403-exec-continue" \ - "403\\^running" \ - "testing exec continue" +mi_send_resuming_command "exec-continue" "testing exec continue" =20 mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue" =20 @@ -75,7 +73,7 @@ mi_create_breakpoint "subroutine" 3 keep subroutine ".*mi= -syn-frame.c" $decimal "insert breakpoint subroutine" =20 mi_gdb_test "406-data-evaluate-expression have_a_very_merry_interrupt()" \ - "406\\^error,msg=3D\"The program being debugged stopped while in a funct= ion called from GDB.\\\\nWhen the function \\(have_a_very_merry_interrupt\\= ) is done executing, GDB will silently\\\\nstop \\(instead of continuing to= evaluate the expression containing\\\\nthe function call\\).\"" \ + ".*406\\^error,msg=3D\"The program being debugged stopped while in a fun= ction called from GDB.\\\\nWhen the function \\(have_a_very_merry_interrupt= \\) is done executing, GDB will silently\\\\nstop \\(instead of continuing = to evaluate the expression containing\\\\nthe function call\\).\"" \ "evaluate expression have_a_very_merry_interrupt" =20 # We should have both a signal handler and a call dummy frame @@ -85,7 +83,7 @@ mi_gdb_test "407-stack-list-frames" \ "407\\^done,stack=3D\\\[frame=3D\{level=3D\"0\",addr=3D\"$hex\",func=3D\= "subroutine\",file=3D\".*mi-syn-frame.c\",line=3D\"$decimal\"\},frame=3D\{l= evel=3D\"1\",addr=3D\"$hex\",func=3D\"handler\",file=3D\".*mi-syn-frame.c\"= ,line=3D\"$decimal\"\},frame=3D\{level=3D\"2\",addr=3D\"$hex\",func=3D\"\"\},.*frame=3D\{level=3D\"$decimal\",addr=3D\"$hex\",f= unc=3D\"have_a_very_merry_interrupt\",file=3D\".*mi-syn-frame.c\",line=3D\"= $decimal\"\},frame=3D\{level=3D\"$decimal\",addr=3D\"$hex\",func=3D\"\"\},frame=3D\{level=3D\"$decimal\",addr=3D\"$hex\",fun= c=3D\"main\",file=3D\".*mi-syn-frame.c\",line=3D\"$decimal\"\}.*\\\]" \ "list stack frames" =20 -mi_gdb_test "408-exec-continue" "408\\^running" +mi_send_resuming_command "exec-continue" "testing exec continue" =20 mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue" =20 @@ -97,7 +95,7 @@ mi_gdb_test "409-stack-list-frames 0 0" \ # Call bar() by hand, which should get an exception while running. #=20 =20 -mi_gdb_test "410-data-evaluate-expression bar()" "410\\^error,msg=3D\"The = program being debugged was signaled while in a function called from GDB.\\\= \nGDB remains in the frame where the signal was received.\\\\nTo change thi= s behavior use \\\\\"set unwindonsignal on\\\\\"\\\\nEvaluation of the expr= ession containing the function \\(bar\\) will be abandoned.\"" "call inferi= or function which raises exception" +mi_gdb_test "410-data-evaluate-expression bar()" ".*410\\^error,msg=3D\"Th= e program being debugged was signaled while in a function called from GDB.\= \\\nGDB remains in the frame where the signal was received.\\\\nTo change t= his behavior use \\\\\"set unwindonsignal on\\\\\"\\\\nEvaluation of the ex= pression containing the function \\(bar\\) will be abandoned.\"" "call infe= rior function which raises exception" =20 mi_gdb_test "411-stack-list-frames" "411\\^done,stack=3D\\\[frame=3D\{leve= l=3D\"0\",addr=3D\"$hex\",func=3D\"bar\",file=3D\".*mi-syn-frame.c\",fullna= me=3D\"${fullname_syntax}${srcfile}\",line=3D\"$decimal\"},frame=3D\{level= =3D\"1\",addr=3D\"$hex\",func=3D\"\"\},frame=3D\{= level=3D\"2\",addr=3D\"$hex\",func=3D\"main\",file=3D\".*mi-syn-frame.c\",f= ullname=3D\"${fullname_syntax}${srcfile}\",line=3D\"$decimal\"}.*\\\]" "bac= ktrace from inferior function at exception" =20 diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-suppor= t.exp index 23f3f07..7a821b8 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -802,7 +802,7 @@ proc mi_run_cmd {args} { if [target_info exists gdb,do_reload_on_run] { send_gdb "220-exec-continue\n"; gdb_expect 60 { - -re "220\\^running\[\r\n\]+$mi_gdb_prompt$" {} + -re "220\\^running\[\r\n\]+(\\*running,thread-id=3D\"\[^\"\]+\"\r\n)?$mi= _gdb_prompt$" {} default {} } return; @@ -823,7 +823,7 @@ proc mi_run_cmd {args} { =20 send_gdb "220-exec-run $args\n" gdb_expect { - -re "220\\^running\r\n(=3Dthread-created,id=3D\"1\"\r\n)?${mi_gdb_prompt}= " { + -re "220\\^running\r\n(\\*running,thread-id=3D\"\[^\"\]+\"\r\n|=3Dthread-= created,id=3D\"1\"\r\n)*${mi_gdb_prompt}" { } timeout { perror "Unable to start target" @@ -1399,7 +1399,7 @@ proc mi_send_resuming_command {command test} { =20 send_gdb "220-$command\n" gdb_expect { - -re "220\\^running\r\n${mi_gdb_prompt}" { + -re "220\\^running\r\n(\\*running,thread-id=3D\"\[^\"\]+\"\r\n)?${= mi_gdb_prompt}" { } -re ".*${mi_gdb_prompt}" { fail "$test (failed to resume)" diff --git a/gdb/thread.c b/gdb/thread.c index fe93b75..60948b8 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -440,6 +440,67 @@ prune_threads (void) } } =20 +static int main_thread_running =3D 0; + +void +set_running (ptid_t ptid, int running) +{ + struct thread_info *tp; + + if (!thread_list) + { + /* This is one of the targets that does not add main + thread to the thread list. Just use a single + global flag to indicate that a thread is running.=20=20 + + This problem is unique to ST programs. For MT programs, + the main thread is always present in the thread list. If it's + not, the first call to context_switch will mess up GDB internal + state. */ + if (running && !main_thread_running && !suppress_run_stop_observers) + observer_notify_target_resumed (ptid); + main_thread_running =3D running; + return; + } + + /* We try not to notify the observer if no thread has actually changed=20 + the running state -- merely to reduce the number of messages to=20 + frontend. Frontend is supposed to handle multiple *running just fine= . */ + if (PIDGET (ptid) =3D=3D -1) + { + int any_started =3D 0; + for (tp =3D thread_list; tp; tp =3D tp->next) + { + if (running && !tp->running_) + any_started =3D 1; + tp->running_ =3D running; + } + if (any_started && !suppress_run_stop_observers) + observer_notify_target_resumed (ptid);=20=20=20=20=20=20 + } + else + { + tp =3D find_thread_pid (ptid); + gdb_assert (tp); + if (running && !tp->running_ && !suppress_run_stop_observers) + observer_notify_target_resumed (ptid); + tp->running_ =3D running; + }=20=20 +} + +int +is_running (ptid_t ptid) +{ + struct thread_info *tp; + + if (!thread_list) + return main_thread_running; + + tp =3D find_thread_pid (ptid); + gdb_assert (tp); + return tp->running_;=20=20 +} + /* Prints the list of threads and their details on UIOUT. This is a version of 'info_thread_command' suitable for use from MI.=20=20 --=20 1.5.3.5 --Boundary-00=_4ocHINAKUsxuvKG--