If the launcher can't figure out what it's own name is, don't bail
out.  Instead, print a warning message, continue, and cause any
attempt to trace into a child process to fail with ECHILD.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4861 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/launcher.c b/coregrind/launcher.c
index 8c3c395..8140491 100644
--- a/coregrind/launcher.c
+++ b/coregrind/launcher.c
@@ -99,8 +99,16 @@
       invokations of valgrind on child processes. */
    memset(launcher_name, 0, PATH_MAX+1);
    r = readlink("/proc/self/exe", launcher_name, PATH_MAX);
-   if (r == -1)
-      barf("readlink(\"/proc/self/exe\") failed.");
+   if (r == -1) {
+      /* If /proc/self/exe can't be followed, don't give up.  Instead
+         continue with an empty string for VALGRIND_LAUNCHER.  In the
+         sys_execve wrapper, this is tested, and if found to be empty,
+         fail the execve. */
+      fprintf(stderr, "valgrind: warning (non-fatal): "
+                      "readlink(\"/proc/self/exe\") failed.\n");
+      fprintf(stderr, "valgrind: continuing, however --trace-children=yes "
+                      "will not work.\n");
+   }
 
    /* tediously augment the env: VALGRIND_LAUNCHER=launcher_name */
    new_line = malloc(strlen(VALGRIND_LAUNCHER) + 1 
diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c
index 3bde662..f4a9cb7 100644
--- a/coregrind/m_syswrap/syswrap-generic.c
+++ b/coregrind/m_syswrap/syswrap-generic.c
@@ -2329,6 +2329,16 @@
       return;
    }
 
+   /* If we're tracing the child, and the launcher name looks bogus
+      (possibly because launcher.c couldn't figure it out, see
+      comments therein) then we have no option but to fail. */
+   if (VG_(clo_trace_children) 
+       && (VG_(name_of_launcher) == NULL
+           || VG_(name_of_launcher)[0] != '/')) {
+      SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
+      return;
+   }
+
    /* After this point, we can't recover if the execve fails. */
    VG_(debugLog)(1, "syswrap", "Exec of %s\n", (Char*)ARG1);
 
diff --git a/include/vki-linux.h b/include/vki-linux.h
index 3fe2354..599ac1a 100644
--- a/include/vki-linux.h
+++ b/include/vki-linux.h
@@ -1087,6 +1087,7 @@
 #define	VKI_EINTR		 4	/* Interrupted system call */
 #define VKI_ENOEXEC              8      /* Exec format error */
 #define	VKI_EBADF		 9	/* Bad file number */
+#define VKI_ECHILD              10      /* No child processes */
 #define VKI_EAGAIN		11	/* Try again */
 #define VKI_EWOULDBLOCK		VKI_EAGAIN
 #define	VKI_ENOMEM		12	/* Out of memory */