|
From: Nicholas N. <nj...@ca...> - 2004-01-26 16:48:38
|
CVS commit by nethercote:
Patch from Tom Hughes:
Patch to allow debuggers other than GDB to be used
The patch replaces --gdb-attach and --gdb-path with --db-attach and
--db-command which are more general. The --db-command switch takes a
command string that can contain one or more instances of %p and %f markers.
The %p marker is replaced with the PID of the process to attach to and the
%f marker with the filename of the executable being attached to.
The default command is "gdb -nw %f %p" which gaves the same result as
currently.
M +10 -10 vg_errcontext.c 1.53
M +9 -6 vg_include.h 1.176
M +60 -25 vg_main.c 1.142
M +2 -2 vg_signals.c 1.59
M +21 -16 docs/coregrind_core.html 1.24
--- valgrind/coregrind/vg_errcontext.c #1.52:1.53
@@ -112,5 +112,5 @@ static void pp_Error ( Error* err, Bool
}
-/* Figure out if we want to attach for GDB for this error, possibly
+/* Figure out if we want to perform a given action for this error, possibly
by asking the user. */
Bool VG_(is_action_requested) ( Char* action, Bool* clo )
@@ -248,12 +248,12 @@ static void gen_suppression(Error* err)
static
-void do_actions_on_error(Error* err, Bool allow_GDB_attach)
+void do_actions_on_error(Error* err, Bool allow_db_attach)
{
- /* Perhaps we want a GDB attach at this point? */
- if (allow_GDB_attach &&
- VG_(is_action_requested)( "Attach to GDB", & VG_(clo_GDB_attach) ))
+ /* Perhaps we want a debugger attach at this point? */
+ if (allow_db_attach &&
+ VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) ))
{
- VG_(printf)("starting gdb\n");
- VG_(start_GDB)( err->tid );
+ VG_(printf)("starting debugger\n");
+ VG_(start_debugger)( err->tid );
}
/* Or maybe we want to generate the error's suppression? */
@@ -413,5 +413,5 @@ void VG_(maybe_record_error) ( ThreadId
is_first_shown_context = False;
vg_n_errs_shown++;
- do_actions_on_error(p, /*allow_GDB_attach*/True);
+ do_actions_on_error(p, /*allow_db_attach*/True);
} else {
vg_n_errs_suppressed++;
@@ -429,5 +429,5 @@ void VG_(maybe_record_error) ( ThreadId
Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s,
void* extra, ExeContext* where, Bool print_error,
- Bool allow_GDB_attach, Bool count_error )
+ Bool allow_db_attach, Bool count_error )
{
Error err;
@@ -454,5 +454,5 @@ Bool VG_(unique_error) ( ThreadId tid, E
is_first_shown_context = False;
}
- do_actions_on_error(&err, allow_GDB_attach);
+ do_actions_on_error(&err, allow_db_attach);
return False;
--- valgrind/coregrind/vg_include.h #1.175:1.176
@@ -164,4 +164,7 @@
#define VG_CLO_MAX_SFILES 10
+/* Default debugger command. */
+#define VG_CLO_DEFAULT_DBCOMMAND GDB_PATH " -nw %f %p"
+
/* Describes where logging output is to be sent. */
typedef
@@ -183,8 +186,8 @@ extern Int VG_(max_fd);
/* Should we stop collecting errors if too many appear? default: YES */
extern Bool VG_(clo_error_limit);
-/* Enquire about whether to attach to GDB at errors? default: NO */
-extern Bool VG_(clo_GDB_attach);
-/* The path to GDB? default: whatever ./configure found */
-extern Char* VG_(clo_GDB_path);
+/* Enquire about whether to attach to a debugger at errors? default: NO */
+extern Bool VG_(clo_db_attach);
+/* The debugger command? default: whatever gdb ./configure found */
+extern Char* VG_(clo_db_command);
/* Enquire about generating a suppression for each error? default: NO */
extern Bool VG_(clo_gen_suppressions);
@@ -1411,6 +1414,6 @@ extern Bool VG_(sysinfo_page_exists);
extern Addr VG_(sysinfo_page_addr);
-/* Something of a function looking for a home ... start up GDB. */
-extern void VG_(start_GDB) ( Int tid );
+/* Something of a function looking for a home ... start up debugger. */
+extern void VG_(start_debugger) ( Int tid );
/* VG_(bbs_done) in include/vg_skin.h */
--- valgrind/coregrind/vg_main.c #1.141:1.142
@@ -293,10 +293,10 @@ static void show_counts ( void )
/*====================================================================*/
-/* Start GDB and get it to attach to this process. Called if the user
- requests this service after an error has been shown, so she can
+/* Start debugger and get it to attach to this process. Called if the
+ user requests this service after an error has been shown, so she can
poke around and look at parameters, memory, etc. You can't
- meaningfully get GDB to continue the program, though; to continue,
- quit GDB. */
-void VG_(start_GDB) ( Int tid )
+ meaningfully get the debugger to continue the program, though; to
+ continue, quit the debugger. */
+void VG_(start_debugger) ( Int tid )
{
Int pid;
@@ -353,14 +353,49 @@ void VG_(start_GDB) ( Int tid )
ptrace(PTRACE_SETREGS, pid, NULL, ®s) == 0 &&
ptrace(PTRACE_DETACH, pid, NULL, SIGSTOP) == 0) {
- UChar buf[VG_(strlen)(VG_(clo_GDB_path)) + 100];
+ Char pidbuf[15];
+ Char file[30];
+ Char buf[100];
+ Char *bufptr;
+ Char *cmdptr;
- VG_(sprintf)(buf, "%s -nw /proc/%d/fd/%d %d",
- VG_(clo_GDB_path), VG_(main_pid), VG_(clexecfd), pid);
- VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
+ VG_(sprintf)(pidbuf, "%d", pid);
+ VG_(sprintf)(file, "/proc/%d/fd/%d", pid, VG_(clexecfd));
+
+ bufptr = buf;
+ cmdptr = VG_(clo_db_command);
+
+ while (*cmdptr) {
+ switch (*cmdptr) {
+ case '%':
+ switch (*++cmdptr) {
+ case 'f':
+ VG_(memcpy)(bufptr, file, VG_(strlen)(file));
+ bufptr += VG_(strlen)(file);
+ cmdptr++;
+ break;
+ case 'p':
+ VG_(memcpy)(bufptr, pidbuf, VG_(strlen)(pidbuf));
+ bufptr += VG_(strlen)(pidbuf);
+ cmdptr++;
+ break;
+ default:
+ *bufptr++ = *cmdptr++;
+ break;
+ }
+ break;
+ default:
+ *bufptr++ = *cmdptr++;
+ break;
+ }
+ }
+
+ *bufptr++ = '\0';
+
+ VG_(message)(Vg_UserMsg, "starting debugger with cmd: %s", buf);
res = VG_(system)(buf);
if (res == 0) {
VG_(message)(Vg_UserMsg, "");
VG_(message)(Vg_UserMsg,
- "GDB has detached. Valgrind regains control. We continue.");
+ "Debugger has detached. Valgrind regains control. We continue.");
} else {
VG_(message)(Vg_UserMsg, "Apparently failed!");
@@ -1364,6 +1399,6 @@ static void load_client(char* cl_argv[],
/* Define, and set defaults. */
Bool VG_(clo_error_limit) = True;
-Bool VG_(clo_GDB_attach) = False;
-Char* VG_(clo_GDB_path) = GDB_PATH;
+Bool VG_(clo_db_attach) = False;
+Char* VG_(clo_db_command) = VG_CLO_DEFAULT_DBCOMMAND;
Bool VG_(clo_gen_suppressions) = False;
Int VG_(sanity_level) = 1;
@@ -1473,7 +1508,7 @@ void usage ( void )
" --gen-suppressions=no|yes print suppressions for errors detected [no]\n"
-" --gdb-attach=no|yes start GDB when errors detected? [no]\n"
-" --gdb-path=/path/to/gdb path to the GDB to use [/usr/bin/gdb]\n"
-" --input-fd=<number> file descriptor for (gdb) input [0=stdin]\n"
+" --db-attach=no|yes start debugger when errors detected? [no]\n"
+" --db-command=<command> command to start debugger [gdb -nw %%f %%p]\n"
+" --input-fd=<number> file descriptor for input [0=stdin]\n"
"\n";
@@ -1656,11 +1691,11 @@ static void process_cmd_line_options
VG_(clo_error_limit) = False;
- else if (VG_CLO_STREQ(arg, "--gdb-attach=yes"))
- VG_(clo_GDB_attach) = True;
- else if (VG_CLO_STREQ(arg, "--gdb-attach=no"))
- VG_(clo_GDB_attach) = False;
+ else if (VG_CLO_STREQ(arg, "--db-attach=yes"))
+ VG_(clo_db_attach) = True;
+ else if (VG_CLO_STREQ(arg, "--db-attach=no"))
+ VG_(clo_db_attach) = False;
- else if (VG_CLO_STREQN(11,arg, "--gdb-path="))
- VG_(clo_GDB_path) = &arg[11];
+ else if (VG_CLO_STREQN(13,arg, "--db-command="))
+ VG_(clo_db_command) = &arg[13];
else if (VG_CLO_STREQ(arg, "--gen-suppressions=yes"))
@@ -1849,11 +1884,11 @@ static void process_cmd_line_options
VG_(clo_verbosity) = 0;
- if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
+ if (VG_(clo_db_attach) && VG_(clo_trace_children)) {
VG_(message)(Vg_UserMsg, "");
VG_(message)(Vg_UserMsg,
- "--gdb-attach=yes conflicts with --trace-children=yes");
+ "--db-attach=yes conflicts with --trace-children=yes");
VG_(message)(Vg_UserMsg,
"Please choose one or the other, but not both.");
- VG_(bad_option)("--gdb-attach=yes and --trace-children=yes");
+ VG_(bad_option)("--db-attach=yes and --trace-children=yes");
}
--- valgrind/coregrind/vg_signals.c #1.58:1.59
@@ -1392,6 +1392,6 @@ static void vg_default_action(const vki_
}
- if (VG_(is_action_requested)( "Attach to GDB", & VG_(clo_GDB_attach) )) {
- VG_(start_GDB)( tid );
+ if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
+ VG_(start_debugger)( tid );
}
--- valgrind/coregrind/docs/coregrind_core.html #1.23:1.24
@@ -617,5 +617,5 @@
<code>---- Print suppression ? --- [Return/N/n/Y/y/C/c] ----</code>
<p>
- The prompt's behaviour is the same as for the <code>--gdb-attach</code>
+ The prompt's behaviour is the same as for the <code>--db-attach</code>
option.
<p>
@@ -647,26 +647,26 @@
<br><p>
- <li><code>--gdb-attach=no</code> [default]<br>
- <code>--gdb-attach=yes</code>
+ <li><code>--db-attach=no</code> [default]<br>
+ <code>--db-attach=yes</code>
<p>When enabled, Valgrind will pause after every error shown,
and print the line
<br>
- <code>---- Attach to GDB ? --- [Return/N/n/Y/y/C/c] ----</code>
+ <code>---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ----</code>
<p>
Pressing <code>Ret</code>, or <code>N</code> <code>Ret</code>
or <code>n</code> <code>Ret</code>, causes Valgrind not to
- start GDB for this error.
+ start a debugger for this error.
<p>
<code>Y</code> <code>Ret</code>
or <code>y</code> <code>Ret</code> causes Valgrind to
- start GDB, for the program at this point. When you have
- finished with GDB, quit from it, and the program will continue.
- Trying to continue from inside GDB doesn't work.
+ start a debugger, for the program at this point. When you have
+ finished with the debugger, quit from it, and the program will continue.
+ Trying to continue from inside the debugger doesn't work.
<p>
<code>C</code> <code>Ret</code>
or <code>c</code> <code>Ret</code> causes Valgrind not to
- start GDB, and not to ask again.
+ start a debugger, and not to ask again.
<p>
- <code>--gdb-attach=yes</code> conflicts with
+ <code>--db-attach=yes</code> conflicts with
<code>--trace-children=yes</code>. You can't use them together.
Valgrind refuses to start up in this situation. 1 May 2002:
@@ -679,14 +679,19 @@
</li><br><p>
- <li><code>--gdb-path=/path/to/gdb</code>
- <p>This specifies how Valgrind will invoke GDB. By default, it
- will use whatever GDB is detected at build time,
+ <li><code>--db-command=<command></code> [default: gdb -nw %f %p]<br>
+ <p>This specifies how Valgrind will invoke the debugger. By
+ default it will use whatever GDB is detected at build time,
which is usually <code>/usr/bin/gdb</code>. Using this command,
- you can specify some alternative path to the GDB you want to
- use.
+ you can specify some alternative command to invoke the debugger
+ you want to use.
+ <p>
+ The command string given can include one or instances of the
+ %p and %f expansions. Each instance of %p expands to the PID of
+ the process to be debugged and each instance of %f expands to
+ the path to the executable for the process to be debugged.
</li><br><p>
<li><code>--input-fd=<number></code> [default=0, stdin]<br>
- <p>When using <code>--gdb-attach=yes</code> and
+ <p>When using <code>--db-attach=yes</code> and
<code>--gen-suppressions=yes</code>, Valgrind will stop
so as to read keyboard input from you, when each error occurs.
|