]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Make ptrace-based launchers able to handle --help, --version etc.
authorJulian Seward <jseward@acm.org>
Mon, 19 Mar 2007 18:38:55 +0000 (18:38 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 19 Mar 2007 18:38:55 +0000 (18:38 +0000)
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.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6653

coregrind/Makefile.am
coregrind/launcher-aix5.c
coregrind/m_initimg/initimg-aix5.c
coregrind/m_main.c
coregrind/no_op_client_for_valgrind.c [new file with mode: 0644]

index 578e77db5432355219d6f7c5ef85ed39e6494bcf..d725ad40d5d99ea5db2c30a027ca0d2e60249e61 100644 (file)
@@ -42,7 +42,7 @@ endif
 # 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_CPPFLAGS  = $(AM_CPPFLAGS_PRI)
 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)
 #
 #----------------------------------------------------------
 
index eaa2dc7913a1be5b5b05d8950747fe6741210226..775e51d56c74bef4e67ee529ce116fb83d3f735b 100644 (file)
@@ -1329,7 +1329,7 @@ int main ( int argc, char** argv, char** envp )
    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 @@ int main ( int argc, char** argv, char** envp )
 
    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 @@ int main ( int argc, char** argv, char** envp )
       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 @@ int main ( int argc, char** argv, char** envp )
    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");
index 5033be79e66975471a8c1df422b19732c2e2f65d..cf02dacc27444ad9d3a8d57b63ec73abece92e0f 100644 (file)
@@ -96,6 +96,10 @@ IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii )
    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*/
index 84fb4e39fca949bc8820deaec938e8fdd1cd06db..0c8bebc7a01bc79c72c9349d00ffe892af36a3fa 100644 (file)
@@ -1399,6 +1399,18 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
          );
    }
 
+#  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,
diff --git a/coregrind/no_op_client_for_valgrind.c b/coregrind/no_op_client_for_valgrind.c
new file mode 100644 (file)
index 0000000..5956607
--- /dev/null
@@ -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;
+}