|
From: <sv...@va...> - 2014-04-20 13:41:23
|
Author: philippe
Date: Sun Apr 20 13:41:10 2014
New Revision: 13900
Log:
- The option "--vgdb-stop-at=event1,event2,..." allows the user
to ask GDB server to stop before program execution, at the end
of the program execution and on Valgrind internal errors.
- A new monitor command "v.set hostvisibility" that allows GDB server
to provide access to Valgrind internal host status/memory.
Modified:
trunk/NEWS
trunk/coregrind/m_gdbserver/m_gdbserver.c
trunk/coregrind/m_gdbserver/remote-utils.c
trunk/coregrind/m_gdbserver/server.c
trunk/coregrind/m_gdbserver/target.c
trunk/coregrind/m_gdbserver/target.h
trunk/coregrind/m_libcassert.c
trunk/coregrind/m_main.c
trunk/coregrind/m_options.c
trunk/coregrind/pub_core_gdbserver.h
trunk/coregrind/pub_core_libcassert.h
trunk/coregrind/pub_core_options.h
trunk/docs/xml/manual-core-adv.xml
trunk/docs/xml/manual-core.xml
trunk/gdbserver_tests/mchelp.stdoutB.exp
trunk/none/tests/cmdline1.stdout.exp
trunk/none/tests/cmdline2.stdout.exp
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Sun Apr 20 13:41:10 2014
@@ -24,9 +24,16 @@
* New and modified GDB server monitor features:
+ - The option "--vgdb-stop-at=event1,event2,..." allows the user
+ to ask GDB server to stop before program execution, at the end
+ of the program execution and on Valgrind internal errors.
+
- A new monitor command "v.info stats" that shows various valgrind core and
tool statistics.
+ - A new monitor command "v.set hostvisibility" that allows GDB server
+ to provide access to Valgrind internal host status/memory.
+
* ==================== FIXED BUGS ====================
The following bugs have been fixed or resolved. Note that "n-i-bz"
Modified: trunk/coregrind/m_gdbserver/m_gdbserver.c
==============================================================================
--- trunk/coregrind/m_gdbserver/m_gdbserver.c (original)
+++ trunk/coregrind/m_gdbserver/m_gdbserver.c Sun Apr 20 13:41:10 2014
@@ -588,11 +588,22 @@
invalidate_if_jump_not_yet_gdbserved (VG_(get_IP) (tid), who);
}
+Bool VG_(gdbserver_init_done) (void)
+{
+ return gdbserver_called > 0;
+}
+
+Bool VG_(gdbserver_stop_at) (VgdbStopAt stopat)
+{
+ return gdbserver_called > 0 && VgdbStopAtiS(stopat, VG_(clo_vgdb_stop_at));
+}
+
void VG_(gdbserver_prerun_action) (ThreadId tid)
{
// Using VG_(dyn_vgdb_error) allows the user to control if gdbserver
// stops after a fork.
- if (VG_(dyn_vgdb_error) == 0) {
+ if (VG_(dyn_vgdb_error) == 0
+ || VgdbStopAtiS(VgdbStopAt_Startup, VG_(clo_vgdb_stop_at))) {
/* The below call allows gdb to attach at startup
before the first guest instruction is executed. */
VG_(umsg)("(action at startup) vgdb me ... \n");
@@ -1457,7 +1468,8 @@
"interrupts intr_tid %d gs_non_busy %d gs_busy %d tid_non_intr %d\n"
"gdbserved addresses %d (-1 = not initialized)\n"
"watchpoints %d (-1 = not initialized)\n"
- "vgdb-error %d\n",
+ "vgdb-error %d\n"
+ "hostvisibility %s\n",
gdbserver_called,
valgrind_single_stepping(),
@@ -1468,5 +1480,6 @@
nr_gdbserved_addresses,
nr_watchpoints,
- VG_(dyn_vgdb_error));
+ VG_(dyn_vgdb_error),
+ hostvisibility ? "yes" : "no");
}
Modified: trunk/coregrind/m_gdbserver/remote-utils.c
==============================================================================
--- trunk/coregrind/m_gdbserver/remote-utils.c (original)
+++ trunk/coregrind/m_gdbserver/remote-utils.c Sun Apr 20 13:41:10 2014
@@ -407,21 +407,23 @@
{
const int pid = VG_(getpid)();
remote_finish(orderly_finish);
- if (pid == pid_from_to_creator) {
- dlog(1, "unlinking\n %s\n %s\n %s\n",
- from_gdb, to_gdb, shared_mem);
- if (VG_(unlink) (from_gdb) == -1)
- warning ("could not unlink %s\n", from_gdb);
- if (VG_(unlink) (to_gdb) == -1)
- warning ("could not unlink %s\n", to_gdb);
- if (VG_(unlink) (shared_mem) == -1)
- warning ("could not unlink %s\n", shared_mem);
- }
- else {
- dlog(1, "not creator => not unlinking %s and %s\n", from_gdb, to_gdb);
- }
+ dlog(1, "%d (creator %d) maybe unlinking \n %s\n %s\n %s\n",
+ pid, pid_from_to_creator,
+ from_gdb ? from_gdb : "NULL",
+ to_gdb ? to_gdb : "NULL",
+ shared_mem ? shared_mem : "NULL");
+ if (pid == pid_from_to_creator && from_gdb && VG_(unlink) (from_gdb) == -1)
+ warning ("could not unlink %s\n", from_gdb);
+ if (pid == pid_from_to_creator && to_gdb && VG_(unlink) (to_gdb) == -1)
+ warning ("could not unlink %s\n", to_gdb);
+ if (pid == pid_from_to_creator && shared_mem && VG_(unlink) (shared_mem) == -1)
+ warning ("could not unlink %s\n", shared_mem);
free (from_gdb);
+ from_gdb = NULL;
free (to_gdb);
+ to_gdb = NULL;
+ free (shared_mem);
+ shared_mem = NULL;
}
Bool remote_connected(void)
Modified: trunk/coregrind/m_gdbserver/server.c
==============================================================================
--- trunk/coregrind/m_gdbserver/server.c (original)
+++ trunk/coregrind/m_gdbserver/server.c Sun Apr 20 13:41:10 2014
@@ -119,7 +119,6 @@
void kill_request (const char *msg)
{
VG_(umsg) ("%s", msg);
- remote_close();
VG_(exit) (0);
}
@@ -243,6 +242,8 @@
" v.info scheduler : show valgrind thread state and stacktrace\n"
" v.info stats : show various valgrind and tool stats\n"
" v.set debuglog <level> : set valgrind debug log level to <level>\n"
+" v.set hostvisibility [yes*|no] : (en/dis)ables access by gdb/gdbserver to\n"
+" Valgrind internal host status/memory\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");
@@ -253,7 +254,7 @@
wcmd = strtok_r (NULL, " ", &ssaveptr);
switch (kwdid = VG_(keyword_id)
("vgdb-error debuglog merge-recursive-frames"
- " gdb_output log_output mixed_output",
+ " gdb_output log_output mixed_output hostvisibility ",
wcmd, kwd_report_all)) {
case -2:
case -1:
@@ -305,6 +306,32 @@
VG_(gdb_printf)
("valgrind output will go to log, interactive output will go to gdb\n");
break;
+ case 6: /* hostvisibility */
+ wcmd = strtok_r (NULL, " ", &ssaveptr);
+ if (wcmd != NULL) {
+ switch (VG_(keyword_id) ("yes no", wcmd, kwd_report_all)) {
+ case -2:
+ case -1: break;
+ case 0:
+ hostvisibility = True;
+ break;
+ case 1:
+ hostvisibility = False;
+ break;
+ default: tl_assert (0);
+ }
+ } else {
+ hostvisibility = True;
+ }
+ if (hostvisibility)
+ VG_(gdb_printf)
+ ("Enabled access to Valgrind memory/status by GDB\n"
+ "If not yet done, tell GDB which valgrind file(s) to use:\n"
+ "add-symbol-file <tool or preloaded file> <loadaddr>\n");
+ else
+ VG_(gdb_printf)
+ ("Disabled access to Valgrind memory/status by GDB\n");
+ break;
default:
vg_assert (0);
}
Modified: trunk/coregrind/m_gdbserver/target.c
==============================================================================
--- trunk/coregrind/m_gdbserver/target.c (original)
+++ trunk/coregrind/m_gdbserver/target.c Sun Apr 20 13:41:10 2014
@@ -446,46 +446,55 @@
usr_store_inferior_registers (regno);
}
+Bool hostvisibility = False;
+
int valgrind_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
const void *sourceaddr = C2v (memaddr);
dlog(2, "reading memory %p size %d\n", sourceaddr, len);
- if (!VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr) sourceaddr,
- len, VKI_PROT_READ)) {
+ if (VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr) sourceaddr,
+ len, VKI_PROT_READ)
+ || (hostvisibility /* TBD: && check valgrind read accessibility */)) {
+ VG_(memcpy) (myaddr, sourceaddr, len);
+ return 0;
+ } else {
dlog(1, "error reading memory %p size %d\n", sourceaddr, len);
return -1;
}
- VG_(memcpy) (myaddr, sourceaddr, len);
- return 0;
}
int valgrind_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
{
+ Bool is_valid_client_memory;
void *targetaddr = C2v (memaddr);
dlog(2, "writing memory %p size %d\n", targetaddr, len);
- if (!VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr)targetaddr,
- len, VKI_PROT_WRITE)) {
+ is_valid_client_memory
+ = VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr)targetaddr,
+ len, VKI_PROT_WRITE);
+ if (is_valid_client_memory
+ || (hostvisibility /* TBD: && check valgrind write accessibility */)) {
+ if (len > 0) {
+ VG_(memcpy) (targetaddr, myaddr, len);
+ if (is_valid_client_memory && VG_(tdict).track_post_mem_write) {
+ /* Inform the tool of the post memwrite. Note that we do the
+ minimum necessary to avoid complains from e.g.
+ memcheck. The idea is that the debugger is as least
+ intrusive as possible. So, we do not inform of the pre
+ mem write (and in any case, this would cause problems with
+ memcheck that does not like our CorePart in
+ pre_mem_write. */
+ ThreadState *tst =
+ (ThreadState *) inferior_target_data (current_inferior);
+ ThreadId tid = tst->tid;
+ VG_(tdict).track_post_mem_write( Vg_CoreClientReq, tid,
+ (Addr) targetaddr, len );
+ }
+ }
+ return 0;
+ } else {
dlog(1, "error writing memory %p size %d\n", targetaddr, len);
return -1;
}
- if (len > 0) {
- VG_(memcpy) (targetaddr, myaddr, len);
- if (VG_(tdict).track_post_mem_write) {
- /* Inform the tool of the post memwrite. Note that we do the
- minimum necessary to avoid complains from e.g.
- memcheck. The idea is that the debugger is as least
- intrusive as possible. So, we do not inform of the pre
- mem write (and in any case, this would cause problems with
- memcheck that does not like our CorePart in
- pre_mem_write. */
- ThreadState *tst =
- (ThreadState *) inferior_target_data (current_inferior);
- ThreadId tid = tst->tid;
- VG_(tdict).track_post_mem_write( Vg_CoreClientReq, tid,
- (Addr) targetaddr, len );
- }
- }
- return 0;
}
/* insert or remove a breakpoint */
Modified: trunk/coregrind/m_gdbserver/target.h
==============================================================================
--- trunk/coregrind/m_gdbserver/target.h (original)
+++ trunk/coregrind/m_gdbserver/target.h Sun Apr 20 13:41:10 2014
@@ -233,5 +233,8 @@
Bool *mod);
+// True means gdbserver can access (internal) Valgrind memory.
+// Otherwise, only the client memory can be accessed.
+extern Bool hostvisibility;
#endif /* TARGET_H */
Modified: trunk/coregrind/m_libcassert.c
==============================================================================
--- trunk/coregrind/m_libcassert.c (original)
+++ trunk/coregrind/m_libcassert.c Sun Apr 20 13:41:10 2014
@@ -33,6 +33,7 @@
#include "pub_core_vkiscnums.h"
#include "pub_core_libcsetjmp.h" // to keep threadstate.h happy
#include "pub_core_threadstate.h"
+#include "pub_core_gdbserver.h"
#include "pub_core_aspacemgr.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
@@ -228,9 +229,33 @@
#define BACKTRACE_DEPTH 100 // nice and deep!
-/* Pull down the entire world */
-void VG_(exit)( Int status )
+__attribute__ ((__noreturn__))
+static void exit_wrk( Int status, Bool gdbserver_call_allowed)
{
+ static Bool exit_called = False;
+ // avoid recursive exit during gdbserver call.
+
+ if (gdbserver_call_allowed && !exit_called) {
+ const ThreadId atid = 1; // Arbitrary tid used to call/terminate gdbsrv.
+ exit_called = True;
+ if (status != 0 && VG_(gdbserver_stop_at) (VgdbStopAt_ValgrindAbExit)) {
+ if (VG_(gdbserver_init_done)()) {
+ VG_(umsg)("(action at valgrind abnormal exit) vgdb me ... \n");
+ VG_(gdbserver) (atid);
+ } else {
+ VG_(umsg)("(action at valgrind abnormal exit) "
+ "Early valgrind exit : vgdb not yet usable\n");
+ }
+ }
+ if (VG_(gdbserver_init_done)()) {
+ // Always terminate the gdbserver when Valgrind exits, so as
+ // to e.g. cleanup the FIFOs.
+ VG_(gdbserver_exit) (atid,
+ status == 0 ? VgSrc_ExitProcess : VgSrc_FatalSig);
+ }
+ }
+ exit_called = True;
+
#if defined(VGO_linux)
(void)VG_(do_syscall1)(__NR_exit_group, status );
#elif defined(VGO_darwin)
@@ -245,6 +270,19 @@
*(volatile Int*)0 = 'x';
}
+/* Pull down the entire world */
+void VG_(exit)( Int status )
+{
+ exit_wrk (status, True);
+}
+
+/* Pull down the entire world */
+void VG_(client_exit)( Int status )
+{
+ exit_wrk (status, False);
+}
+
+
// Print the scheduler status.
static void show_sched_status_wrk ( Bool host_stacktrace,
Bool valgrind_stack_usage,
@@ -305,7 +343,8 @@
if (valgrind_stack_usage && stack != 0)
VG_(printf)("valgrind stack top usage: %ld of %ld\n",
VG_STACK_ACTIVE_SZB
- - VG_(am_get_VgStack_unused_szB)(stack, VG_STACK_ACTIVE_SZB),
+ - VG_(am_get_VgStack_unused_szB)(stack,
+ VG_STACK_ACTIVE_SZB),
(SizeT) VG_STACK_ACTIVE_SZB);
}
VG_(printf)("\n");
Modified: trunk/coregrind/m_main.c
==============================================================================
--- trunk/coregrind/m_main.c (original)
+++ trunk/coregrind/m_main.c Sun Apr 20 13:41:10 2014
@@ -108,6 +108,8 @@
" --vgdb-error=<number> invoke gdbserver after <number> errors [%d]\n"
" to get started quickly, use --vgdb-error=0\n"
" and follow the on-screen directions\n"
+" --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]\n"
+" where event is one of startup exit valgrindabexit all none\n"
" --track-fds=no|yes track open file descriptors? [no]\n"
" --time-stamp=no|yes add timestamps to log messages? [no]\n"
" --log-fd=<number> log messages to file descriptor [2=stderr]\n"
@@ -537,6 +539,11 @@
}
else if VG_INT_CLO (arg, "--vgdb-poll", VG_(clo_vgdb_poll)) {}
else if VG_INT_CLO (arg, "--vgdb-error", VG_(clo_vgdb_error)) {}
+ else if VG_STR_CLO (arg, "--vgdb-stop-at", tmp_str) {
+ if (!VG_(parse_enum_set)("startup,exit,valgrindabexit", tmp_str,
+ &VG_(clo_vgdb_stop_at)))
+ VG_(fmsg_bad_option)(arg, "");
+ }
else if VG_STR_CLO (arg, "--vgdb-prefix", VG_(clo_vgdb_prefix)) {
VG_(arg_vgdb_prefix) = arg;
}
@@ -2414,7 +2421,13 @@
vg_assert(VG_(count_living_threads)() >= 1);
}
+ /* Final call to gdbserver, if requested. */
+ if (VG_(gdbserver_stop_at) (VgdbStopAt_Exit)) {
+ VG_(umsg)("(action at exit) vgdb me ... \n");
+ VG_(gdbserver) (tid);
+ }
VG_(threads)[tid].status = VgTs_Empty;
+
//--------------------------------------------------------------
// Finalisation: cleanup, messages, etc. Order not so important, only
// affects what order the messages come.
@@ -2489,7 +2502,7 @@
/* Flush any output cached by previous calls to VG_(message). */
VG_(message_flush)();
- /* terminate gdbserver if ever it was started. We terminate it here
+ /* Terminate gdbserver if ever it was started. We terminate it here
so that it get the output above if output was redirected to
gdb */
VG_(gdbserver_exit) (tid, tids_schedretcode);
@@ -2508,11 +2521,11 @@
if an error was found */
if (VG_(clo_error_exitcode) > 0
&& VG_(get_n_errs_found)() > 0) {
- VG_(exit)( VG_(clo_error_exitcode) );
+ VG_(client_exit)( VG_(clo_error_exitcode) );
} else {
/* otherwise, return the client's exit code, in the normal
way. */
- VG_(exit)( VG_(threads)[tid].os_state.exitcode );
+ VG_(client_exit)( VG_(threads)[tid].os_state.exitcode );
}
/* NOT ALIVE HERE! */
VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
Modified: trunk/coregrind/m_options.c
==============================================================================
--- trunk/coregrind/m_options.c (original)
+++ trunk/coregrind/m_options.c Sun Apr 20 13:41:10 2014
@@ -56,6 +56,7 @@
#endif
Int VG_(clo_vgdb_poll) = 5000;
Int VG_(clo_vgdb_error) = 999999999;
+UInt VG_(clo_vgdb_stop_at) = 0;
const HChar *VG_(clo_vgdb_prefix) = NULL;
const HChar *VG_(arg_vgdb_prefix) = NULL;
Bool VG_(clo_vgdb_shadow_registers) = False;
Modified: trunk/coregrind/pub_core_gdbserver.h
==============================================================================
--- trunk/coregrind/pub_core_gdbserver.h (original)
+++ trunk/coregrind/pub_core_gdbserver.h Sun Apr 20 13:41:10 2014
@@ -31,6 +31,7 @@
#define __PUB_CORE_GDBSERVER_H
#include "pub_tool_gdbserver.h"
+#include "pub_core_options.h"
#include "pub_core_threadstate.h" // VgSchedReturnCode
/* Return the default path prefix for the named pipes (FIFOs) used by vgdb/gdb
@@ -44,6 +45,13 @@
// If VG_(clo_vgdb) == No, the below has no effect.
void VG_(gdbserver_prerun_action) (ThreadId tid);
+// True if the initialisation of gdbserver was done,
+// i.e. VG_(gdbserver_prerun_action) was called.
+Bool VG_(gdbserver_init_done) (void);
+
+// True if gdbserver should stop execution for the specified stop at reason
+Bool VG_(gdbserver_stop_at) (VgdbStopAt stopat);
+
// True if there is some activity from vgdb
// If it returns True, then extern void VG_(gdbserver) can be called
// to handle this incoming vgdb request.
Modified: trunk/coregrind/pub_core_libcassert.h
==============================================================================
--- trunk/coregrind/pub_core_libcassert.h (original)
+++ trunk/coregrind/pub_core_libcassert.h Sun Apr 20 13:41:10 2014
@@ -66,6 +66,9 @@
__attribute__ ((__noreturn__))
extern void VG_(core_panic_at) ( const HChar* str, UnwindStartRegs* );
+/* Exits with status as client exit code. */
+extern void VG_(client_exit)( Int status );
+
/* Called when some unhandleable client behaviour is detected.
Prints a msg and aborts. */
extern void VG_(unimplemented) ( const HChar* msg )
Modified: trunk/coregrind/pub_core_options.h
==============================================================================
--- trunk/coregrind/pub_core_options.h (original)
+++ trunk/coregrind/pub_core_options.h Sun Apr 20 13:41:10 2014
@@ -69,6 +69,26 @@
/* if > 0, checks every VG_(clo_vgdb_poll) BBS if vgdb wants to be served. */
extern Int VG_(clo_vgdb_poll);
+/* Specify when Valgrind gdbserver stops the execution and wait
+ for a GDB to connect. */
+typedef
+ enum { // Stop :
+ VgdbStopAt_Startup, // just before the client starts to execute.
+ VgdbStopAt_Exit, // just before the client exits.
+ VgdbStopAt_ValgrindAbExit // on abnormal valgrind exit.
+ }
+ VgdbStopAt;
+// Build mask to check or set VgdbStop_At a membership
+#define VgdbStopAt2S(a) (1 << (a))
+// VgdbStopAt a is member of the Set s ?
+#define VgdbStopAtiS(a,s) ((s) & VgdbStopAt2S(a))
+// A set with all VgdbStopAt:
+#define VgdbStopAtallS \
+ (VgdbStopAt2S(VgdbStopAt_Startup) \
+ | VgdbStopAt2S(VgdbStopAt_Exit) \
+ | VgdbStopAt2S(VgdbStopAt_ValgrindAbExit)
+extern UInt VG_(clo_vgdb_stop_at); // A set of VgdbStopAt reasons.
+
/* prefix for the named pipes (FIFOs) used by vgdb/gdb to communicate with valgrind */
extern const HChar *VG_(clo_vgdb_prefix);
Modified: trunk/docs/xml/manual-core-adv.xml
==============================================================================
--- trunk/docs/xml/manual-core-adv.xml (original)
+++ trunk/docs/xml/manual-core-adv.xml Sun Apr 20 13:41:10 2014
@@ -1456,6 +1456,40 @@
</listitem>
<listitem>
+ <para><varname>v.set hostvisibility [yes*|no]</varname> The value
+ "yes" indicates to gdbserver that GDB can look at the Valgrind
+ 'host' (internal) status/memory. "no" disables this access.
+ When hostvisibility is activated, GDB can e.g. look at Valgrind
+ global variables. As an example, to examine a Valgrind global
+ variable of the memcheck tool on an x86, do the following setup:</para>
+
+<screen><![CDATA[
+(gdb) monitor v.set hostvisibility yes
+(gdb) add-symbol-file /path/to/tool/executable/file/memcheck-x86-linux 0x38000000
+add symbol table from file "/path/to/tool/executable/file/memcheck-x86-linux" at
+ .text_addr = 0x38000000
+(y or n) y
+Reading symbols from /path/to/tool/executable/file/memcheck-x86-linux...done.
+(gdb)
+]]></screen>
+
+ <para>After that, variables defined in memcheck-x86-linux can be accessed, e.g.</para>
+
+<screen><![CDATA[
+(gdb) p /x vgPlain_threads[1].os_state
+$3 = {lwpid = 0x4688, threadgroup = 0x4688, parent = 0x0,
+ valgrind_stack_base = 0x62e78000, valgrind_stack_init_SP = 0x62f79fe0,
+ exitcode = 0x0, fatalsig = 0x0}
+(gdb) p vex_control
+$5 = {iropt_verbosity = 0, iropt_level = 2,
+ iropt_register_updates = VexRegUpdUnwindregsAtMemAccess,
+ iropt_unroll_thresh = 120, guest_max_insns = 60, guest_chase_thresh = 10,
+ guest_chase_cond = 0 '\000'}
+(gdb)
+]]></screen>
+ </listitem>
+
+ <listitem>
<para><varname>v.translate <address>
[<traceflags>]</varname> shows the translation of the block
containing <computeroutput>address</computeroutput> with the given
Modified: trunk/docs/xml/manual-core.xml
==============================================================================
--- trunk/docs/xml/manual-core.xml (original)
+++ trunk/docs/xml/manual-core.xml Sun Apr 20 13:41:10 2014
@@ -777,6 +777,46 @@
</listitem>
</varlistentry>
+ <varlistentry id="opt.vgdb-stop-at" xreflabel="--vgdb-stop-at">
+ <term>
+ <option><![CDATA[--vgdb-stop-at=<set> [default: none] ]]></option>
+ </term>
+ <listitem>
+ <para> Use this option when the Valgrind gdbserver is enabled with
+ <option>--vgdb=yes</option> or <option>--vgdb=full</option>.
+ The Valgrind gdbserver will be invoked for each error after
+ <option>--vgdb-error</option> have been reported.
+ You can additionally ask the Valgrind gdbserver to be invoked
+ for other events, specified in one of the following ways: </para>
+ <itemizedlist>
+ <listitem><para>a comma separated list of one or more of
+ <option>startup exit valgrindabexit</option>.</para>
+
+ <para>The values <option>startup</option> <option>exit</option>
+ <option>valgrindabexit</option> respectively indicate to
+ invoke gdbserver before your program is executed, after the
+ last instruction of your program, on Valgrind abnormal exit
+ (e.g. internal error, out of memory, ...).</para>
+
+ <para>Note: <option>startup</option> and
+ <option>--vgdb-error=0</option> will both cause Valgrind
+ gdbserver to be invoked before your program is executed. The
+ <option>--vgdb-error=0</option> will in addition cause your
+ program to stop on all subsequent errors.</para>
+
+ </listitem>
+
+ <listitem><para><option>all</option> to specify the complete set.
+ It is equivalent to
+ <option>--vgdb-stop-at=startup,exit,valgrindabexit</option>.</para>
+ </listitem>
+
+ <listitem><para><option>none</option> for the empty set.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="opt.track-fds" xreflabel="--track-fds">
<term>
<option><![CDATA[--track-fds=<yes|no> [default: no] ]]></option>
Modified: trunk/gdbserver_tests/mchelp.stdoutB.exp
==============================================================================
--- trunk/gdbserver_tests/mchelp.stdoutB.exp (original)
+++ trunk/gdbserver_tests/mchelp.stdoutB.exp Sun Apr 20 13:41:10 2014
@@ -64,6 +64,8 @@
v.info scheduler : show valgrind thread state and stacktrace
v.info stats : show various valgrind and tool stats
v.set debuglog <level> : set valgrind debug log level to <level>
+ v.set hostvisibility [yes*|no] : (en/dis)ables access by gdb/gdbserver to
+ Valgrind internal host status/memory
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
Modified: trunk/none/tests/cmdline1.stdout.exp
==============================================================================
--- trunk/none/tests/cmdline1.stdout.exp (original)
+++ trunk/none/tests/cmdline1.stdout.exp Sun Apr 20 13:41:10 2014
@@ -21,6 +21,8 @@
--vgdb-error=<number> invoke gdbserver after <number> errors [999999999]
to get started quickly, use --vgdb-error=0
and follow the on-screen directions
+ --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]
+ where event is one of startup exit valgrindabexit all none
--track-fds=no|yes track open file descriptors? [no]
--time-stamp=no|yes add timestamps to log messages? [no]
--log-fd=<number> log messages to file descriptor [2=stderr]
Modified: trunk/none/tests/cmdline2.stdout.exp
==============================================================================
--- trunk/none/tests/cmdline2.stdout.exp (original)
+++ trunk/none/tests/cmdline2.stdout.exp Sun Apr 20 13:41:10 2014
@@ -21,6 +21,8 @@
--vgdb-error=<number> invoke gdbserver after <number> errors [999999999]
to get started quickly, use --vgdb-error=0
and follow the on-screen directions
+ --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]
+ where event is one of startup exit valgrindabexit all none
--track-fds=no|yes track open file descriptors? [no]
--time-stamp=no|yes add timestamps to log messages? [no]
--log-fd=<number> log messages to file descriptor [2=stderr]
|