]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Darwin launcher: executable path changes
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 15 Nov 2025 13:31:36 +0000 (14:31 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 15 Nov 2025 13:33:48 +0000 (14:33 +0100)
Fixes
memcheck/tests/execve2
Merged from
https://github.com/LouisBrunner/valgrind-macos.git

coregrind/launcher-darwin.c

index 933050617b6de026e08d4838a0c1c94a1cf4d08c..743f7c943b8ceb146c7116aba4afc94662f0fb51 100644 (file)
@@ -64,7 +64,7 @@ static struct {
       MacOS X, but .. the Apple PPC descriptors refer to the BE
       variant, since the LE variant is something that appeared long
       after Apple dropped PPC. */
-   { CPU_TYPE_POWERPC,   "ppc",    "ppc32" }, 
+   { CPU_TYPE_POWERPC,   "ppc",    "ppc32" },
    { CPU_TYPE_POWERPC64, "ppc64",  "ppc64be" }
 };
 static int valid_archs_count = sizeof(valid_archs)/sizeof(valid_archs[0]);
@@ -156,7 +156,7 @@ static const char *select_arch(
    if (bytes != sizeof(buf)) {
       return NULL;
    }
-   
+
    // If it's thin, return that arch.
    {
       struct mach_header *mh = (struct mach_header *)buf;
@@ -182,7 +182,7 @@ static const char *select_arch(
          if (fat_has_cputype(fh, default_cputype)) {
             return default_arch;
          }
-         
+
          // Scan fat headers for any supported arch.
          for (i = 0; i < valid_archs_count; i++) {
             if (fat_has_cputype(fh, valid_archs[i].cputype)) {
@@ -191,7 +191,7 @@ static const char *select_arch(
          }
       }
    }
-   
+
    return NULL;
 }
 
@@ -210,6 +210,7 @@ int main(int argc, char** argv, char** envp)
    const char *default_arch;
    cpu_type_t default_cputype;
    char *toolfile;
+   char* executable_path;
    char launcher_name[PATH_MAX+1];
    char* new_line;
    char* set_cwd;
@@ -218,7 +219,7 @@ int main(int argc, char** argv, char** envp)
    char **new_argv;
    int new_argc;
 
-   /* Start the debugging-log system ASAP.  First find out how many 
+   /* Start the debugging-log system ASAP.  First find out how many
       "-d"s were specified.  This is a pre-scan of the command line.
       At the same time, look for the tool name. */
    loglevel = 0;
@@ -235,9 +236,9 @@ int main(int argc, char** argv, char** envp)
          }
          break;
       }
-      if (0 == strcmp(argv[i], "-d")) 
+      if (0 == strcmp(argv[i], "-d"))
          loglevel++;
-      if (0 == strncmp(argv[i], "--tool=", 7)) 
+      if (0 == strncmp(argv[i], "--tool=", 7))
          toolname = argv[i] + 7;
       if (0 == strncmp(argv[i], "--arch=", 7))
          archname = argv[i] + 7;
@@ -251,7 +252,7 @@ int main(int argc, char** argv, char** envp)
    if (toolname) {
       VG_(debugLog)(1, "launcher", "tool '%s' requested\n", toolname);
    } else {
-      VG_(debugLog)(1, "launcher", 
+      VG_(debugLog)(1, "launcher",
                        "no tool requested, defaulting to 'memcheck'\n");
       toolname = "memcheck";
    }
@@ -296,14 +297,14 @@ int main(int argc, char** argv, char** envp)
       free(vgpreload_core);
    }
 
-   /* Find the "default" arch (VGCONF_ARCH_PRI from configure). 
+   /* Find the "default" arch (VGCONF_ARCH_PRI from configure).
       This is the preferred arch from fat files and the fallback. */
    default_arch = NULL;
    default_cputype = 0;
    for (i = 0; i < valid_archs_count; i++) {
       if (!valid_archs[i].cputype) continue;
-      if (0 == strncmp(VG_PLATFORM, valid_archs[i].valgrind_name, 
-                       strlen(valid_archs[i].valgrind_name))) 
+      if (0 == strncmp(VG_PLATFORM, valid_archs[i].valgrind_name,
+                       strlen(valid_archs[i].valgrind_name)))
       {
          default_arch = valid_archs[i].valgrind_name;
          default_cputype = valid_archs[i].cputype;
@@ -319,7 +320,7 @@ int main(int argc, char** argv, char** envp)
       // --arch from command line
       arch = NULL;
       for (i = 0; i < valid_archs_count; i++) {
-         if (0 == strcmp(archname, valid_archs[i].apple_name)  ||  
+         if (0 == strcmp(archname, valid_archs[i].apple_name)  ||
              0 == strcmp(archname, valid_archs[i].valgrind_name))
          {
             arch = valid_archs[i].valgrind_name;
@@ -328,28 +329,28 @@ int main(int argc, char** argv, char** envp)
       }
       if (i == valid_archs_count) barf("Unknown --arch '%s'", archname);
       assert(NULL != arch);
-      VG_(debugLog)(1, "launcher", "using arch '%s' from --arch=%s\n", 
+      VG_(debugLog)(1, "launcher", "using arch '%s' from --arch=%s\n",
                     arch, archname);
-   } 
+   }
    else if (clientname == NULL) {
       // no client executable; use default as fallback
-      VG_(debugLog)(1, "launcher", 
+      VG_(debugLog)(1, "launcher",
                        "no client specified, defaulting arch to '%s'\n",
                         default_arch);
       arch = default_arch;
-   } 
+   }
    else if ((arch = select_arch(clientname, default_cputype,default_arch))) {
       // arch from client executable
       VG_(debugLog)(1, "launcher", "selected arch '%s'\n", arch);
-   } 
+   }
    else {
       // nothing found in client executable; use default as fallback
-      VG_(debugLog)(1, "launcher", 
+      VG_(debugLog)(1, "launcher",
                        "no arch detected, defaulting arch to '%s'\n",
                        default_arch);
       arch = default_arch;
    }
-   
+
    cwd = getcwd(NULL, 0);
    if (!cwd) barf("Current directory no longer exists.");
 
@@ -357,28 +358,35 @@ int main(int argc, char** argv, char** envp)
       we can tell stage2.  stage2 will use the name for recursive
       invocations of valgrind on child processes. */
    memset(launcher_name, 0, PATH_MAX+1);
-   for (i = 0; envp[i]; i++) 
+   for (i = 0; envp[i]; i++)
        ; /* executable path is after last envp item */
    /* envp[i] == NULL ; envp[i+1] == executable_path */
-   if (envp[i+1][0] != '/') {
+   executable_path = envp[i+1];
+   /* Since macOS 10.14.6, executable_path is prefixed by "executable_path=",
+      like an environment list */
+   if (strlen(executable_path) > 16 && strncmp(executable_path, "executable_path=", 16) == 0) {
+     executable_path = &executable_path[16];
+   }
+   if (executable_path[0] != '/') {
       strcpy(launcher_name, cwd);
       strcat(launcher_name, "/");
    }
-   if (strlen(launcher_name) + strlen(envp[i+1]) > PATH_MAX)
+   if (strlen(launcher_name) + strlen(executable_path) > PATH_MAX)
       barf("launcher path is too long");
-   strcat(launcher_name, envp[i+1]);
+   strcat(launcher_name, executable_path);
    VG_(debugLog)(1, "launcher", "launcher_name = %s\n", launcher_name);
 
    /* tediously augment the env: VALGRIND_LAUNCHER=launcher_name */
    asprintf(&new_line, VALGRIND_LAUNCHER "=%s", launcher_name);
 
    /* tediously augment the env: VALGRIND_STARTUP_PWD_%PID_XYZZY=current_working_dir */
-   asprintf(&set_cwd, "VALGRIND_STARTUP_PWD_%u_XYZZY=%s", getppid(), cwd);
+   asprintf(&set_cwd, "VALGRIND_STARTUP_PWD_%d_XYZZY=%s", getppid(), cwd);
 
    // Note that Apple binaries get a secret fourth arg, "char* apple", which
    // contains the executable path.  Don't forget about it.
    for (j = 0; envp[j]; j++)
       ;
+   // 4 includes VALGRIND_LAUNCHER, VALGRIND_STARTUP_PWD, NULL and executable_path
    new_env = malloc((j+4) * sizeof(char*));
    if (new_env == NULL)
       barf("malloc of new_env failed.");