Bug 1293656 - Clean up the exception handler code r=ted
☠☠ backed out by 93d785448a69 ☠ ☠
authorGabriele Svelto <gsvelto@mozilla.com>
Wed, 19 Oct 2016 12:38:56 +0200
changeset 325292 b997bb5bccb4da93ce1f5d3453ca562324ab1d5f
parent 325291 1e7ee9c3b11432576e6bff68aa9a96650c3130a0
child 325293 f59861923f8169c003f0f7f8bd50e3fae52e0b51
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersted
bugs1293656
milestone53.0a1
Bug 1293656 - Clean up the exception handler code r=ted
toolkit/crashreporter/nsExceptionHandler.cpp
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -546,20 +546,22 @@ CreatePathFromFile(nsIFile* file)
   if (NS_FAILED(rv)) {
     return nullptr;
   }
   return new xpstring(path.get(), path.Length());
 }
 #endif
 
 static XP_CHAR*
-Concat(XP_CHAR* str, const XP_CHAR* toAppend, int* size)
+Concat(XP_CHAR* str, const XP_CHAR* toAppend, size_t* size)
 {
-  int appendLen = XP_STRLEN(toAppend);
-  if (appendLen >= *size) appendLen = *size - 1;
+  size_t appendLen = XP_STRLEN(toAppend);
+  if (appendLen >= *size) {
+    appendLen = *size - 1;
+  }
 
   memcpy(str, toAppend, appendLen * sizeof(XP_CHAR));
   str += appendLen;
   *str = '\0';
   *size -= appendLen;
 
   return str;
 }
