Fix 324514 gdbserver monitor cmd output behaviour consistency + allow user
to put a "marker" msg in process log output
* v.info n_errs_found accepts optional msg, added in the output of
the monitor command.
* use VG_(printf) rather than VG_(gdb_printf) when output of command
should be redirected according to v.set gdb_output|log_output|mixed_output
* also avoid calling gdb_printf in output sink processing
to output zero bytes, as gdb_printf expects to have a null terminated
string, which is not ensured when 0 bytes have to be output.
* some minor reformatting (replace char* xxx by char *xxx).
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13532 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_gdbserver/server.c b/coregrind/m_gdbserver/server.c
index 5e79fd0..46abb7c 100644
--- a/coregrind/m_gdbserver/server.c
+++ b/coregrind/m_gdbserver/server.c
@@ -122,6 +122,31 @@
VG_(exit) (0);
}
+// s is a NULL terminated string made of O or more words (separated by spaces).
+// Returns a pointer to the Nth word in s.
+// If Nth word does not exist, return a pointer to the last (0) byte of s.
+static
+const char *wordn (const char *s, int n)
+{
+ int word_seen = 0;
+ Bool searching_word = True;
+
+ while (*s) {
+ if (*s == ' ')
+ searching_word = True;
+ else {
+ if (searching_word) {
+ searching_word = False;
+ word_seen++;
+ if (word_seen == n)
+ return s;
+ }
+ }
+ s++;
+ }
+ return s;
+}
+
/* handle_gdb_valgrind_command handles the provided mon string command.
If command is recognised, return 1 else return 0.
Note that in case of ambiguous command, 1 is returned.
@@ -130,13 +155,13 @@
'v.set *_output' is handled.
*/
static
-int handle_gdb_valgrind_command (char* mon, OutputSink* sink_wanted_at_return)
+int handle_gdb_valgrind_command (char *mon, OutputSink *sink_wanted_at_return)
{
UWord ret = 0;
char s[strlen(mon)+1]; /* copy for strtok_r */
- char* wcmd;
- HChar* ssaveptr;
- const char* endptr;
+ char *wcmd;
+ HChar *ssaveptr;
+ const char *endptr;
int kwdid;
int int_value;
@@ -175,7 +200,7 @@
" v.wait [<ms>] : sleep <ms> (default 0) then continue\n"
" v.info all_errors : show all errors found so far\n"
" v.info last_error : show last error found\n"
-" v.info n_errs_found : show the nr of errors found so far\n"
+" v.info n_errs_found [msg] : show the nr of errors found so far and the given msg\n"
" v.info open_fds : show open file descriptors (only if --track-fds=yes)\n"
" v.kill : kill the Valgrind process\n"
" v.set gdb_output : set valgrind output to gdb\n"
@@ -222,15 +247,15 @@
if (*endptr != '\0') {
VG_(gdb_printf) ("missing or malformed integer value\n");
} else if (kwdid == 0) {
- VG_(gdb_printf) ("vgdb-error value changed from %d to %d\n",
+ VG_(printf) ("vgdb-error value changed from %d to %d\n",
VG_(dyn_vgdb_error), int_value);
VG_(dyn_vgdb_error) = int_value;
} else if (kwdid == 1) {
- VG_(gdb_printf) ("debuglog value changed from %d to %d\n",
+ VG_(printf) ("debuglog value changed from %d to %d\n",
VG_(debugLog_getLevel)(), int_value);
VG_(debugLog_startup) (int_value, "gdbsrv");
} else if (kwdid == 2) {
- VG_(gdb_printf)
+ VG_(printf)
("merge-recursive-frames value changed from %d to %d\n",
VG_(clo_merge_recursive_frames), int_value);
VG_(clo_merge_recursive_frames) = int_value;
@@ -273,10 +298,11 @@
VG_(show_all_errors)(/* verbosity */ 2, /* xml */ False);
break;
case 1: // n_errs_found
- VG_(gdb_printf) ("n_errs_found %d n_errs_shown %d (vgdb-error %d)\n",
- VG_(get_n_errs_found) (),
- VG_(get_n_errs_shown) (),
- VG_(dyn_vgdb_error));
+ VG_(printf) ("n_errs_found %d n_errs_shown %d (vgdb-error %d) %s\n",
+ VG_(get_n_errs_found) (),
+ VG_(get_n_errs_shown) (),
+ VG_(dyn_vgdb_error),
+ wordn (mon, 3));
break;
case 2: // last_error
VG_(show_last_error)();
@@ -328,10 +354,10 @@
wcmd = strtok_r (NULL, " ", &ssaveptr);
if (wcmd != NULL) {
int_value = strtol (wcmd, NULL, 10);
- VG_(gdb_printf) ("gdbserver: continuing in %d ms ...\n", int_value);
+ VG_(printf) ("gdbserver: continuing in %d ms ...\n", int_value);
VG_(poll)(NULL, 0, int_value);
}
- VG_(gdb_printf) ("gdbserver: continuing after wait ...\n");
+ VG_(printf) ("gdbserver: continuing after wait ...\n");
ret = 1;
break;
case 4: /* v.kill */
@@ -410,7 +436,7 @@
Note that in case of ambiguous command, 1 is returned.
*/
static
-int handle_gdb_monitor_command (char* mon)
+int handle_gdb_monitor_command (char *mon)
{
UWord ret = 0;
UWord tool_ret = 0;
@@ -450,6 +476,8 @@
VG_(dyn_vgdb_error) = save_dyn_vgdb_error;
}
+ VG_(message_flush) ();
+
/* restore or set the desired output */
VG_(log_output_sink).fd = sink_wanted_at_return.fd;
if (ret | tool_ret)
@@ -496,7 +524,7 @@
arg_own_buf[0] = 0;
}
-Bool VG_(client_monitor_command) (HChar* cmd)
+Bool VG_(client_monitor_command) (HChar *cmd)
{
const Bool connected = remote_connected();
const int saved_command_output_to_log = command_output_to_log;
@@ -535,9 +563,6 @@
cmd[cmdlen] = '\0';
if (handle_gdb_monitor_command (cmd)) {
- /* In case the command is from a standalone vgdb,
- connection will be closed soon => flush the output. */
- VG_(message_flush) ();
write_ok (arg_own_buf);
return;
} else {