<itemizedlist>
<listitem>
- <para><varname>ct.dump [<dump_hint>]</varname> requests to dump the
+ <para><varname>dump [<dump_hint>]</varname> requests to dump the
profile data. </para>
</listitem>
<listitem>
- <para><varname>ct.zero</varname> requests to zero the profile data
+ <para><varname>zero</varname> requests to zero the profile data
counters. </para>
</listitem>
{
VG_(gdb_printf) ("\n");
VG_(gdb_printf) ("callgrind monitor commands:\n");
- VG_(gdb_printf) (" ct.dump [<dump_hint>]\n");
+ VG_(gdb_printf) (" dump [<dump_hint>]\n");
VG_(gdb_printf) (" dump counters\n");
- VG_(gdb_printf) (" ct.zero\n");
+ VG_(gdb_printf) (" zero\n");
VG_(gdb_printf) (" zero counters\n");
VG_(gdb_printf) ("\n");
}
VG_(strcpy) (s, req);
wcmd = VG_(strtok_r) (s, " ", &ssaveptr);
- switch (VG_(keyword_id) ("help ct.dump ct.zero",
+ switch (VG_(keyword_id) ("help dump zero",
wcmd, kwd_report_duplicated_matches)) {
case -2: /* multiple matches */
return True;
case 0: /* help */
print_monitor_help();
return True;
- case 1: { /* ct.dump */
+ case 1: { /* dump */
CLG_(dump_profile)(req, False);
return True;
}
- case 2: { /* ct.zero */
+ case 2: { /* zero */
CLG_(zero_all_cost)(False);
return True;
}
TODO and/or additional nice things to have
------------------------------------------
* many options can be changed on-line without problems.
- => would be nice to have a vg.option command that would evaluate
+ => would be nice to have a v.option command that would evaluate
its arguments like the startup options of m_main.c and tool clo processing.
-* have a mc.who_points_at <address> | <loss_record_nr>
+* have a memcheck monitor command
+ who_points_at <address> | <loss_record_nr>
that would describe the addresses where a pointer is found
to address (or address leaked at loss_record_nr>)
This would allow to interactively searching who is "keeping" a piece
* more client requests can be programmed in various tools. Currently,
there are only a few standard valgrind or memcheck client requests
implemented.
- vg.suppression [generate|add|delete] might be an interesting command:
+ v.suppression [generate|add|delete] might be an interesting command:
generate would output a suppression, add/delete would add a suppression
in memory for the last (or selected?) error.
- vg.break on fn calls/entry/exit + commands associated to it
+ v.break on fn calls/entry/exit + commands associated to it
(such as search leaks)?
Note that in case of ambiguous command, 1 is returned.
*sink_wanted_at_return is modified if one of the commands
- 'vg.set *_output' is handled.
+ 'v.set *_output' is handled.
*/
static
int handle_gdb_valgrind_command (char* mon, OutputSink* sink_wanted_at_return)
strcpy (s, mon);
wcmd = strtok_r (s, " ", &ssaveptr);
/* NB: if possible, avoid introducing a new command below which
- starts with the same 4 first letters as an already existing
+ starts with the same 3 first letters as an already existing
command. This ensures a shorter abbreviation for the user. */
- switch (VG_(keyword_id) ("help vg.set vg.info vg.wait vg.kill vg.translate",
+ switch (VG_(keyword_id) ("help v.set v.info v.wait v.kill v.translate",
wcmd, kwd_report_duplicated_matches)) {
case -2:
ret = 1;
VG_(gdb_printf) (
"general valgrind monitor commands:\n"
" help [debug] : monitor command help. With debug: + debugging commands\n"
-" vg.wait [<ms>] : sleep <ms> (default 0) then continue\n"
-" vg.info all_errors : show all errors found so far\n"
-" vg.info last_error : show last error found\n"
-" vg.info n_errs_found : show the nr of errors found so far\n"
-" vg.kill : kill the Valgrind process\n"
-" vg.set gdb_output : set valgrind output to gdb\n"
-" vg.set log_output : set valgrind output to log\n"
-" vg.set mixed_output : set valgrind output to log, interactive output to gdb\n"
-" vg.set vgdb-error <errornr> : debug me at error >= <errornr> \n");
+" 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.kill : kill the Valgrind process\n"
+" v.set gdb_output : set valgrind output to gdb\n"
+" v.set log_output : set valgrind output to log\n"
+" v.set mixed_output : set valgrind output to log, interactive output to gdb\n"
+" v.set vgdb-error <errornr> : debug me at error >= <errornr> \n");
if (int_value) { VG_(gdb_printf) (
"debugging valgrind internals monitor commands:\n"
-" vg.info gdbserver_status : show gdbserver status\n"
-" vg.info memory : show valgrind heap memory stats\n"
-" vg.set debuglog <level> : set valgrind debug log level to <level>\n"
-" vg.translate <addr> [<traceflags>] : debug translation of <addr> with <traceflags>\n"
+" v.info gdbserver_status : show gdbserver status\n"
+" v.info memory : show valgrind heap memory stats\n"
+" v.set debuglog <level> : set valgrind debug log level to <level>\n"
+" v.translate <addr> [<traceflags>] : debug translation of <addr> with <traceflags>\n"
" (default traceflags 0b00100000 : show after instrumentation)\n"
" An additional flag 0b100000000 allows to show gdbserver instrumentation\n");
}
break;
- case 1: /* vg.set */
+ case 1: /* v.set */
ret = 1;
wcmd = strtok_r (NULL, " ", &ssaveptr);
switch (kwdid = VG_(keyword_id)
vg_assert (0);
}
break;
- case 2: /* vg.info */ {
+ case 2: /* v.info */ {
ret = 1;
wcmd = strtok_r (NULL, " ", &ssaveptr);
switch (kwdid = VG_(keyword_id)
}
break;
}
- case 3: /* vg.wait */
+ case 3: /* v.wait */
wcmd = strtok_r (NULL, " ", &ssaveptr);
if (wcmd != NULL) {
int_value = strtol (wcmd, &endptr, 10);
VG_(gdb_printf) ("gdbserver: continuing after wait ...\n");
ret = 1;
break;
- case 4: /* vg.kill */
+ case 4: /* v.kill */
kill_request ("monitor command request to kill this process\n");
break;
- case 5: { /* vg.translate */
+ case 5: { /* v.translate */
Addr address;
SizeT verbosity = 0x20;
#include "pub_core_threadstate.h"
#include "pub_core_gdbserver.h"
+#include <limits.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
#undef PTRACEINVOKER
#endif
+// Outputs information for the user about ptrace_scope protection
+// or ptrace not working.
+static void ptrace_restrictions_msg(void);
+
static int debuglevel;
static struct timeval dbgtv;
/* if level <= debuglevel, print timestamp, then print provided by debug info */
Bool attach (int pid, char *msg)
{
long res;
+ static Bool output_error = True;
+ static Bool initial_attach = True;
+ // For a ptrace_scope protected system, we do not want to output
+ // repetitively attach error. We will output once an error
+ // for the initial_attach. Once the 1st attach has succeeded, we
+ // again show all errors.
DEBUG(1, "%s PTRACE_ATTACH pid %d\n", msg, pid);
res = ptrace (PTRACE_ATTACH, pid, NULL, NULL);
if (res != 0) {
- ERROR(errno, "%s PTRACE_ATTACH pid %d %ld\n", msg, pid, res);
+ if (output_error || debuglevel > 0) {
+ ERROR(errno, "%s PTRACE_ATTACH pid %d %ld\n", msg, pid, res);
+ if (initial_attach)
+ output_error = False;
+ }
return False;
}
+ initial_attach = False;
+ output_error = True;
return waitstopped(pid, SIGSTOP, msg);
}
static
Bool invoke_gdbserver (int pid)
{
+ static Bool ptrace_restrictions_msg_given = False;
long res;
Bool stopped;
struct user user_mod;
DEBUG(1, "attach to 'main' pid %d\n", pid);
if (!attach(pid, "attach main pid")) {
- ERROR(0, "error attach main pid %d\n", pid);
+ if (!ptrace_restrictions_msg_given) {
+ ptrace_restrictions_msg_given = True;
+ ERROR(0, "error attach main pid %d\n", pid);
+ ptrace_restrictions_msg();
+ }
return False;
}
(if PTRACE_INVOKER is defined) to ensure that the gdbserver code is
called soon by valgrind. */
static int max_invoke_ms = 100;
+#define NEVER 99999999
+static int cmd_time_out = NEVER;
static
void *invoke_gdbserver_in_valgrind(void *v_pid)
{
+ struct timeval cmd_max_end_time;
+ Bool cmd_started = False;
+ struct timeval invoke_time;
+
int pid = *(int *)v_pid;
int written_by_vgdb_before_sleep;
int seen_by_valgrind_before_sleep;
int invoked_written = -1;
+ unsigned int usecs;
pthread_cleanup_push(cleanup_restore_and_detach, v_pid);
"seen_by_valgrind_before_sleep %d\n",
written_by_vgdb_before_sleep,
seen_by_valgrind_before_sleep);
- if (usleep(1000 * max_invoke_ms) != 0) {
+ if (cmd_time_out != NEVER
+ && !cmd_started
+ && written_by_vgdb_before_sleep > seen_by_valgrind_before_sleep) {
+ /* A command was started. Record the time at which it was started. */
+ DEBUG(1, "IO for command started\n");
+ gettimeofday(&cmd_max_end_time, NULL);
+ cmd_max_end_time.tv_sec += cmd_time_out;
+ cmd_started = True;
+ }
+ if (max_invoke_ms > 0) {
+ usecs = 1000 * max_invoke_ms;
+ gettimeofday(&invoke_time, NULL);
+ invoke_time.tv_sec += max_invoke_ms / 1000;
+ invoke_time.tv_usec += 1000 * (max_invoke_ms % 1000);
+ invoke_time.tv_sec += invoke_time.tv_usec / (1000 * 1000);
+ invoke_time.tv_usec = invoke_time.tv_usec % (1000 * 1000);
+ } else {
+ usecs = 0;
+ }
+ if (cmd_started) {
+ // 0 usecs here means the thread just has to check gdbserver eats
+ // the characters in <= cmd_time_out seconds.
+ // We will just wait by 1 second max at a time.
+ if (usecs == 0 || usecs > 1000 * 1000)
+ usecs = 1000 * 1000;
+ }
+ if (usleep(usecs) != 0) {
if (errno == EINTR)
continue;
XERROR (errno, "error usleep\n");
}
- /* if nothing happened during our sleep, let's try to wake up valgrind */
+ /* If nothing happened during our sleep, let's try to wake up valgrind
+ or check for cmd time out. */
if (written_by_vgdb_before_sleep == VS_written_by_vgdb
&& seen_by_valgrind_before_sleep == VS_seen_by_valgrind
&& VS_written_by_vgdb > VS_seen_by_valgrind) {
+ struct timeval now;
+ gettimeofday(&now, NULL);
DEBUG(2,
"after sleep "
"written_by_vgdb %d "
XERROR (errno,
"invoke_gdbserver_in_valgrind: "
"check for pid %d existence failed\n", pid);
-
- #if defined(PTRACEINVOKER)
- /* only need to wake up if the nr written has changed since
- last invoke. */
- if (invoked_written != written_by_vgdb_before_sleep) {
- if (invoke_gdbserver(pid)) {
- /* If invoke succesful, no need to invoke again
- for the same value of written_by_vgdb_before_sleep. */
- invoked_written = written_by_vgdb_before_sleep;
+ if (cmd_started) {
+ if (timercmp (&now, &cmd_max_end_time, >))
+ XERROR (0,
+ "pid %d did not handle a command in %d seconds\n",
+ pid, cmd_time_out);
+ }
+ if (max_invoke_ms > 0 && timercmp (&now, &invoke_time, >=)) {
+ #if defined(PTRACEINVOKER)
+ /* only need to wake up if the nr written has changed since
+ last invoke. */
+ if (invoked_written != written_by_vgdb_before_sleep) {
+ if (invoke_gdbserver(pid)) {
+ /* If invoke succesful, no need to invoke again
+ for the same value of written_by_vgdb_before_sleep. */
+ invoked_written = written_by_vgdb_before_sleep;
+ }
}
+ #else
+ DEBUG(2, "invoke_gdbserver via ptrace not (yet) implemented\n");
+ #endif
+ }
+ } else {
+ // Something happened => restart timer check.
+ if (cmd_time_out != NEVER) {
+ DEBUG(2, "some IO was done => restart command\n");
+ cmd_started = False;
}
- #else
- DEBUG(2, "invoke_gdbserver via ptrace not (yet) implemented\n");
- #endif
}
}
pthread_cleanup_pop(0);
in the valgrind process can stay stopped if vgdb main
exits before the invoke thread had time to detach from
all valgrind threads. */
- if (max_invoke_ms > 0) {
+ if (max_invoke_ms > 0 || cmd_time_out != NEVER) {
int join;
/* It is surprisingly complex to properly shutdown or exit the
int nc;
- if (max_invoke_ms > 0)
+ if (max_invoke_ms > 0 || cmd_time_out != NEVER)
pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
invoke_gdbserver_in_valgrind, (void *) &pid);
/* report to user the existence of a vgdb-able valgrind process
with given pid */
static
-void report_pid (int pid)
+void report_pid (int pid, Bool on_stdout)
{
char cmdline_file[100];
char cmdline[1000];
cmdline[sz] = 0;
close (fd);
}
- fprintf(stderr, "use --pid=%d for %s\n", pid, cmdline);
- fflush(stderr);
+ fprintf((on_stdout ? stdout : stderr), "use --pid=%d for %s\n", pid, cmdline);
+ fflush((on_stdout ? stdout : stderr));
}
-/* Eventually produces additional usage information documenting the
+/* Possibly produces additional usage information documenting the
ptrace restrictions. */
static
-void ptrace_restrictions(void)
+void ptrace_restrictions_msg(void)
{
# ifdef PR_SET_PTRACER
char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope";
" Only OPTION(s) can be given.\n"
"\n"
" OPTIONS are [--pid=<number>] [--vgdb-prefix=<prefix>]\n"
-" [--max-invoke-ms=<number>] [--wait=<number>] [-d] [-D] [-l]\n"
+" [--wait=<number>] [--max-invoke-ms=<number>]\n"
+" [--cmd-time-out=<number>] [-l] [-D] [-d]\n"
+" \n"
" --pid arg must be given if multiple Valgrind gdbservers are found.\n"
" --vgdb-prefix arg must be given to both Valgrind and vgdb utility\n"
" if you want to change the default prefix for the FIFOs communication\n"
" between the Valgrind gdbserver and vgdb.\n"
-" --wait arg tells vgdb to check during the specified number\n"
+" --wait (default 0) tells vgdb to check during the specified number\n"
" of seconds if a Valgrind gdbserver can be found.\n"
-" --max-invoke-ms gives the nr of milli-seconds after which vgdb will force\n"
-" the invocation of the Valgrind gdbserver (if the Valgrind process\n"
-" is blocked in a system call).\n"
-" -d arg tells to show debug info. Multiple -d args for more debug info\n"
-" -D arg tells to show shared mem status and then exit.\n"
+" --max-invoke-ms (default 100) gives the nr of milli-seconds after which vgdb\n"
+" will force the invocation of the Valgrind gdbserver (if the Valgrind\n"
+" process is blocked in a system call).\n"
+" --cmd-time-out (default 99999999) tells vgdb to exit if the found Valgrind\n"
+" gdbserver has not processed a command after number seconds\n"
" -l arg tells to show the list of running Valgrind gdbserver and then exit.\n"
+" -D arg tells to show shared mem status and then exit.\n"
+" -d arg tells to show debug info. Multiple -d args for more debug info\n"
"\n"
" -h --help shows this message\n"
" To get help from the Valgrind gdbserver, use vgdb help\n"
"\n"
);
- ptrace_restrictions();
+ ptrace_restrictions_msg();
}
-/* If show_list, shows the list of Valgrind processes with gdbserver activated.
+/* If show_list, outputs on stdout the list of Valgrind processes with gdbserver activated.
and then exits.
else if arg_pid == -1, waits maximum check_trials seconds to discover
&& kill (newpid, 0) == 0) {
nr_valid_pid++;
if (show_list) {
- report_pid (newpid);
+ report_pid (newpid, /*on_stdout*/ True);
pid = newpid;
} else if (arg_pid != -1) {
if (arg_pid == newpid) {
(stderr,
"no --pid= arg given"
" and multiple valgrind pids found:\n");
- report_pid (pid);
+ report_pid (pid, /*on_stdout*/ False);
}
pid = -2;
- report_pid (newpid);
+ report_pid (newpid, /*on_stdout*/ False);
} else {
pid = newpid;
}
{
const char *eq_pos = strchr(arg, '=');
char *wrong;
+ long long int long_value;
if (eq_pos == NULL)
return False;
- *value = strtol(eq_pos+1, &wrong, 10);
+ long_value = strtoll(eq_pos+1, &wrong, 10);
+ if (long_value < 0 || long_value > INT_MAX)
+ return False;
if (*wrong)
return False;
+ *value = (int) long_value;
return True;
}
} else if (is_opt(argv[i], "--pid=")) {
int newpid;
if (!numeric_val(argv[i], &newpid)) {
- fprintf (stderr, "invalid pid argument %s\n", argv[i]);
+ fprintf (stderr, "invalid --pid argument %s\n", argv[i]);
arg_errors++;
} else if (arg_pid != -1) {
- fprintf (stderr, "multiple pid arguments given\n");
+ fprintf (stderr, "multiple --pid arguments given\n");
arg_errors++;
} else {
arg_pid = newpid;
}
} else if (is_opt(argv[i], "--wait=")) {
if (!numeric_val(argv[i], &check_trials)) {
- fprintf (stderr, "invalid wait argument %s\n", argv[i]);
+ fprintf (stderr, "invalid --wait argument %s\n", argv[i]);
arg_errors++;
}
} else if (is_opt(argv[i], "--max-invoke-ms=")) {
if (!numeric_val(argv[i], &max_invoke_ms)) {
- fprintf (stderr, "invalid max-invoke-ms argument %s\n", argv[i]);
+ fprintf (stderr, "invalid --max-invoke-ms argument %s\n", argv[i]);
+ arg_errors++;
+ }
+ } else if (is_opt(argv[i], "--cmd-time-out=")) {
+ if (!numeric_val(argv[i], &cmd_time_out)) {
+ fprintf (stderr, "invalid --cmd-time-out argument %s\n", argv[i]);
arg_errors++;
}
} else if (is_opt(argv[i], "--vgdb-prefix=")) {
"Can't use both -D and -l options\n");
}
+ if (max_invoke_ms > 0
+ && cmd_time_out != NEVER
+ && (cmd_time_out * 1000) <= max_invoke_ms) {
+ arg_errors++;
+ fprintf (stderr,
+ "--max-invoke-ms must be < --cmd-time-out * 1000\n");
+ }
+
if (show_list && arg_pid != -1) {
arg_errors++;
fprintf (stderr,
<para>Each tool can also provide tool-specific monitor commands.
An example of a tool specific monitor command is the Memcheck monitor
-command <computeroutput>mc.leak_check full
+command <computeroutput>leak_check full
reachable any</computeroutput>. This requests a full reporting of the
allocated memory blocks. To have this leak check executed, use the GDB
command:
<screen><![CDATA[
-(gdb) monitor mc.leak_check full reachable any
+(gdb) monitor leak_check full reachable any
]]></screen>
</para>
-<para>GDB will send the <computeroutput>mc.leak_check</computeroutput>
+<para>GDB will send the <computeroutput>leak_check</computeroutput>
command to the Valgrind gdbserver. The Valgrind gdbserver will
execute the monitor command itself, if it recognises it to be a Valgrind core
monitor command. If it is not recognised as such, it is assumed to
be tool-specific and is handed to the tool for execution. For example:
</para>
<programlisting><![CDATA[
-(gdb) monitor mc.leak_check full reachable any
+(gdb) monitor leak_check full reachable any
==2418== 100 bytes in 1 blocks are still reachable in loss record 1 of 1
==2418== at 0x4006E9E: malloc (vg_replace_malloc.c:236)
==2418== by 0x804884F: main (prog.c:88)
<para>As with other GDB commands, the Valgrind gdbserver will accept
abbreviated monitor command names and arguments, as long as the given
abbreviation is unambiguous. For example, the above
-<computeroutput>mc.leak_check</computeroutput>
+<computeroutput>leak_check</computeroutput>
command can also be typed as:
<screen><![CDATA[
-(gdb) mo mc.l f r a
+(gdb) mo l f r a
]]></screen>
The letters <computeroutput>mo</computeroutput> are recognised by GDB as being
an abbreviation for <computeroutput>monitor</computeroutput>. So GDB sends the
-string <computeroutput>mc.l f r a</computeroutput> to the Valgrind
+string <computeroutput>l f r a</computeroutput> to the Valgrind
gdbserver. The letters provided in this string are unambiguous for the
Valgrind gdbserver. This therefore gives the same output as the
unabbreviated command and arguments. If the provided abbreviation is
ambiguous, the Valgrind gdbserver will report the list of commands (or
argument values) that can match:
<programlisting><![CDATA[
-(gdb) mo mc. a r f
-mc. can match mc.get_vbits mc.leak_check mc.make_memory mc.check_memory
+(gdb) mo v. n
+v. can match v.set v.info v.wait v.kill v.translate
+(gdb) mo v.i n
+n_errs_found 0 (vgdb-error 0)
(gdb)
]]></programlisting>
</para>
lines, when given in a shell, will cause the same leak search to be executed
by the process 3145:
<screen><![CDATA[
-vgdb --pid=3145 mc.leak_check any full reachable
-vgdb --pid=3145 mc.l f r a
+vgdb --pid=3145 leak_check any full reachable
+vgdb --pid=3145 l f r a
]]></screen></para>
<para>Note that the Valgrind gdbserver automatically continues the
Whilst an inferior call is running, the Valgrind tool will report
errors as usual. If you do not want to have such errors stop the
execution of the inferior call, you can
- use <computeroutput>vg.set vgdb-error</computeroutput> to set a
+ use <computeroutput>v.set vgdb-error</computeroutput> to set a
big value before the call, then manually reset it to its original
value when the call is complete.</para>
gdbserver and vgdb. </para>
</listitem>
+ <listitem>
+ <para><option>--wait=<number></option> instructs vgdb to
+ search for available Valgrind gdbservers for the specified number
+ of seconds. This makes it possible start a vgdb process
+ before starting the Valgrind gdbserver with which you intend the
+ vgdb to communicate. This option is useful when used in
+ conjunction with a <option>--vgdb-prefix</option> that is
+ unique to the process you want to wait for.
+ Also, if you use the <option>--wait</option> argument in the GDB
+ "target remote" command, you must set the GDB remotetimeout to a
+ value bigger than the --wait argument value. See option
+ <option>--max-invoke-ms</option> (just below)
+ for an example of setting the remotetimeout value.</para>
+ </listitem>
+
<listitem>
<para><option>--max-invoke-ms=<number></option> gives the
number of milliseconds after which vgdb will force the invocation
- of gdbserver embedded in valgrind. The default value is 100
- milliseconds. A value of 0 disables forced invocation.
+ of gdbserver embedded in Valgrind. The default value is 100
+ milliseconds. A value of 0 disables forced invocation. The forced
+ invocation is used when vgdb is connected to a Valgrind gdbserver,
+ and the Valgrind process has all its threads blocked in a system
+ call.
</para>
<para>If you specify a large value, you might need to increase the
]]></screen>
</para>
</listitem>
-
+
<listitem>
- <para><option>--wait=<number></option> instructs vgdb to
- search for available Valgrind gdbservers for the specified number
- of seconds. This makes it possible start a vgdb process
- before starting the Valgrind gdbserver with which you intend the
- vgdb to communicate. This option is useful when used in
- conjunction with a <option>--vgdb-prefix</option> that is
- unique to the process you want to wait for.
- Also, if you use the <option>--wait</option> argument in the GDB
- "target remote" command, you must set the GDB remotetimeout to a
- value bigger than the --wait argument value. See option
- <option>--max-invoke-ms</option> (just above)
- for an example of setting the remotetimeout value.</para>
+ <para><option>--cmd-time-out=<number></option> instructs a
+ standalone vgdb to exit if the Valgrind gdbserver it is connected
+ to does not process a command in the specified number of seconds.
+ The default value is to never time out.</para>
</listitem>
+
<listitem>
- <para><option>-c</option> To give more than one command, separate
- the commands by an option <option>-c</option>. Example:
+ <para><option>-c</option> To give more than one command to a
+ standalone vgdb, separate the commands by an
+ option <option>-c</option>. Example:
<screen><![CDATA[
-vgdb vg.set log_output -c mc.leak_check any
+vgdb v.set log_output -c leak_check any
]]></screen></para>
</listitem>
<listitem>
- <para><option>-d</option> instructs vgdb to produce debugging
- output. Give multiple <option>-d</option> args to increase the
- verbosity.</para>
+ <para><option>-l</option> instructs a standalone vgdb to report
+ the list of the Valgrind gdbserver processes running and then
+ exit.</para>
</listitem>
-
+
<listitem>
- <para><option>-D</option> instructs vgdb to show the state of the
- shared memory used by the Valgrind gdbserver. vgdb will exit after
- having shown the Valgrind gdbserver shared memory state.</para>
+ <para><option>-D</option> instructs a standalone vgdb to show the
+ state of the shared memory used by the Valgrind gdbserver. vgdb
+ will exit after having shown the Valgrind gdbserver shared memory
+ state.</para>
</listitem>
<listitem>
- <para><option>-l</option> instructs vgdb to report the list of
- the Valgrind gdbserver processes running and then exit.</para>
+ <para><option>-d</option> instructs vgdb to produce debugging
+ output. Give multiple <option>-d</option> args to increase the
+ verbosity. When giving <option>-d</option> to a relay vgdb, you better
+ redirect the standard error (stderr) of vgdb to a file to avoid
+ interaction between GDB and vgdb debugging output.</para>
</listitem>
+
</itemizedlist>
</sect2>
</listitem>
<listitem>
- <para><varname>vg.info all_errors</varname> shows all errors found
+ <para><varname>v.info all_errors</varname> shows all errors found
so far.</para>
</listitem>
<listitem>
- <para><varname>vg.info last_error</varname> shows the last error
+ <para><varname>v.info last_error</varname> shows the last error
found.</para>
</listitem>
<listitem>
- <para><varname>vg.info n_errs_found</varname> shows the number of
+ <para><varname>v.info n_errs_found</varname> shows the number of
errors found so far and the current value of the
<option>--vgdb-error</option>
argument.</para>
</listitem>
<listitem>
- <para><varname>vg.set {gdb_output | log_output |
+ <para><varname>v.set {gdb_output | log_output |
mixed_output}</varname> allows redirection of the Valgrind output
(e.g. the errors detected by the tool). The default setting is
<computeroutput>mixed_output</computeroutput>.</para>
<para>With <computeroutput>mixed_output</computeroutput>, the
Valgrind output goes to the Valgrind log (typically stderr) while
the output of the interactive GDB monitor commands (e.g.
- <computeroutput>vg.info last_error</computeroutput>)
+ <computeroutput>v.info last_error</computeroutput>)
is displayed by GDB.</para>
<para>With <computeroutput>gdb_output</computeroutput>, both the
</listitem>
<listitem>
- <para><varname>vg.wait [ms (default 0)]</varname> instructs
+ <para><varname>v.wait [ms (default 0)]</varname> instructs
Valgrind gdbserver to sleep "ms" milli-seconds and then
continue. When sent from a standalone vgdb, if this is the last
command, the Valgrind process will continue the execution of the
</listitem>
<listitem>
- <para><varname>vg.kill</varname> requests the gdbserver to kill
+ <para><varname>v.kill</varname> requests the gdbserver to kill
the process. This can be used from a standalone vgdb to properly
kill a Valgrind process which is currently expecting a vgdb
connection.</para>
</listitem>
<listitem>
- <para><varname>vg.set vgdb-error <errornr></varname>
+ <para><varname>v.set vgdb-error <errornr></varname>
dynamically changes the value of the
<option>--vgdb-error</option> argument. A
typical usage of this is to start with
<itemizedlist>
<listitem>
- <para><varname>vg.info gdbserver_status</varname> shows the
+ <para><varname>v.info gdbserver_status</varname> shows the
gdbserver status. In case of problems (e.g. of communications),
this showns the values of some relevant Valgrind gdbserver internal
variables. Note that the variables related to breakpoints and
</listitem>
<listitem>
- <para><varname>vg.info memory</varname> shows the statistics of
+ <para><varname>v.info memory</varname> shows the statistics of
Valgrind's internal heap management. If
option <option>--profile-heap=yes</option> was given, detailed
statistics will be output.
</listitem>
<listitem>
- <para><varname>vg.set debuglog <intvalue></varname> sets the
+ <para><varname>v.set debuglog <intvalue></varname> sets the
Valgrind debug log level to <intvalue>. This allows to
dynamically change the log level of Valgrind e.g. when a problem
is detected.</para>
</listitem>
<listitem>
- <para><varname>vg.translate <address>
+ <para><varname>v.translate <address>
[<traceflags>]</varname> shows the translation of the block
containing <computeroutput>address</computeroutput> with the given
trace flags. The <computeroutput>traceflags</computeroutput> value
mcleak.stdinB.gdb \
mcleak.stdoutB.exp \
mcleak.vgtest \
+ mcmain_pic.stderrB.exp \
+ mcmain_pic.stderr.exp \
+ mcmain_pic.stdinB.gdb \
+ mcmain_pic.stdoutB.exp \
+ mcmain_pic.stdout.exp \
mcmain_pic.vgtest \
mcmain_pic.stderrB.exp \
mcmain_pic.stderr.exp \
Validate monitor commands abbreviation recognition
***************************************************
-mo vg.info all_errors # to show all errors recorded so far
-mo vg.i a # the same
-mo v # must give an error: v can match vg.set vg.info
-mo vg # the same vg
-mo vg. # the same vg.
+mo v.info all_errors # to show all errors recorded so far
+mo v.i a # the same
+mo v # must give an error: v can match v.set v.info
+mo v # the same v
+mo v. # the same v.
test of gdb detaching or dying
******************************
gdb ./t
set remotetimeout 100
target remote|vgdb
-detach valgrind continues
+detach valgrind continues
target remote|vgdb reattach
-detach valgrind continues
+detach valgrind continues
target remote|vgdb reattach
-monitor vg.wait no effect
+monitor v.wait no effect
gdb ./t
set remotetimeout 1000
target remote | vgdb
-mo vg.set vgdb-error 1000 # so that valgrind does stop only at error 1000 and after
-mo vg.set gdb_output # to have further valgrind errors output in gdb
+mo v.set vgdb-error 1000 # so that valgrind does stop only at error 1000 and after
+mo v.set gdb_output # to have further valgrind errors output in gdb
c # continue, some errors will appear
C-c # interrupt program
-mo vg.set log_output # to set back the valgrind output to normal process log output
-mo mc.l # leak output to appear in log of process
-mo vg.set mixed_output
-mo mc.l # leak output to appear in gdb
+mo v.set log_output # to set back the valgrind output to normal process log output
+mo l # leak output to appear in log of process
+mo v.set mixed_output
+mo l # leak output to appear in gdb
In another window, do:
while true
do
- vgdb mc.leak
+ vgdb leak
sleep 1
done
# The first argument is the nr of times vgdb has to be called.
# rest of args are given to vgdb
# At the end of the loop, an additional call is done
-# but adding " -c vg.kill" to kill Valgrind process.
+# but adding " -c v.kill" to kill Valgrind process.
LOOPS=$1
shift
i=`expr $i + 1`
done
-./vgdb "$@" -c vg.kill
+./vgdb "$@" -c v.kill
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcbreak
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
define checkstep
set $old_pc=$pc
checkstep
checkstep
#
-monitor vg.set vgdb-error 0
+monitor v.set vgdb-error 0
#
next
print whoami("first")
# delete all breaks
delete
continue
-monitor vg.info n_errs_found
+monitor v.info n_errs_found
# inferior call "in the middle" of an instruction is not working at least
# on all platforms, so comment the below.
# print whoami("after error: inferior call pushed from mcbreak.stdinB.gdb")
checkstep
-monitor vg.set vgdb-error 0
+monitor v.set vgdb-error 0
continue
# stop the process a.o. to avoid non deterministic output
-monitor vg.kill
+monitor v.kill
quit
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcclean_after_fork
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
# put a break in main, and then a watch
# also put breaks in code that only the child will execute.
#
# we should now have encountered the read watchpoint in the parent.
# let's kill the parent:
-monitor vg.kill
+monitor v.kill
quit
sending command help to pid ....
sending command help debug to pid ....
-sending command vg.kill to pid ....
+sending command v.kill to pid ....
readchar: Got EOF
error reading packet
general valgrind monitor commands:
help [debug] : monitor command help. With debug: + debugging commands
- vg.wait [<ms>] : sleep <ms> (default 0) then continue
- vg.info all_errors : show all errors found so far
- vg.info last_error : show last error found
- vg.info n_errs_found : show the nr of errors found so far
- vg.kill : kill the Valgrind process
- vg.set gdb_output : set valgrind output to gdb
- vg.set log_output : set valgrind output to log
- vg.set mixed_output : set valgrind output to log, interactive output to gdb
- vg.set vgdb-error <errornr> : debug me at error >= <errornr>
+ v.wait [<ms>] : sleep <ms> (default 0) then continue
+ v.info all_errors : show all errors found so far
+ v.info last_error : show last error found
+ v.info n_errs_found : show the nr of errors found so far
+ v.kill : kill the Valgrind process
+ v.set gdb_output : set valgrind output to gdb
+ v.set log_output : set valgrind output to log
+ v.set mixed_output : set valgrind output to log, interactive output to gdb
+ v.set vgdb-error <errornr> : debug me at error >= <errornr>
memcheck monitor commands:
- mc.get_vbits <addr> [<len>]
+ get_vbits <addr> [<len>]
returns validity bits for <len> (or 1) bytes at <addr>
bit values 0 = valid, 1 = invalid, __ = unaddressable byte
- Example: mc.get_vbits 0x........ 10
- mc.make_memory [noaccess|undefined
- |defined|ifaddressabledefined] <addr> [<len>]
+ Example: get_vbits 0x........ 10
+ make_memory [noaccess|undefined
+ |defined|Definedifaddressable] <addr> [<len>]
mark <len> (or 1) bytes at <addr> with the given accessibility
- mc.check_memory [addressable|defined] <addr> [<len>]
+ check_memory [addressable|defined] <addr> [<len>]
check that <len> (or 1) bytes at <addr> have the given accessibility
and outputs a description of <addr>
- mc.leak_check [full*|summary] [reachable|leakpossible*|definiteleak]
+ leak_check [full*|summary] [reachable|possibleleak*|definiteleak]
[increased*|changed|any]
* = defaults
- Examples: mc.leak_check
- mc.leak_check summary any
+ Examples: leak_check
+ leak_check summary any
general valgrind monitor commands:
help [debug] : monitor command help. With debug: + debugging commands
- vg.wait [<ms>] : sleep <ms> (default 0) then continue
- vg.info all_errors : show all errors found so far
- vg.info last_error : show last error found
- vg.info n_errs_found : show the nr of errors found so far
- vg.kill : kill the Valgrind process
- vg.set gdb_output : set valgrind output to gdb
- vg.set log_output : set valgrind output to log
- vg.set mixed_output : set valgrind output to log, interactive output to gdb
- vg.set vgdb-error <errornr> : debug me at error >= <errornr>
+ v.wait [<ms>] : sleep <ms> (default 0) then continue
+ v.info all_errors : show all errors found so far
+ v.info last_error : show last error found
+ v.info n_errs_found : show the nr of errors found so far
+ v.kill : kill the Valgrind process
+ v.set gdb_output : set valgrind output to gdb
+ v.set log_output : set valgrind output to log
+ v.set mixed_output : set valgrind output to log, interactive output to gdb
+ v.set vgdb-error <errornr> : debug me at error >= <errornr>
debugging valgrind internals monitor commands:
- vg.info gdbserver_status : show gdbserver status
- vg.info memory : show valgrind heap memory stats
- vg.set debuglog <level> : set valgrind debug log level to <level>
- vg.translate <addr> [<traceflags>] : debug translation of <addr> with <traceflags>
+ v.info gdbserver_status : show gdbserver status
+ v.info memory : show valgrind heap memory stats
+ v.set debuglog <level> : set valgrind debug log level to <level>
+ v.translate <addr> [<traceflags>] : debug translation of <addr> with <traceflags>
(default traceflags 0b00100000 : show after instrumentation)
An additional flag 0b100000000 allows to show gdbserver instrumentation
memcheck monitor commands:
- mc.get_vbits <addr> [<len>]
+ get_vbits <addr> [<len>]
returns validity bits for <len> (or 1) bytes at <addr>
bit values 0 = valid, 1 = invalid, __ = unaddressable byte
- Example: mc.get_vbits 0x........ 10
- mc.make_memory [noaccess|undefined
- |defined|ifaddressabledefined] <addr> [<len>]
+ Example: get_vbits 0x........ 10
+ make_memory [noaccess|undefined
+ |defined|Definedifaddressable] <addr> [<len>]
mark <len> (or 1) bytes at <addr> with the given accessibility
- mc.check_memory [addressable|defined] <addr> [<len>]
+ check_memory [addressable|defined] <addr> [<len>]
check that <len> (or 1) bytes at <addr> have the given accessibility
and outputs a description of <addr>
- mc.leak_check [full*|summary] [reachable|leakpossible*|definiteleak]
+ leak_check [full*|summary] [reachable|possibleleak*|definiteleak]
[increased*|changed|any]
* = defaults
- Examples: mc.leak_check
- mc.leak_check summary any
+ Examples: leak_check
+ leak_check summary any
monitor command request to kill this process
stdout_filter: filter_make_empty
stderr_filter: filter_make_empty
progB: vgdb
-argsB: --wait=60 --vgdb-prefix=./vgdb-prefix-mchelp -c help -c help debug -c vg.kill
+argsB: --wait=60 --vgdb-prefix=./vgdb-prefix-mchelp -c help -c help debug -c v.kill
stdoutB_filter: filter_memcheck_monitor
stderrB_filter: filter_vgdb
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcinfcallRU
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
# We will interrupt in a few seconds (be sure the main task is ready).
# Once it is ready, we still have to wait to be sure it is running.
# before they have a chance to execute the whoami
# thread apply all
print whoami("inferior call pushed from gdb in mcinfcallRU.stdinB.gdb")
-monitor vg.kill
+monitor v.kill
quit
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcinfcallWSRU
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
# ensure all threads are known
break sleeper_or_burner
print whoami("thread 3 inferior call pushed from gdb in mcinfcallWSRU.stdinB.gdb")
thread 4
print whoami("thread 4 inferior call pushed from gdb in mcinfcallWSRU.stdinB.gdb")
-monitor vg.kill
+monitor v.kill
quit
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.kill to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.kill to pid ....
readchar: Got EOF
error reading packet
stderr_filter: filter_make_empty
# as the Valgrind process is always busy, we do not need the vgdb.ptraceinvoker prereq.
progB: invoker
-argsB: 10 --vgdb-prefix=./vgdb-prefix-mcinvokeRU --wait=60 -c vg.wait 0
+argsB: 10 --vgdb-prefix=./vgdb-prefix-mcinvokeRU --wait=60 -c v.wait 0
# if the --wait is not enough, the test will fail or block.
stdoutB_filter: filter_memcheck_monitor
stderrB_filter: filter_vgdb
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.wait 0 to pid ....
-sending command vg.kill to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.wait 0 to pid ....
+sending command v.kill to pid ....
readchar: Got EOF
error reading packet
stderr_filter: filter_make_empty
prereq: test -f vgdb.ptraceinvoker
progB: invoker
-argsB: 10 --vgdb-prefix=./vgdb-prefix-mcinvokeWS --wait=60 -c vg.wait 0
+argsB: 10 --vgdb-prefix=./vgdb-prefix-mcinvokeWS --wait=60 -c v.wait 0
# if the --wait is not enough, the test will fail or block
stdoutB_filter: filter_memcheck_monitor
stderrB_filter: filter_vgdb
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcleak
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
#
# insert break:
#
# fprintf(stderr, "expecting details 10 bytes reachable\n"); fflush(stderr); breakme();
up
-monitor mc.leak_check full reachable any
+monitor leak_check full reachable any
continue
# VALGRIND_DO_LEAK_CHECK;
#
# fprintf(stderr, "expecting to have NO details\n"); fflush(stderr);
up
-monitor mc.leak_check full reachable increased
+monitor leak_check full reachable increased
continue
# VALGRIND_DO_ADDED_LEAK_CHECK;
#
# b21 = malloc (21);
# fprintf(stderr, "expecting details +10 bytes lost, +21 bytes reachable\n"); fflush(stderr); breakme();
up
-monitor mc.leak_check full reachable increased
+monitor leak_check full reachable increased
continue
# VALGRIND_DO_ADDED_LEAK_CHECK;
#
# b32_33[i] = malloc (32+i);
# fprintf(stderr, "expecting details +65 bytes reachable\n"); fflush(stderr); breakme();
up
-monitor mc.leak_check full reachable increased
+monitor leak_check full reachable increased
continue
# VALGRIND_DO_ADDED_LEAK_CHECK;
#
# fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme();
up
-monitor mc.leak_check full reachable increased
+monitor leak_check full reachable increased
continue
# VALGRIND_DO_ADDED_LEAK_CHECK;
#
# b10++;
# fprintf(stderr, "expecting details +10 bytes reachable\n"); fflush(stderr); breakme();
up
-monitor mc.leak_check full reachable increased
+monitor leak_check full reachable increased
continue
# VALGRIND_DO_ADDED_LEAK_CHECK;
#
# b10--;
# fprintf(stderr, "expecting details -10 bytes reachable, +10 bytes lost\n"); fflush(stderr); breakme();
up
-monitor mc.leak_check full reachable changed
+monitor leak_check full reachable changed
continue
# VALGRIND_DO_CHANGED_LEAK_CHECK;
#
# b10++;
# fprintf(stderr, "expecting details -10 bytes lost, +10 bytes reachable\n"); fflush(stderr); breakme();
up
-monitor mc.leak_check full reachable changed
+monitor leak_check full reachable changed
continue
# VALGRIND_DO_CHANGED_LEAK_CHECK;
#
# b32_33[0]--;
# fprintf(stderr, "expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable\n"); fflush(stderr); breakme();
up
-monitor mc.leak_check full reachable changed
+monitor leak_check full reachable changed
continue
# VALGRIND_DO_CHANGED_LEAK_CHECK;
#
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcmain_pic
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
# break
break main
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcsignopass
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
# instruct gdb to not pass (i.e. ignore) these signals.
#
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcsigpass
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
# After this continue, we will receive 5 signals.
continue
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcvabits
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
#
# insert break:
set $0xundefined = &undefined
#
# Verif A-bits, V-bits, Get V-bits: A,V,G [0..9]
-eval "monitor mc.check_memory addressable 0x%x 10", $0xundefined
-eval "monitor mc.check_memory defined 0x%x 10", $0xundefined
-eval "monitor mc.get_vbits 0x%x 10", $0xundefined
+eval "monitor check_memory addressable 0x%x 10", $0xundefined
+eval "monitor check_memory defined 0x%x 10", $0xundefined
+eval "monitor get_vbits 0x%x 10", $0xundefined
#
# continue till //2break:
continue
#
# A,V,G [0..9] after the undefinition of some bytes by executable:
-eval "monitor mc.check_memory addressable 0x%x 10", $0xundefined
-eval "monitor mc.check_memory defined 0x%x 10", $0xundefined
-eval "monitor mc.get_vbits 0x%x 10", $0xundefined
+eval "monitor check_memory addressable 0x%x 10", $0xundefined
+eval "monitor check_memory defined 0x%x 10", $0xundefined
+eval "monitor get_vbits 0x%x 10", $0xundefined
#
# Redefine [2..4]
set $0xundefined_2 = (char*)$0xundefined + 2
-eval "monitor mc.make_memory defined 0x%x 3", $0xundefined_2
+eval "monitor make_memory defined 0x%x 3", $0xundefined_2
# A,V,G
-eval "monitor mc.check_memory addressable 0x%x 10", $0xundefined
-eval "monitor mc.check_memory defined 0x%x 10", $0xundefined
-eval "monitor mc.get_vbits 0x%x 10", $0xundefined
+eval "monitor check_memory addressable 0x%x 10", $0xundefined
+eval "monitor check_memory defined 0x%x 10", $0xundefined
+eval "monitor get_vbits 0x%x 10", $0xundefined
#
# Undefine [2..5]
-eval "monitor mc.make_memory undefined 0x%x 4", $0xundefined_2
+eval "monitor make_memory undefined 0x%x 4", $0xundefined_2
# A,V,G [0..9]
-eval "monitor mc.check_memory addressable 0x%x 10", $0xundefined
-eval "monitor mc.check_memory defined 0x%x 10", $0xundefined
-eval "monitor mc.get_vbits 0x%x 10", $0xundefined
+eval "monitor check_memory addressable 0x%x 10", $0xundefined
+eval "monitor check_memory defined 0x%x 10", $0xundefined
+eval "monitor get_vbits 0x%x 10", $0xundefined
#
# noaccess [2..3]
-eval "monitor mc.make_memory noaccess 0x%x 2", $0xundefined_2
+eval "monitor make_memory noaccess 0x%x 2", $0xundefined_2
# A,V,G [0..1]
-eval "monitor mc.check_memory addressable 0x%x 2", $0xundefined
-eval "monitor mc.check_memory defined 0x%x 2", $0xundefined
-eval "monitor mc.get_vbits 0x%x 2", $0xundefined
+eval "monitor check_memory addressable 0x%x 2", $0xundefined
+eval "monitor check_memory defined 0x%x 2", $0xundefined
+eval "monitor get_vbits 0x%x 2", $0xundefined
# A,V,G [2..3]
-eval "monitor mc.check_memory addressable 0x%x 2", $0xundefined_2
-eval "monitor mc.check_memory defined 0x%x 2", $0xundefined_2
-eval "monitor mc.get_vbits 0x%x 2", $0xundefined_2
+eval "monitor check_memory addressable 0x%x 2", $0xundefined_2
+eval "monitor check_memory defined 0x%x 2", $0xundefined_2
+eval "monitor get_vbits 0x%x 2", $0xundefined_2
# A,V,G [4..9]
set $0xundefined_4 = (char*) $0xundefined_2 + 2
-eval "monitor mc.check_memory addressable 0x%x 6", $0xundefined_4
-eval "monitor mc.check_memory defined 0x%x 6", $0xundefined_4
-eval "monitor mc.get_vbits 0x%x 6", $0xundefined_4
+eval "monitor check_memory addressable 0x%x 6", $0xundefined_4
+eval "monitor check_memory defined 0x%x 6", $0xundefined_4
+eval "monitor get_vbits 0x%x 6", $0xundefined_4
#
-# ifaddressabledefined undefined[0..9]
-eval "monitor mc.make_memory ifaddressabledefined 0x%x 10", $0xundefined
+# Definedifaddressable undefined[0..9]
+eval "monitor make_memory Definedifaddressable 0x%x 10", $0xundefined
# A,V,G
-eval "monitor mc.check_memory addressable 0x%x 10", $0xundefined
-eval "monitor mc.check_memory defined 0x%x 10", $0xundefined
-eval "monitor mc.get_vbits 0x%x 10", $0xundefined
+eval "monitor check_memory addressable 0x%x 10", $0xundefined
+eval "monitor check_memory defined 0x%x 10", $0xundefined
+eval "monitor get_vbits 0x%x 10", $0xundefined
#
-monitor vg.kill
+monitor v.kill
quit
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcwatchpoints
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
#
# insert break:
vgdb-error value changed from 0 to 999999
general valgrind monitor commands:
help [debug] : monitor command help. With debug: + debugging commands
- vg.wait [<ms>] : sleep <ms> (default 0) then continue
- vg.info all_errors : show all errors found so far
- vg.info last_error : show last error found
- vg.info n_errs_found : show the nr of errors found so far
- vg.kill : kill the Valgrind process
- vg.set gdb_output : set valgrind output to gdb
- vg.set log_output : set valgrind output to log
- vg.set mixed_output : set valgrind output to log, interactive output to gdb
- vg.set vgdb-error <errornr> : debug me at error >= <errornr>
+ v.wait [<ms>] : sleep <ms> (default 0) then continue
+ v.info all_errors : show all errors found so far
+ v.info last_error : show last error found
+ v.info n_errs_found : show the nr of errors found so far
+ v.kill : kill the Valgrind process
+ v.set gdb_output : set valgrind output to gdb
+ v.set log_output : set valgrind output to log
+ v.set mixed_output : set valgrind output to log, interactive output to gdb
+ v.set vgdb-error <errornr> : debug me at error >= <errornr>
massif monitor commands:
- ms.snapshot [<filename>]
- ms.detailed_snapshot [<filename>]
+ snapshot [<filename>]
+ detailed_snapshot [<filename>]
takes a snapshot (or a detailed snapshot)
and saves it in <filename>
default <filename> is massif.vgdb.out
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mssnapshot
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
#
# insert break:
monitor help
#
# test non detailed and detailed snapshot
-monitor ms.snapshot
-monitor ms.detailed_snapshot
+monitor snapshot
+monitor detailed_snapshot
#
#
-monitor vg.kill
+monitor v.kill
quit
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-nlcontrolc
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
#
# simulate control-c in a few seconds
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-nlpasssigalrm
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
#
# ensure SIGALRM can be passed directly to the process, without
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-nlsigvgdb
echo vgdb launched process attached\n
-monitor vg.set vgdb-error 999999
+monitor v.set vgdb-error 999999
#
#
# simulate control-c in a few seconds
# an invocation while the gdbserver is already busy.
shell ./simulate_control_c --vgdb-prefix=./vgdb-prefix-nlsigvgdb 1 grep continuing nlsigvgdb.stderrB.out
#
-monitor vg.wait 5000
+monitor v.wait 5000
#
# kill the process now
-monitor vg.kill
+monitor v.kill
quit
<itemizedlist>
<listitem>
- <para><varname>ms.snapshot [<filename>]</varname> requests
+ <para><varname>snapshot [<filename>]</varname> requests
to take a snapshot and save it in the given <filename>
(default massif.vgdb.out).
</para>
</listitem>
<listitem>
- <para><varname>ms.detailed_snapshot [<filename>]</varname>
+ <para><varname>detailed_snapshot [<filename>]</varname>
requests to take a detailed snapshot and save it in the given
<filename> (default massif.vgdb.out).
</para>
{
VG_(gdb_printf) ("\n");
VG_(gdb_printf) ("massif monitor commands:\n");
- VG_(gdb_printf) (" ms.snapshot [<filename>]\n");
- VG_(gdb_printf) (" ms.detailed_snapshot [<filename>]\n");
+ VG_(gdb_printf) (" snapshot [<filename>]\n");
+ VG_(gdb_printf) (" detailed_snapshot [<filename>]\n");
VG_(gdb_printf) (" takes a snapshot (or a detailed snapshot)\n");
VG_(gdb_printf) (" and saves it in <filename>\n");
VG_(gdb_printf) (" default <filename> is massif.vgdb.out\n");
VG_(strcpy) (s, req);
wcmd = VG_(strtok_r) (s, " ", &ssaveptr);
- switch (VG_(keyword_id) ("help ms.snapshot ms.detailed_snapshot",
+ switch (VG_(keyword_id) ("help snapshot detailed_snapshot",
wcmd, kwd_report_duplicated_matches)) {
case -2: /* multiple matches */
return True;
case 0: /* help */
print_monitor_help();
return True;
- case 1: { /* ms.snapshot */
+ case 1: { /* snapshot */
Char* filename;
filename = VG_(strtok_r) (NULL, " ", &ssaveptr);
handle_snapshot_monitor_command (filename, False /* detailed */);
return True;
}
- case 2: { /* ms.detailed_snapshot */
+ case 2: { /* detailed_snapshot */
Char* filename;
filename = VG_(strtok_r) (NULL, " ", &ssaveptr);
handle_snapshot_monitor_command (filename, True /* detailed */);
<itemizedlist>
<listitem>
- <para><varname>mc.get_vbits <addr> [<len>]</varname>
+ <para><varname>get_vbits <addr> [<len>]</varname>
shows the definedness (V) bits for <len> (default 1) bytes
starting at <addr>. The definedness of each byte in the
range is given using two hexadecimal digits. These hexadecimal
<programlisting><![CDATA[
(gdb) p &string10
$4 = (char (*)[10]) 0x8049e28
-(gdb) monitor mc.get_vbits 0x8049e28 10
+(gdb) monitor get_vbits 0x8049e28 10
ff00ff00 ff__ff00 ff00
(gdb)
]]></programlisting>
+
+ <para> The command get_vbits cannot be used with registers. To get
+ the validity bits of a register, you must start Valgrind with the
+ option <option>--vgdb-shadow-registers=yes</option>. The validity
+ bits of a register can be obtained by printing the 'shadow 1'
+ corresponding register. In the below x86 example, the register
+ eax has all its bits undefined, while the register ebx is fully
+ defined.
+ </para>
+<programlisting><![CDATA[
+(gdb) p /x $eaxs1
+$9 = 0xffffffff
+(gdb) p /x $ebxs1
+$10 = 0x0
+(gdb)
+]]></programlisting>
+
</listitem>
<listitem>
- <para><varname>mc.make_memory
- [noaccess|undefined|defined|ifaddressabledefined] <addr>
+ <para><varname>make_memory
+ [noaccess|undefined|defined|Definedifaddressable] <addr>
[<len>]</varname> marks the range of <len> (default 1)
bytes at <addr> as having the given status. Parameter
<varname>noaccess</varname> marks the range as non-accessible, so
<varname>undefined</varname> or <varname>defined</varname> mark
the area as accessible, but Memcheck regards the bytes in it
respectively as having undefined or defined values.
- <varname>ifaddressabledefined</varname> marks as defined, bytes in
+ <varname>Definedifaddressable</varname> marks as defined, bytes in
the range which are already addressible, but makes no change to
- the status of bytes in the range which are not addressible.</para>
+ the status of bytes in the range which are not addressible. Note
+ that the first letter of <varname>Definedifaddressable</varname>
+ is an uppercase D to avoid confusion with <varname>defined</varname>.
+ </para>
<para>
In the following example, the first byte of the
<varname>string10</varname> is marked as defined:
</para>
<programlisting><![CDATA[
-(gdb) monitor mc.make_memory defined 0x8049e28 1
-(gdb) monitor mc.get_vbits 0x8049e28 10
+(gdb) monitor make_memory defined 0x8049e28 1
+(gdb) monitor get_vbits 0x8049e28 10
0000ff00 ff00ff00 ff00
(gdb)
]]></programlisting>
</listitem>
<listitem>
- <para><varname>mc.check_memory [addressable|defined] <addr>
+ <para><varname>check_memory [addressable|defined] <addr>
[<len>]</varname> checks that the range of <len>
- (default 1) bytes at <addr> has the specified accessibility. It
- then outputs a description of <addr>. In the following example, a
- detailed description is given available because
- the option <option>--read-var-info=yes</option>
- was given Valgrind at startup:
+ (default 1) bytes at <addr> has the specified accessibility.
+ It then outputs a description of <addr>. In the following
+ example, a detailed description is available because the
+ option <option>--read-var-info=yes</option> was given Valgrind at
+ startup:
</para>
<programlisting><![CDATA[
-(gdb) monitor mc.check_memory defined 0x8049e28 1
+(gdb) monitor check_memory defined 0x8049e28 1
Address 0x8049E28 len 1 defined
==14698== Location 0x8049e28 is 0 bytes inside string10[0],
==14698== declared at prog.c:10, in frame #0 of thread 1
</listitem>
<listitem>
- <para><varname>mc.leak_check [full*|summary]
- [reachable|leakpossible*|definiteleak]
- [increased*|changed|any]
+ <para><varname>leak_check [full*|summary]
+ [reachable|possibleleak*|definiteleak]
+ [increased*|changed|any]
</varname>
performs a leak check. The <varname>*</varname> in the arguments
indicates the default value. </para>
a <varname>full</varname> leak search. The
value <varname>definiteleak</varname> specifies that only
definitely leaked blocks should be shown. The
- value <varname>leakpossible</varname> will also show possibly
+ value <varname>possibleleak</varname> will also show possibly
leaked blocks (those for which only an interior pointer was
found). The value
<varname>reachable</varname> will show all block categories
</para>
<para>The following example shows usage of the
- <varname>mc.leak_check monitor</varname> command on
+ <varname>leak_check monitor</varname> command on
the <varname>memcheck/tests/leak-cases.c</varname> regression
test. The first command outputs one entry having an increase in
the leaked bytes. The second command is the same as the first
Valgrind gdbserver. It only outputs the summary information, as
there was no increase since the previous leak search.</para>
<programlisting><![CDATA[
-(gdb) monitor mc.leak_check full leakpossible increased
+(gdb) monitor leak_check full possibleleak increased
==14729== 16 (+16) bytes in 1 (+1) blocks are possibly lost in loss record 13 of 16
==14729== at 0x4006E9E: malloc (vg_replace_malloc.c:236)
==14729== by 0x80484D5: mk (leak-cases.c:52)
==14729== still reachable: 96 (+16) bytes in 6 (+1) blocks
==14729== suppressed: 0 (+0) bytes in 0 (+0) blocks
==14729== Reachable blocks (those to which a pointer was found) are not shown.
-==14729== o see them, add 'reachable any' args to mc.leak_check
+==14729== To see them, add 'reachable any' args to leak_check
==14729==
-(gdb) mo mc.l
+(gdb) mo l
==14729== LEAK SUMMARY:
==14729== definitely lost: 32 (+0) bytes in 2 (+0) blocks
==14729== indirectly lost: 16 (+0) bytes in 1 (+0) blocks
==14729== still reachable: 96 (+0) bytes in 6 (+0) blocks
==14729== suppressed: 0 (+0) bytes in 0 (+0) blocks
==14729== Reachable blocks (those to which a pointer was found) are not shown.
-==14729== To see them, add 'reachable any' args to mc.leak_check
+==14729== To see them, add 'reachable any' args to leak_check
==14729==
(gdb)
]]></programlisting>
with <option>--leak-check=full</option>
<option>--show-reachable=yes</option> to see the reachable
blocks. You can obtain the same information without rerunning by
- using the GDB command <computeroutput>monitor mc.leak_check full
+ using the GDB command <computeroutput>monitor leak_check full
reachable any</computeroutput> (or, using
- abbreviation: <computeroutput>mo mc.l f r a</computeroutput>).
+ abbreviation: <computeroutput>mo l f r a</computeroutput>).
</para>
</listitem>
</itemizedlist>
UInt n_total_records = extra->Err.Leak.n_total_records;
LossRecord* lr = extra->Err.Leak.lr;
// char arrays to produce the indication of increase/decrease in case
- // of delta_mode != LC_Any
+ // of delta_mode != LCD_Any
char d_bytes[20];
char d_direct_bytes[20];
char d_indirect_bytes[20];
// maintains the lcp.deltamode given in the last call to detect_memory_leaks
extern LeakCheckDeltaMode MC_(detect_memory_leaks_last_delta_mode);
-// if delta_mode == LC_Any, prints in buf an empty string
+// if delta_mode == LCD_Any, prints in buf an empty string
// otherwise prints a delta in the layout " (+%'lu)" or " (-%'lu)"
extern char * MC_(snprintf_delta) (char * buf, Int size,
SizeT current_val, SizeT old_val,
(MC_(blocks_leaked) + MC_(blocks_indirect) +
MC_(blocks_dubious) + MC_(blocks_reachable)) > 0) {
if (lcp.requested_by_monitor_command)
- VG_(umsg)("To see details of leaked memory, give 'full' arg to mc.leak_check\n");
+ VG_(umsg)("To see details of leaked memory, give 'full' arg to leak_check\n");
else
VG_(umsg)("Rerun with --leak-check=full to see details "
"of leaked memory\n");
VG_(umsg)("Reachable blocks (those to which a pointer "
"was found) are not shown.\n");
if (lcp.requested_by_monitor_command)
- VG_(umsg)("To see them, add 'reachable any' args to mc.leak_check\n");
+ VG_(umsg)("To see them, add 'reachable any' args to leak_check\n");
else
VG_(umsg)("To see them, rerun with: --leak-check=full "
"--show-reachable=yes\n");
cgb_allocs, cgb_discards, cgb_used_MAX, cgb_search
);
}
-
static void print_monitor_help ( void )
{
VG_(gdb_printf)
(
"\n"
"memcheck monitor commands:\n"
-" mc.get_vbits <addr> [<len>]\n"
+" get_vbits <addr> [<len>]\n"
" returns validity bits for <len> (or 1) bytes at <addr>\n"
" bit values 0 = valid, 1 = invalid, __ = unaddressable byte\n"
-" Example: mc.get_vbits 0x8049c78 10\n"
-" mc.make_memory [noaccess|undefined\n"
-" |defined|ifaddressabledefined] <addr> [<len>]\n"
+" Example: get_vbits 0x8049c78 10\n"
+" make_memory [noaccess|undefined\n"
+" |defined|Definedifaddressable] <addr> [<len>]\n"
" mark <len> (or 1) bytes at <addr> with the given accessibility\n"
-" mc.check_memory [addressable|defined] <addr> [<len>]\n"
+" check_memory [addressable|defined] <addr> [<len>]\n"
" check that <len> (or 1) bytes at <addr> have the given accessibility\n"
" and outputs a description of <addr>\n"
-" mc.leak_check [full*|summary] [reachable|leakpossible*|definiteleak]\n"
+" leak_check [full*|summary] [reachable|possibleleak*|definiteleak]\n"
" [increased*|changed|any]\n"
" * = defaults\n"
-" Examples: mc.leak_check\n"
-" mc.leak_check summary any\n"
+" Examples: leak_check\n"
+" leak_check summary any\n"
"\n");
}
wcmd = VG_(strtok_r) (s, " ", &ssaveptr);
/* NB: if possible, avoid introducing a new command below which
- starts with the same 4 first letters as an already existing
+ starts with the same first letter(s) as an already existing
command. This ensures a shorter abbreviation for the user. */
switch (VG_(keyword_id)
- ("help mc.get_vbits mc.leak_check mc.make_memory mc.check_memory",
+ ("help get_vbits leak_check make_memory check_memory",
wcmd, kwd_report_duplicated_matches)) {
case -2: /* multiple matches */
return True;
case 0: /* help */
print_monitor_help();
return True;
- case 1: { /* mc.get_vbits */
+ case 1: { /* get_vbits */
Addr address;
SizeT szB = 1;
VG_(strtok_get_address_and_size) (&address, &szB, &ssaveptr);
}
return True;
}
- case 2: { /* mc.leak_check */
+ case 2: { /* leak_check */
Int err = 0;
LeakCheckParams lcp;
Char* kw;
kw = VG_(strtok_r) (NULL, " ", &ssaveptr)) {
switch (VG_(keyword_id)
("full summary "
- "reachable leakpossible definiteleak "
+ "reachable possibleleak definiteleak "
"increased changed any",
kw, kwd_report_all)) {
case -2: err++; break;
case 2: /* reachable */
lcp.show_reachable = True;
lcp.show_possibly_lost = True; break;
- case 3: /* leakpossible */
+ case 3: /* possibleleak */
lcp.show_reachable = False;
lcp.show_possibly_lost = True; break;
case 4: /* definiteleak */
return True;
}
- case 3: { /* mc.make_memory */
+ case 3: { /* make_memory */
Addr address;
SizeT szB = 1;
int kwdid = VG_(keyword_id)
- ("noaccess undefined defined ifaddressabledefined",
+ ("noaccess undefined defined Definedifaddressable",
VG_(strtok_r) (NULL, " ", &ssaveptr), kwd_report_all);
VG_(strtok_get_address_and_size) (&address, &szB, &ssaveptr);
if (address == (Addr) 0 && szB == 0) return True;
return True;
}
- case 4: { /* mc.check_memory */
+ case 4: { /* check_memory */
Addr address;
SizeT szB = 1;
Addr bad_addr;