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 */