@@ -769,17 +771,17 @@ WriteAnnotation(PlatformWriter& pw, cons
  * dump file path.
  */
 static void
 OpenAPIData(PlatformWriter& aWriter,
             const XP_CHAR* dump_path, const XP_CHAR* minidump_id = nullptr
            )
 {
   static XP_CHAR extraDataPath[XP_PATH_MAX];
-  int size = XP_PATH_MAX;
+  size_t size = XP_PATH_MAX;
   XP_CHAR* p;
   if (minidump_id) {
     p = Concat(extraDataPath, dump_path, &size);
     p = Concat(p, XP_PATH_SEPARATOR, &size);
     p = Concat(p, minidump_id, &size);
   } else {
     p = Concat(extraDataPath, dump_path, &size);
     // Skip back past the .dmp extension, if any.
@@ -820,16 +822,146 @@ WriteGlobalMemoryStatus(PlatformWriter* 
     WRITE_STATEX_FIELD(ullTotalPhys, "TotalPhysicalMemory", _ui64toa);
     WRITE_STATEX_FIELD(ullAvailPhys, "AvailablePhysicalMemory", _ui64toa);
 
 #undef WRITE_STATEX_FIELD
   }
 }
 #endif
 
+#if !defined(MOZ_WIDGET_ANDROID)
+
+/**
+ * Launches the program specified in aProgramPath with aMinidumpPath as its
+ * sole argument.
+ *
+ * @param aProgramPath The path of the program to be launched
+ * @param aMinidumpPath The path of the minidump file, passed as an argument
+ *        to the launched program
+ */
+static bool
+LaunchProgram(XP_CHAR* aProgramPath, XP_CHAR* aMinidumpPath)
+{
+#ifdef XP_WIN
+  XP_CHAR cmdLine[CMDLINE_SIZE];
+  XP_CHAR* p;
+
+  size_t size = CMDLINE_SIZE;
+  p = Concat(cmdLine, L"\"", &size);
+  p = Concat(p, aProgramPath, &size);
+  p = Concat(p, L"\" \"", &size);
+  p = Concat(p, aMinidumpPath, &size);
+  Concat(p, L"\"", &size);
+
+  STARTUPINFO si;
+  PROCESS_INFORMATION pi;
+  ZeroMemory(&si, sizeof(si));
+  si.cb = sizeof(si);
+  ZeroMemory(&pi, sizeof(pi));
+
+  // If CreateProcess() fails don't do anything
+  if (CreateProcess(nullptr, (LPWSTR)cmdLine, nullptr, nullptr, FALSE,
+                    NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
+                    nullptr, nullptr, &si, &pi)) {
+    CloseHandle(pi.hProcess);
+    CloseHandle(pi.hThread);
+  }
+#elif defined(XP_UNIX)
+#ifdef XP_MACOSX
+  pid_t pid = 0;
+  char* const my_argv[] = {
+    aProgramPath,
+    aMinidumpPath,
+    nullptr
+  };
+
+  char **env = nullptr;
+  char ***nsEnv = _NSGetEnviron();
+  if (nsEnv)
+    env = *nsEnv;
+
+  int rv = posix_spawnp(&pid, my_argv[0], nullptr, &spawnattr, my_argv, env);
+
+  if (rv != 0) {
+    return false;
+  }
+
+#else // !XP_MACOSX
+  pid_t pid = sys_fork();
+
+  if (pid == -1) {
+    return false;
+  } else if (pid == 0) {
+    // need to clobber this, as libcurl might load NSS,
+    // and we want it to load the system NSS.
+    unsetenv("LD_LIBRARY_PATH");
+    Unused << execl(aProgramPath,
+                    aProgramPath, aMinidumpPath, (char*)0);
+    _exit(1);
+  }
+#endif // XP_MACOSX
+#endif // XP_UNIX
+
+  return true;
+}
+
+#else
+
+/**
+ * Launch the crash reporter activity on Android
+ *
+ * @param aProgramPath The path of the program to be launched
+ * @param aMinidumpPath The path to the crash minidump file
+ * @param aSucceeded True if the minidump was obtained successfully
+ */
+
+static bool
+LaunchCrashReporterActivity(XP_CHAR* aProgramPath, XP_CHAR* aMinidumpPath,
+                            bool aSucceeded)
+{
+  pid_t pid = sys_fork();
+
+  if (pid == -1)
+    return false;
+  else if (pid == 0) {
+    // Invoke the reportCrash activity using am
+    if (androidUserSerial) {
+      Unused << execlp("/system/bin/am",
+                       "/system/bin/am",
+                       "start",
+                       "--user", androidUserSerial,
+                       "-a", "org.mozilla.gecko.reportCrash",
+                       "-n", aProgramPath,
+                       "--es", "minidumpPath", aMinidumpPath,
+                       "--ez", "minidumpSuccess", aSucceeded ? "true" : "false",
+                       (char*)0);
+    } else {
+      Unused << execlp("/system/bin/am",
+                       "/system/bin/am",
+                       "start",
+                       "-a", "org.mozilla.gecko.reportCrash",
+                       "-n", aProgramPath,
+                       "--es", "minidumpPath", aMinidumpPath,
+                       "--ez", "minidumpSuccess", aSucceeded ? "true" : "false",
+                       (char*)0);
+    }
+    _exit(1);
+
+  } else {
+    // We need to wait on the 'am start' command above to finish, otherwise everything will
+    // be killed by the ActivityManager as soon as the signal handler exits
+    int status;
+    Unused << HANDLE_EINTR(sys_waitpid(pid, &status, __WALL));
+  }
+
+  return true;
+}
+
+#endif
+
 bool MinidumpCallback(
 #ifdef XP_LINUX
                       const MinidumpDescriptor& descriptor,
 #else
                       const XP_CHAR* dump_path,
                       const XP_CHAR* minidump_id,
 #endif
                       void* context,
@@ -837,17 +969,17 @@ bool MinidumpCallback(
                       EXCEPTION_POINTERS* exinfo,
                       MDRawAssertionInfo* assertion,
 #endif
                       bool succeeded)
 {
   bool returnValue = showOSCrashReporter ? false : succeeded;
 
   static XP_CHAR minidumpPath[XP_PATH_MAX];
-  int size = XP_PATH_MAX;
+  size_t size = XP_PATH_MAX;
   XP_CHAR* p;
 #ifndef XP_LINUX
   p = Concat(minidumpPath, dump_path, &size);
   p = Concat(p, XP_PATH_SEPARATOR, &size);
   p = Concat(p, minidump_id, &size);
   Concat(p, dumpFileExtension, &size);
 #else
   Concat(minidumpPath, descriptor.path(), &size);
@@ -959,17 +1091,17 @@ bool MinidumpCallback(
 #endif
 
   {
     PlatformWriter apiData;
     PlatformWriter eventFile;
 
     if (eventsDirectory) {
       static XP_CHAR crashEventPath[XP_PATH_MAX];
-      int size = XP_PATH_MAX;
+      size_t size = XP_PATH_MAX;
       XP_CHAR* p;
       p = Concat(crashEventPath, eventsDirectory, &size);
       p = Concat(p, XP_PATH_SEPARATOR, &size);
 #ifdef XP_LINUX
       p = Concat(p, id_ascii, &size);
 #else
       p = Concat(p, minidump_id, &size);
 #endif
@@ -1005,20 +1137,18 @@ bool MinidumpCallback(
 
     if (timeSinceLastCrash != 0) {
       WriteAnnotation(apiData, "SecondsSinceLastCrash",
                       timeSinceLastCrashString);
       WriteAnnotation(eventFile, "SecondsSinceLastCrash",
                       timeSinceLastCrashString);
     }
     if (isGarbageCollecting) {
-      WriteAnnotation(apiData, "IsGarbageCollecting",
-                      isGarbageCollecting ? "1" : "0");
-      WriteAnnotation(eventFile, "IsGarbageCollecting",
-                      isGarbageCollecting ? "1" : "0");
+      WriteAnnotation(apiData, "IsGarbageCollecting", "1");
+      WriteAnnotation(eventFile, "IsGarbageCollecting", "1");
     }
 
     char buffer[128];
 
     if (eventloopNestingLevel > 0) {
       XP_STOA(eventloopNestingLevel, buffer, 10);
       WriteAnnotation(apiData, "EventLoopNestingLevel", buffer);
       WriteAnnotation(eventFile, "EventLoopNestingLevel", buffer);
@@ -1074,118 +1204,32 @@ bool MinidumpCallback(
     }
 
     if (memoryReportPath) {
       WriteLiteral(apiData, "ContainsMemoryReport=1\n");
       WriteLiteral(eventFile, "ContainsMemoryReport=1\n");
     }
   }
 
+  if (!doReport) {
 #ifdef XP_WIN
-  if (!doReport) {
     TerminateProcess(GetCurrentProcess(), 1);
-    return returnValue;
-  }
-
-  XP_CHAR cmdLine[CMDLINE_SIZE];
-  size = CMDLINE_SIZE;
-  p = Concat(cmdLine, L"\"", &size);
-  p = Concat(p, crashReporterPath, &size);
-  p = Concat(p, L"\" \"", &size);
-  p = Concat(p, minidumpPath, &size);
-  Concat(p, L"\"", &size);
-
-  STARTUPINFO si;
-  PROCESS_INFORMATION pi;
-
-  ZeroMemory(&si, sizeof(si));
-  si.cb = sizeof(si);
-  si.dwFlags = STARTF_USESHOWWINDOW;
-  si.wShowWindow = SW_SHOWNORMAL;
-  ZeroMemory(&pi, sizeof(pi));
-
-  if (CreateProcess(nullptr, (LPWSTR)cmdLine, nullptr, nullptr, FALSE, 0,
-                    nullptr, nullptr, &si, &pi)) {
-    CloseHandle( pi.hProcess );
-    CloseHandle( pi.hThread );
-  }
-  // we're not really in a position to do anything if the CreateProcess fails
-  TerminateProcess(GetCurrentProcess(), 1);
-#elif defined(XP_UNIX)
-  if (!doReport) {
+#endif // XP_WIN
     return returnValue;
   }
 
-#ifdef XP_MACOSX
-  char* const my_argv[] = {
-    crashReporterPath,
-    minidumpPath,
-    nullptr
-  };
-
-  char **env = nullptr;
-  char ***nsEnv = _NSGetEnviron();
-  if (nsEnv)
-    env = *nsEnv;
-  int result = posix_spawnp(nullptr,
-                            my_argv[0],
-                            nullptr,
-                            &spawnattr,
-                            my_argv,
-                            env);
-
-  if (result != 0)
-    return false;
-
-#else // !XP_MACOSX
-  pid_t pid = sys_fork();
-
-  if (pid == -1)
-    return false;
-  else if (pid == 0) {
-#if !defined(MOZ_WIDGET_ANDROID)
-    // need to clobber this, as libcurl might load NSS,
-    // and we want it to load the system NSS.
-    unsetenv("LD_LIBRARY_PATH");
-    Unused << execl(crashReporterPath,
-                    crashReporterPath, minidumpPath, (char*)0);
-#else
-    // Invoke the reportCrash activity using am
-    if (androidUserSerial) {
-      Unused << execlp("/system/bin/am",
-                       "/system/bin/am",
-                       "start",
-                       "--user", androidUserSerial,
-                       "-a", "org.mozilla.gecko.reportCrash",
-                       "-n", crashReporterPath,
-                       "--es", "minidumpPath", minidumpPath,
-                       "--ez", "minidumpSuccess", succeeded ? "true" : "false",
-                       (char*)0);
-    } else {
-      Unused << execlp("/system/bin/am",
-                       "/system/bin/am",
-                       "start",
-                       "-a", "org.mozilla.gecko.reportCrash",
-                       "-n", crashReporterPath,
-                       "--es", "minidumpPath", minidumpPath,
-                       "--ez", "minidumpSuccess", succeeded ? "true" : "false",
-                       (char*)0);
-    }
+#if defined(MOZ_WIDGET_ANDROID) // Android
+  returnValue = LaunchCrashReporterActivity(crashReporterPath, minidumpPath,
+                                            succeeded);
+#else // Windows, Mac, Linux, etc...
+  returnValue = LaunchProgram(crashReporterPath, minidumpPath);
+#ifdef XP_WIN
+  TerminateProcess(GetCurrentProcess(), 1);
 #endif
-    _exit(1);
-#ifdef MOZ_WIDGET_ANDROID
-  } else {
-    // We need to wait on the 'am start' command above to finish, otherwise everything will
-    // be killed by the ActivityManager as soon as the signal handler exits
-    int status;
-    Unused << HANDLE_EINTR(sys_waitpid(pid, &status, __WALL));
 #endif
-  }
-#endif // XP_MACOSX
-#endif // XP_UNIX
 
   return returnValue;
 }
 
 #if defined(XP_MACOSX) || defined(__ANDROID__) || defined(XP_LINUX)
 static size_t
 EnsureTrailingSlash(XP_CHAR* aBuf, size_t aBufLen)
 {
@@ -1250,32 +1294,32 @@ BuildTempPath(char* aBuf, size_t aBufLen
 static size_t
 BuildTempPath(char* aBuf, size_t aBufLen)
 {
   // GeckoAppShell or Gonk's init.rc sets this in the environment
   const char *tempenv = PR_GetEnv("TMPDIR");
   if (!tempenv) {
     return false;
   }
-  int size = (int)aBufLen;
+  size_t size = aBufLen;
   Concat(aBuf, tempenv, &size);
   return EnsureTrailingSlash(aBuf, aBufLen);
 }
 
 #elif defined(XP_UNIX)
 
 static size_t
 BuildTempPath(char* aBuf, size_t aBufLen)
 {
   const char *tempenv = PR_GetEnv("TMPDIR");
   const char *tmpPath = "/tmp/";
   if (!tempenv) {
     tempenv = tmpPath;
   }
-  int size = (int)aBufLen;
+  size_t size = aBufLen;
   Concat(aBuf, tempenv, &size);
   return EnsureTrailingSlash(aBuf, aBufLen);
 }
 
 #else
 #error "Implement this for your platform"
 #endif
 
@@ -1302,17 +1346,17 @@ BuildTempPath(PathStringT& aResult)
 
 static void
 PrepareChildExceptionTimeAnnotations()
 {
   MOZ_ASSERT(!XRE_IsParentProcess());
   static XP_CHAR tempPath[XP_PATH_MAX] = {0};
 
   // Get the temp path
-  int charsAvailable = XP_PATH_MAX;
+  size_t charsAvailable = XP_PATH_MAX;
   XP_CHAR* p = tempPath;
 #if (defined(XP_MACOSX) || defined(XP_WIN))
   if (!childProcessTmpDir || childProcessTmpDir->empty()) {
     return;
   }
   p = Concat(p, childProcessTmpDir->c_str(), &charsAvailable);
   // Ensure that this path ends with a path separator
   if (p > tempPath && *(p - 1) != XP_PATH_SEPARATOR_CHAR) {