diff --git a/toolkit/crashreporter/client/crashreporter_osx.mm b/toolkit/crashreporter/client/crashreporter_osx.mm index 70cdfbebecbf..9f59665947c7 100644 --- a/toolkit/crashreporter/client/crashreporter_osx.mm +++ b/toolkit/crashreporter/client/crashreporter_osx.mm @@ -41,6 +41,8 @@ #import #include "crashreporter.h" #include "crashreporter_osx.h" +#include +#include #include #include #include @@ -62,6 +64,16 @@ static vector gRestartArgs; static bool gDidTrySend = false; static bool gRTLlayout = false; +static cpu_type_t pref_cpu_types[2] = { +#if defined(__i386__) + CPU_TYPE_X86, +#elif defined(__x86_64__) + CPU_TYPE_X86_64, +#elif defined(__ppc__) + CPU_TYPE_POWERPC, +#endif + CPU_TYPE_ANY }; + #define NSSTR(s) [NSString stringWithUTF8String:(s).c_str()] static NSString* Str(const char* aName) @@ -73,10 +85,24 @@ static NSString* Str(const char* aName) static bool RestartApplication() { - char** argv = reinterpret_cast( - malloc(sizeof(char*) * (gRestartArgs.size() + 1))); + vector argv(gRestartArgs.size() + 1); - if (!argv) return false; + posix_spawnattr_t spawnattr; + if (posix_spawnattr_init(&spawnattr) != 0) { + return false; + } + + // Set spawn attributes. + size_t attr_count = sizeof(pref_cpu_types) / sizeof(pref_cpu_types[0]); + size_t attr_ocount = 0; + if (posix_spawnattr_setbinpref_np(&spawnattr, + attr_count, + pref_cpu_types, + &attr_ocount) != 0 || + attr_ocount != attr_count) { + posix_spawnattr_destroy(&spawnattr); + return false; + } unsigned int i; for (i = 0; i < gRestartArgs.size(); i++) { @@ -84,17 +110,20 @@ static bool RestartApplication() } argv[i] = 0; - pid_t pid = fork(); - if (pid == -1) - return false; - else if (pid == 0) { - (void)execv(argv[0], argv); - _exit(1); - } + char **env = NULL; + char ***nsEnv = _NSGetEnviron(); + if (nsEnv) + env = *nsEnv; + int result = posix_spawnp(NULL, + argv[0], + NULL, + &spawnattr, + &argv[0], + env); - free(argv); + posix_spawnattr_destroy(&spawnattr); - return true; + return result == 0; } @implementation CrashReporterUI diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporter/nsExceptionHandler.cpp index 31cefa5b4ff4..727d53c63774 100644 --- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -60,9 +60,11 @@ #include #include #include +#include #include #include #include +#include #include #include "mac_utils.h" #elif defined(XP_LINUX) @@ -226,6 +228,20 @@ static const char* kSubprocessBlacklist[] = { #endif // MOZ_IPC +#ifdef XP_MACOSX +static cpu_type_t pref_cpu_types[2] = { +#if defined(__i386__) + CPU_TYPE_X86, +#elif defined(__x86_64__) + CPU_TYPE_X86_64, +#elif defined(__ppc__) + CPU_TYPE_POWERPC, +#endif + CPU_TYPE_ANY }; + +static posix_spawnattr_t spawnattr; +#endif + #ifdef XP_LINUX inline void my_timetostring(time_t t, char* buffer, size_t buffer_length) @@ -417,6 +433,28 @@ bool MinidumpCallback(const XP_CHAR* dump_path, return returnValue; } +#ifdef XP_MACOSX + char* const my_argv[] = { + crashReporterPath, + minidumpPath, + NULL + }; + + char **env = NULL; + char ***nsEnv = _NSGetEnviron(); + if (nsEnv) + env = *nsEnv; + int result = posix_spawnp(NULL, + my_argv[0], + NULL, + &spawnattr, + my_argv, + env); + + if (result != 0) + return false; + +#else // !XP_MACOSX pid_t pid = sys_fork(); if (pid == -1) @@ -429,7 +467,8 @@ bool MinidumpCallback(const XP_CHAR* dump_path, crashReporterPath, minidumpPath, (char*)0); _exit(1); } -#endif +#endif // XP_MACOSX +#endif // XP_UNIX return returnValue; } @@ -558,6 +597,25 @@ nsresult SetExceptionHandler(nsILocalFile* aXREDirectory, #error "Implement this for your platform" #endif +#ifdef XP_MACOSX + // Initialize spawn attributes, since this calls malloc. + if (posix_spawnattr_init(&spawnattr) != 0) { + return NS_ERROR_FAILURE; + } + + // Set spawn attributes. + size_t attr_count = NS_ARRAY_LENGTH(pref_cpu_types); + size_t attr_ocount = 0; + if (posix_spawnattr_setbinpref_np(&spawnattr, + attr_count, + pref_cpu_types, + &attr_ocount) != 0 || + attr_ocount != attr_count) { + posix_spawnattr_destroy(&spawnattr); + return NS_ERROR_FAILURE; + } +#endif + // now set the exception handler gExceptionHandler = new google_breakpad:: ExceptionHandler(tempPath.get(), @@ -849,6 +907,10 @@ nsresult UnsetExceptionHandler() crashReporterPath = nsnull; } +#ifdef XP_MACOSX + posix_spawnattr_destroy(&spawnattr); +#endif + if (!gExceptionHandler) return NS_ERROR_NOT_INITIALIZED;