|
From: <sv...@va...> - 2007-03-19 18:39:07
|
Author: sewardj
Date: 2007-03-19 18:38:55 +0000 (Mon, 19 Mar 2007)
New Revision: 6653
Log:
Make ptrace-based launchers able to handle --help, --version etc.
Problem is that --help etc are handled by the tool exe. But a
ptrace-based launch scheme can't run "no program" if the user just
types "valgrind --help" because the launcher depends on starting the
client first and only then attaching valgrind to it using ptrace. So
instead provide a dummy do-nothing program to run when no program is
specified. m_main notices this and acts as if there really had been
no program specified.
This has no effect at all on Linux/ELF program launching.
Added:
trunk/coregrind/no_op_client_for_valgrind.c
Modified:
trunk/coregrind/Makefile.am
trunk/coregrind/launcher-aix5.c
trunk/coregrind/m_initimg/initimg-aix5.c
trunk/coregrind/m_main.c
Modified: trunk/coregrind/Makefile.am
===================================================================
--- trunk/coregrind/Makefile.am 2007-03-19 15:29:23 UTC (rev 6652)
+++ trunk/coregrind/Makefile.am 2007-03-19 18:38:55 UTC (rev 6653)
@@ -42,7 +42,7 @@
# Build the launcher (valgrind) for the primary target only.
#
bin_PROGRAMS = \
- valgrind
+ valgrind no_op_client_for_valgrind
if VGO_AIX5
valgrind_SOURCES = \
@@ -59,6 +59,10 @@
valgrind_CFLAGS = $(AM_CFLAGS_PRI)
valgrind_CCASFLAGS = $(AM_CCASFLAGS_PRI)
valgrind_LDFLAGS = $(AM_CFLAGS_PRI)
+
+no_op_client_for_valgrind_SOURCES = no_op_client_for_valgrind.c
+no_op_client_for_valgrind_CPPFLAGS = $(AM_CPPFLAGS_PRI)
+no_op_client_for_valgrind_CFLAGS = $(AM_CFLAGS_PRI)
#
#----------------------------------------------------------
Modified: trunk/coregrind/launcher-aix5.c
===================================================================
--- trunk/coregrind/launcher-aix5.c 2007-03-19 15:29:23 UTC (rev 6652)
+++ trunk/coregrind/launcher-aix5.c 2007-03-19 18:38:55 UTC (rev 6653)
@@ -1329,7 +1329,7 @@
Child child;
Int i, loglevel;
const char *toolname = NULL;
- const char *clientname = NULL;
+ char *clientname = NULL;
/* First, look in our own /proc/<pid>/sysent file to find
the syscall numbers for kwrite and _getpid. These are needed
@@ -1421,6 +1421,44 @@
assert(PAGE_SIZE == 4096); /* stay sane */
+ const char* valgrind_lib = VG_LIBDIR;
+
+ /* If there is no program to run, which will be the case if the
+ user just does "valgrind --help", etc, run a dummy do-nothing
+ program so at least the tool can get started and handle the
+ --help/--version etc. It spots the fact that this is a dummy
+ program and acts like it was started with no program, hence
+ behaving the same as the Linux ports would have. */
+ if (clientname == NULL) {
+ Int j;
+ char** new_argv;
+ const char* noop_exe_name = "no_op_client_for_valgrind";
+ const char* up_n_bindir = "/../../bin";
+ clientname = malloc(strlen(valgrind_lib) + strlen(up_n_bindir)
+ + 2 + strlen(noop_exe_name));
+ if (clientname == NULL) {
+ fprintf(stderr,"%s: malloc of clientname failed\n", argv[0]);
+ return 1;
+ }
+ sprintf(clientname, "%s%s/%s", valgrind_lib, up_n_bindir, noop_exe_name);
+ /* now we have to add it to the end of argv, which means making
+ that one word longer. How tedious. */
+ for (j = 0; argv[j]; j++)
+ ;
+ j += 2;
+ new_argv = calloc(j, sizeof(char*));
+ if (new_argv == NULL) {
+ fprintf(stderr,"%s: malloc of new_argv failed\n", argv[0]);
+ return 1;
+ }
+ for (i = 0; i < j-2; i++)
+ new_argv[i] = argv[i];
+ new_argv[j-2] = clientname;
+ assert(new_argv[j-1] == NULL);
+ argv = new_argv;
+ argc++;
+ }
+
if (argc < 2 || toolname == NULL || clientname == NULL)
barf(1, argv[0], "usage: valgrind [args-for-valgrind] prog args");
@@ -1428,7 +1466,7 @@
executable. */
VG_(debugLog)(1, "launcher", "searching for client in $PATH\n");
if (strchr(clientname, '/') == NULL)
- clientname = find_client(clientname);
+ clientname = (char*)find_client(clientname);
VG_(debugLog)(1, "launcher", "found %s\n", clientname);
Int client_exekind = examine_client ( clientname );
@@ -1450,7 +1488,6 @@
VG_(debugLog)(1, "launcher", "client is an XCOFF%d executable\n",
client_exekind);
- const char* valgrind_lib = VG_LIBDIR;
const char* platform = child.is64 ? "ppc64-aix5" : "ppc32-aix5";
VG_(debugLog)(1, "launcher", "looking for the tool file\n");
Modified: trunk/coregrind/m_initimg/initimg-aix5.c
===================================================================
--- trunk/coregrind/m_initimg/initimg-aix5.c 2007-03-19 15:29:23 UTC (rev 6652)
+++ trunk/coregrind/m_initimg/initimg-aix5.c 2007-03-19 18:38:55 UTC (rev 6653)
@@ -96,6 +96,10 @@
IIFinaliseImageInfo iifii;
VG_(memset)( &iifii, 0, sizeof(iifii) );
+ /* this can happen, if m_main decides to NULL it out */
+ if (VG_(args_the_exename) == NULL)
+ VG_(err_missing_prog)();
+
vg_assert( iicii.toolname );
pltool_len = VG_(strlen)( VG_(libdir) )
+ 1 /*slash*/
Modified: trunk/coregrind/m_main.c
===================================================================
--- trunk/coregrind/m_main.c 2007-03-19 15:29:23 UTC (rev 6652)
+++ trunk/coregrind/m_main.c 2007-03-19 18:38:55 UTC (rev 6653)
@@ -1399,6 +1399,18 @@
);
}
+# if defined(VGO_aix5)
+ /* Tolerate ptraced-based launchers. They can't run 'no program'
+ if the user types "valgrind --help", so they run a do-nothing
+ program $prefix/bin/no_op_client_for_valgrind, and we catch that
+ here and turn it the exe name back into NULL. Then --help,
+ --version etc work as they should. */
+ if (VG_(args_the_exename)
+ && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
+ VG_(args_the_exename) = NULL;
+ }
+# endif
+
//--------------------------------------------------------------
// Extract tool name and whether help has been requested.
// Note we can't print the help message yet, even if requested,
Added: trunk/coregrind/no_op_client_for_valgrind.c
===================================================================
--- trunk/coregrind/no_op_client_for_valgrind.c (rev 0)
+++ trunk/coregrind/no_op_client_for_valgrind.c 2007-03-19 18:38:55 UTC (rev 6653)
@@ -0,0 +1,16 @@
+
+/* This program doesn't do anything. So why is it here? It's a
+ helper for ptraced-based launchers (eg aix5). They can't run 'no
+ program' if the user types "valgrind --help", so they run this
+ do-nothing program. m_main notices that and turns the exe name
+ back into NULL. Then --help, --version etc work as they should. */
+
+#include <stdio.h>
+int main ( void )
+{
+ fprintf(stderr,
+ "This program (part of Valgrind) does nothing except print\n"
+ "this text. You should not see this text. If you do, some\n"
+ "part of valgrind's launch mechanism is not working correctly.\n");
+ return 0;
+}
|
|
From: Nicholas N. <nj...@cs...> - 2007-03-19 21:09:33
|
On Mon, 19 Mar 2007 sv...@va... wrote:
> Modified: trunk/coregrind/m_main.c
> ===================================================================
> --- trunk/coregrind/m_main.c 2007-03-19 15:29:23 UTC (rev 6652)
> +++ trunk/coregrind/m_main.c 2007-03-19 18:38:55 UTC (rev 6653)
> @@ -1399,6 +1399,18 @@
> );
> }
>
> +# if defined(VGO_aix5)
> + /* Tolerate ptraced-based launchers. They can't run 'no program'
> + if the user types "valgrind --help", so they run a do-nothing
> + program $prefix/bin/no_op_client_for_valgrind, and we catch that
> + here and turn it the exe name back into NULL. Then --help,
> + --version etc work as they should. */
> + if (VG_(args_the_exename)
> + && VG_(strstr)( VG_(args_the_exename), "/no_op_client_for_valgrind" )) {
> + VG_(args_the_exename) = NULL;
> + }
> +# endif
Does this need to be conditionally compiled? Seems like it could safely
always be there.
Nick
|