From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1085 invoked by alias); 6 Feb 2013 13:12:52 -0000 Received: (qmail 1041 invoked by uid 22791); 6 Feb 2013 13:12:50 -0000 X-SWARE-Spam-Status: No, hits=-4.6 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 06 Feb 2013 13:12:40 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1U34nm-0003gS-QB from Yao_Qi@mentor.com ; Wed, 06 Feb 2013 05:12:38 -0800 Received: from SVR-ORW-FEM-02.mgc.mentorg.com ([147.34.96.206]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Wed, 6 Feb 2013 05:12:38 -0800 Received: from qiyao.dyndns.org (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.1.289.1; Wed, 6 Feb 2013 05:12:37 -0800 Message-ID: <51125685.4050406@codesourcery.com> Date: Wed, 06 Feb 2013 13:12:00 -0000 From: Yao Qi User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: Pedro Alves CC: Subject: Re: [PATCH] New MI notification "=tsv-modified" References: <1359560580-1970-1-git-send-email-yao@codesourcery.com> <510C27CE.3090102@redhat.com> <510CCE26.50600@codesourcery.com> <510FF037.8000101@redhat.com> <51111F75.1020007@codesourcery.com> <51112835.1010303@redhat.com> In-Reply-To: <51112835.1010303@redhat.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit 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: 2013-02/txt/msg00138.txt.bz2 On 02/05/2013 11:41 PM, Pedro Alves wrote: > I think that even without refactoring, we should > do what tvariables_info_1 does and omit "current" if the value > is not known. The -trace-list-variables docs explain this > suppression -- we should probably copy that bit into the > notification docs. OK, that makes sense to me. A new test case is added in this version to verify that "current=XXX" appeared in the MI notification. Regression tested on x86_64-linux. -- Yao (齐尧) gdb/doc: 2013-02-06 Yao Qi * gdb.texinfo (GDB/MI Async Records): Document new MI notification "=tsv-modified". Update the document of MI notification "=tsv-created". * observer.texi (GDB Observers): New observer tsv_modified. Update observer tsv_created and tsv_deleted. gdb: 2013-02-06 Yao Qi * mi/mi-interp.c: Include "tracepoint.h". (mi_tsv_modified): Declare. (mi_tsv_created, mi_tsv_deleted): Update declaration. (mi_interpreter_init): Call observer_attach_tsv_modified. (mi_tsv_modified): New. (mi_tsv_created, mi_tsv_deleted): Update. * tracepoint.c (trace_variable_command): Call observer_notify_tsv_modified if the initial value of tsv is changed. (delete_trace_state_variable): Call observer_notify_tsv_deleted earlier. (trace_variable_command): Caller update. (create_tsv_from_upload): Likewise. * observer.sh: Declare "struct trace_state_variable". * NEWS: Mention the new MI notification "=tsv-modified". gdb/testsuite: 2013-02-06 Yao Qi * gdb.trace/mi-tsv-changed.exp (test_create_delete_tsv): Rename to ... (test_create_delete_modify_tsv): ... here. New test on modifying the initial value of a tsv. --- gdb/NEWS | 5 +- gdb/doc/gdb.texinfo | 10 +++- gdb/doc/observer.texi | 13 +++-- gdb/mi/mi-interp.c | 45 ++++++++++++--- gdb/observer.sh | 1 + gdb/testsuite/gdb.trace/mi-tsv-changed.exp | 88 +++++++++++++++++++++++++-- gdb/tracepoint.c | 14 +++-- 7 files changed, 147 insertions(+), 29 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 539ceb9..0e01deb 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -121,8 +121,9 @@ show print type typedefs "=cmd-param-changed". ** Trace frame changes caused by command "tfind" are now notified using new async record "=traceframe-changed". - ** The creation and deletion of trace state variables are now notified - using new async records "=tsv-created" and "=tsv-deleted". + ** The creation, deletion and modification of trace state variables + are now notified using new async records "=tsv-created", + "=tsv-deleted" and "=tsv-modified". ** The start and stop of process record are now notified using new async record "=record-started" and "=record-stopped". ** Memory changes are now notified using new async record diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index a8a7284..7e9b2ba 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -27945,15 +27945,21 @@ Reports that the trace frame was changed and its new number is @var{tfnum}. The number of the tracepoint associated with this trace frame is @var{tpnum}. -@item =tsv-created,name=@var{name},value=@var{value} +@item =tsv-created,name=@var{name},initial=@var{initial} Reports that the new trace state variable @var{name} is created with -value @var{value}. +initial value @var{initial}. @item =tsv-deleted,name=@var{name} @itemx =tsv-deleted Reports that the trace state variable @var{name} is deleted or all trace state variables are deleted. +@item =tsv-modified,name=@var{name},initial=@var{initial}[,current=@var{current}] +Reports that the trace state variable @var{name} is modified with +the initial value @var{initial}. The current value @var{current} of +trace state variable is optional and is reported if the current +value of trace state variable is known. + @item =breakpoint-created,bkpt=@{...@} @itemx =breakpoint-modified,bkpt=@{...@} @itemx =breakpoint-deleted,id=@var{number} diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi index 87c08e1..adb7085 100644 --- a/gdb/doc/observer.texi +++ b/gdb/doc/observer.texi @@ -236,16 +236,19 @@ method is called after a command @code{set @var{param} @var{value}}. is the value of changed parameter. @end deftypefun -@deftypefun void tsv_created (const char *@var{name}, LONGEST @var{value}) -The new trace state variable @var{name} is created with value -@var{value}. +@deftypefun void tsv_created (const struct trace_state_variable *@var{tsv}) +The new trace state variable @var{tsv} is created. @end deftypefun -@deftypefun void tsv_deleted (const char *@var{name}) -The trace state variable @var{name} is deleted. If @var{name} is +@deftypefun void tsv_deleted (const struct trace_state_variable *@var{tsv}) +The trace state variable @var{tsv} is deleted. If @var{tsv} is @code{NULL}, all trace state variables are deleted. @end deftypefun +@deftypefun void tsv_modified (const struct trace_state_variable *@var{tsv}) +The trace state value @var{tsv} is modified. +@end deftypefun + @deftypefun void test_notification (int @var{somearg}) This observer is used for internal testing. Do not use. See testsuite/gdb.gdb/observer.exp. diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index 6617647..d1fe33c 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -36,6 +36,7 @@ #include "solist.h" #include "gdb.h" #include "objfiles.h" +#include "tracepoint.h" /* These are the interpreter setup, etc. functions for the MI interpreter. */ @@ -71,8 +72,9 @@ static void mi_solib_loaded (struct so_list *solib); static void mi_solib_unloaded (struct so_list *solib); static void mi_about_to_proceed (void); static void mi_traceframe_changed (int tfnum, int tpnum); -static void mi_tsv_created (const char *name, LONGEST value); -static void mi_tsv_deleted (const char *name); +static void mi_tsv_created (const struct trace_state_variable *tsv); +static void mi_tsv_deleted (const struct trace_state_variable *tsv); +static void mi_tsv_modified (const struct trace_state_variable *tsv); static void mi_breakpoint_created (struct breakpoint *b); static void mi_breakpoint_deleted (struct breakpoint *b); static void mi_breakpoint_modified (struct breakpoint *b); @@ -137,6 +139,7 @@ mi_interpreter_init (struct interp *interp, int top_level) observer_attach_traceframe_changed (mi_traceframe_changed); observer_attach_tsv_created (mi_tsv_created); observer_attach_tsv_deleted (mi_tsv_deleted); + observer_attach_tsv_modified (mi_tsv_modified); observer_attach_breakpoint_created (mi_breakpoint_created); observer_attach_breakpoint_deleted (mi_breakpoint_deleted); observer_attach_breakpoint_modified (mi_breakpoint_modified); @@ -563,15 +566,15 @@ mi_traceframe_changed (int tfnum, int tpnum) /* Emit notification on creating a trace state variable. */ static void -mi_tsv_created (const char *name, LONGEST value) +mi_tsv_created (const struct trace_state_variable *tsv) { struct mi_interp *mi = top_level_interpreter_data (); target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "tsv-created," - "name=\"%s\",value=\"%s\"\n", - name, plongest (value)); + "name=\"%s\",initial=\"%s\"\n", + tsv->name, plongest (tsv->initial_value)); gdb_flush (mi->event_channel); } @@ -579,21 +582,47 @@ mi_tsv_created (const char *name, LONGEST value) /* Emit notification on deleting a trace state variable. */ static void -mi_tsv_deleted (const char *name) +mi_tsv_deleted (const struct trace_state_variable *tsv) { struct mi_interp *mi = top_level_interpreter_data (); target_terminal_ours (); - if (name != NULL) + if (tsv != NULL) fprintf_unfiltered (mi->event_channel, "tsv-deleted," - "name=\"%s\"\n", name); + "name=\"%s\"\n", tsv->name); else fprintf_unfiltered (mi->event_channel, "tsv-deleted\n"); gdb_flush (mi->event_channel); } +/* Emit notification on modifying a trace state variable. */ + +static void +mi_tsv_modified (const struct trace_state_variable *tsv) +{ + struct mi_interp *mi = top_level_interpreter_data (); + struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); + + target_terminal_ours (); + + fprintf_unfiltered (mi->event_channel, + "tsv-modified"); + + ui_out_redirect (mi_uiout, mi->event_channel); + + ui_out_field_string (mi_uiout, "name", tsv->name); + ui_out_field_string (mi_uiout, "initial", + plongest (tsv->initial_value)); + if (tsv->value_known) + ui_out_field_string (mi_uiout, "current", plongest (tsv->value)); + + ui_out_redirect (mi_uiout, NULL); + + gdb_flush (mi->event_channel); +} + /* Emit notification about a created breakpoint. */ static void diff --git a/gdb/observer.sh b/gdb/observer.sh index 3ff28a8..7b9e70c 100755 --- a/gdb/observer.sh +++ b/gdb/observer.sh @@ -64,6 +64,7 @@ struct so_list; struct objfile; struct thread_info; struct inferior; +struct trace_state_variable; EOF ;; esac diff --git a/gdb/testsuite/gdb.trace/mi-tsv-changed.exp b/gdb/testsuite/gdb.trace/mi-tsv-changed.exp index 4e7d5a4..0b9475e 100644 --- a/gdb/testsuite/gdb.trace/mi-tsv-changed.exp +++ b/gdb/testsuite/gdb.trace/mi-tsv-changed.exp @@ -23,11 +23,14 @@ if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ return -1 } -# Test notifications on creating and deleting TSV. +# Test notifications on creating, deleting and modifying TSV. -proc test_create_delete_tsv { } {with_test_prefix "create delete" { +proc test_create_delete_modify_tsv { } {with_test_prefix "create delete modify" { global binfile global decimal + global testfile + global srcdir subdir + global mi_gdb_prompt if [mi_gdb_start] { return @@ -35,10 +38,18 @@ proc test_create_delete_tsv { } {with_test_prefix "create delete" { mi_gdb_load ${binfile} mi_gdb_test "tvariable \$tvar1" \ - ".*=tsv-created,name=\"tvar1\",value=\"0\"\\\\n.*\\^done" \ + ".*=tsv-created,name=\"tvar1\",initial=\"0\"\\\\n.*\\^done" \ "tvariable \$tvar1" + mi_gdb_test "tvariable \$tvar1 = 1" \ + ".*=tsv-modified,name=\"tvar1\",initial=\"1\".*\\^done" \ + "tvariable \$tvar1 modified" + # No "=tsv-modified" notification is emitted, because the initial + # value is not changed. + mi_gdb_test "tvariable \$tvar1 = 1" \ + ".*\\\$tvar1 = 1\\\\n\"\r\n~\"Trace state .*\\\\n.*\\^done" \ + "tvariable \$tvar1 modified without notification" mi_gdb_test "tvariable \$tvar2 = 45" \ - ".*=tsv-created,name=\"tvar2\",value=\"45\"\\\\n.*\\^done" \ + ".*=tsv-created,name=\"tvar2\",initial=\"45\"\\\\n.*\\^done" \ "tvariable \$tvar2" mi_gdb_test "delete tvariable \$tvar2" \ @@ -49,6 +60,69 @@ proc test_create_delete_tsv { } {with_test_prefix "create delete" { ".*=tsv-deleted\\\\n.*\\^done" \ "delete all tvariables" + # Test target supports tracepoints or not. + clean_restart $testfile + + if ![runto_main] { + fail "Can't run to main to check for trace support" + return -1 + } + + if ![gdb_target_supports_trace] { + unsupported "Current target does not support trace" + return -1; + } + gdb_exit + if [mi_gdb_start] { + continue + } + + mi_gdb_reinitialize_dir $srcdir/$subdir + mi_gdb_load ${binfile} + + mi_gdb_test "tvariable \$tvar3 = 3" \ + ".*=tsv-created,name=\"tvar3\",initial=\"3\".*\\^done" \ + "tvariable \$tvar3 modified" + mi_gdb_test "-break-insert -a gdb_c_test" \ + {.*\^done,bkpt=.*} \ + "insert tracepoint on gdb_c_test" + # Define an action that increases $tvar3 + send_gdb "actions\n" + gdb_expect { + -re "End with" { + } + } + send_gdb "collect \$tvar3 += 3\nend\n" + set test "define actions" + gdb_expect { + -re ".*${mi_gdb_prompt}$" { + pass $test + } + timeout { + fail "$test (timeout)" + } + } + + mi_gdb_test "-break-insert begin" \ + {.*\^done,bkpt=.*} \ + "insert tracepoint on begin" + mi_gdb_test "-break-insert end" \ + {.*\^done,bkpt=.*} \ + "insert tracepoint on end" + mi_run_cmd + + mi_expect_stop "breakpoint-hit" "begin" ""\ + ".*" ".*" {"" "disp=\"keep\""} \ + "continue to begin breakpoint" + mi_gdb_test "-trace-start" {.*\^done} "trace start" + mi_send_resuming_command "exec-continue" "continuing to end" + mi_gdb_test "-trace-stop" {.*} "trace stop" + # Force GDB to get the current value of trace state variable. + mi_gdb_test "-trace-list-variables" ".*" "list trace variables" + mi_gdb_test "tvariable \$tvar3 = 2" \ + ".*=tsv-modified,name=\"tvar3\",initial=\"2\",current=\"6\".*\\^done" \ + "tvariable \$tvar3 modified" + }} @@ -121,11 +195,11 @@ proc test_upload_tsv { } { with_test_prefix "upload" { set tsv1_created 0 set tsv2_created 0 gdb_expect { - -re "=tsv-created,name=\"tvar1\",value=\"0\"" { + -re "=tsv-created,name=\"tvar1\",initial=\"0\"" { set tsv1_created 1 exp_continue } - -re "=tsv-created,name=\"tvar2\",value=\"45\"" { + -re "=tsv-created,name=\"tvar2\",initial=\"45\"" { set tsv2_created 1 exp_continue } @@ -148,7 +222,7 @@ proc test_upload_tsv { } { with_test_prefix "upload" { set gdbserver_reconnect_p 0 }} - test_create_delete_tsv + test_create_delete_modify_tsv # Test target supports tracepoints or not. diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index be45cb4..d0a360a 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -351,11 +351,11 @@ delete_trace_state_variable (const char *name) for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix) if (strcmp (name, tsv->name) == 0) { + observer_notify_tsv_deleted (tsv); + xfree ((void *)tsv->name); VEC_unordered_remove (tsv_s, tvariables, ix); - observer_notify_tsv_deleted (name); - return; } @@ -408,7 +408,11 @@ trace_variable_command (char *args, int from_tty) tsv = find_trace_state_variable (internalvar_name (intvar)); if (tsv) { - tsv->initial_value = initval; + if (tsv->initial_value != initval) + { + tsv->initial_value = initval; + observer_notify_tsv_modified (tsv); + } printf_filtered (_("Trace state variable $%s " "now has initial value %s.\n"), tsv->name, plongest (tsv->initial_value)); @@ -420,7 +424,7 @@ trace_variable_command (char *args, int from_tty) tsv = create_trace_state_variable (internalvar_name (intvar)); tsv->initial_value = initval; - observer_notify_tsv_created (tsv->name, initval); + observer_notify_tsv_created (tsv); printf_filtered (_("Trace state variable $%s " "created, with initial value %s.\n"), @@ -3586,7 +3590,7 @@ create_tsv_from_upload (struct uploaded_tsv *utsv) tsv->initial_value = utsv->initial_value; tsv->builtin = utsv->builtin; - observer_notify_tsv_created (tsv->name, tsv->initial_value); + observer_notify_tsv_created (tsv); do_cleanups (old_chain); -- 1.7.7.6