Bug 1289561 - Implement LSB release annotation in crash reports. r=jrmuizel
authorAndrew Comminos <andrew@comminos.com>
Tue, 26 Jul 2016 14:23:47 -0400
changeset 338809 de07c5af9cc8975d82cbb5dde8cd2a64dc3d8b42
parent 338808 3a0a2331334c5f5734f1fd4769c9fcc0b0b3709d
child 338810 603abe52e6879bb81d5274c91d3808e892598fd4
push id4
push userfmarier@mozilla.com
push dateSat, 20 Aug 2016 00:14:13 +0000
reviewersjrmuizel
bugs1289561
milestone51.0a1
Bug 1289561 - Implement LSB release annotation in crash reports. r=jrmuizel MozReview-Commit-ID: IEcH6K5D27H
toolkit/xre/nsAppRunner.cpp
widget/LSBUtils.cpp
widget/LSBUtils.h
widget/moz.build
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -197,16 +197,17 @@
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "GeneratedJNIWrappers.h"
 #endif
 
 #if defined(MOZ_SANDBOX)
 #if defined(XP_LINUX) && !defined(ANDROID)
 #include "mozilla/SandboxInfo.h"
+#include "mozilla/widget/LSBUtils.h"
 #elif defined(XP_WIN)
 #include "SandboxBroker.h"
 #endif
 #endif
 
 extern uint32_t gRestartMode;
 extern void InstallSignalHandlers(const char *ProgramName);
 
@@ -3479,17 +3480,31 @@ static void PR_CALLBACK AnnotateSystemMa
   if (FAILED(hr)) {
     return;
   }
 
   AnnotateSystemManufacturer();
 
   CoUninitialize();
 }
-#endif
+#endif // XP_WIN
+
+#if defined(XP_LINUX) && !defined(ANDROID)
+
+static void
+AnnotateLSBRelease(void*)
+{
+  nsCString dist, desc, release, codename;
+  if (widget::lsb::GetLSBRelease(dist, desc, release, codename)) {
+    CrashReporter::AppendAppNotesToCrashReport(desc);
+  }
+}
+
+#endif // defined(XP_LINUX) && !defined(ANDROID)
+
 #endif
 
 namespace mozilla {
   ShutdownChecksMode gShutdownChecks = SCM_NOTHING;
 } // namespace mozilla
 
 static void SetShutdownChecks() {
   // Set default first. On debug builds we crash. On nightly and local
@@ -3995,16 +4010,21 @@ XREMain::XRE_mainRun()
   CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonSize"),
                                      nsPrintfCString("%lu", uint32_t(gMozillaPoisonSize)));
 
 #ifdef XP_WIN
   PR_CreateThread(PR_USER_THREAD, AnnotateSystemManufacturer_ThreadStart, 0,
                   PR_PRIORITY_LOW, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
 #endif
 
+#if defined(XP_LINUX) && !defined(ANDROID)
+  PR_CreateThread(PR_USER_THREAD, AnnotateLSBRelease, 0, PR_PRIORITY_LOW,
+                  PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+#endif
+
 #endif
 
   if (mStartOffline) {
     nsCOMPtr<nsIIOService2> io (do_GetService("@mozilla.org/network/io-service;1"));
     NS_ENSURE_TRUE(io, NS_ERROR_FAILURE);
     io->SetManageOfflineStatus(false);
     io->SetOffline(true);
   }
new file mode 100644
--- /dev/null
+++ b/widget/LSBUtils.cpp
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "LSBUtils.h"
+
+#include <unistd.h>
+#include "base/process_util.h"
+
+namespace mozilla {
+namespace widget {
+namespace lsb {
+
+static const char* gLsbReleasePath = "/usr/bin/lsb_release";
+
+bool
+GetLSBRelease(nsACString& aDistributor,
+              nsACString& aDescription,
+              nsACString& aRelease,
+              nsACString& aCodename)
+{
+  if (access(gLsbReleasePath, R_OK) != 0)
+    return false;
+
+  int pipefd[2];
+  if (pipe(pipefd) == -1) {
+    NS_WARNING("pipe() failed!");
+    return false;
+  }
+
+  std::vector<std::string> argv = {
+    gLsbReleasePath, "-idrc"
+  };
+
+  std::vector<std::pair<int, int>> fdMap = {
+    { pipefd[1], STDOUT_FILENO }
+  };
+
+  base::ProcessHandle process;
+  base::LaunchApp(argv, fdMap, true, &process);
+  close(pipefd[1]);
+  if (!process) {
+    NS_WARNING("Failed to spawn lsb_release!");
+    close(pipefd[0]);
+    return false;
+  }
+
+  FILE* stream = fdopen(pipefd[0], "r");
+  if (!stream) {
+    NS_WARNING("Could not wrap fd!");
+    close(pipefd[0]);
+    return false;
+  }
+
+  char dist[256], desc[256], release[256], codename[256];
+  if (fscanf(stream, "Distributor ID:\t%255[^\n]\n"
+                     "Description:\t%255[^\n]\n"
+                     "Release:\t%255[^\n]\n"
+                     "Codename:\t%255[^\n]\n",
+             dist, desc, release, codename) != 4)
+  {
+    NS_WARNING("Failed to parse lsb_release!");
+    fclose(stream);
+    close(pipefd[0]);
+    return false;
+  }
+  fclose(stream);
+  close(pipefd[0]);
+
+  aDistributor.Assign(dist);
+  aDescription.Assign(desc);
+  aRelease.Assign(release);
+  aCodename.Assign(codename);
+  return true;
+}
+
+}  // namespace lsb
+}  // namespace widget
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/widget/LSBUtils.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _MOZILLA_WIDGET_LSB_UTILS_H
+#define _MOZILLA_WIDGET_LSB_UTILS_H
+
+#include "nsString.h"
+
+namespace mozilla {
+namespace widget {
+namespace lsb {
+
+// Fetches the LSB release data by parsing the lsb_release command.
+// Returns false if the lsb_release command was not found, or parsing failed.
+bool GetLSBRelease(nsACString& aDistributor,
+                   nsACString& aDescription,
+                   nsACString& aRelease,
+                   nsACString& aCodename);
+
+
+}  // namespace lsb
+}  // namespace widget
+}  // namespace mozilla
+
+#endif // _MOZILLA_WIDGET_LSB_UTILS_H
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -168,16 +168,24 @@ UNIFIED_SOURCES += [
     'ScreenProxy.cpp',
     'SharedWidgetUtils.cpp',
     'TextEventDispatcher.cpp',
     'VsyncDispatcher.cpp',
     'WidgetEventImpl.cpp',
     'WidgetUtils.cpp',
 ]
 
+if CONFIG['OS_ARCH'] == 'Linux':
+    EXPORTS.mozilla.widget += [
+        'LSBUtils.h'
+    ]
+    SOURCES += [
+        'LSBUtils.cpp'
+    ]
+
 if CONFIG['MOZ_XUL'] and CONFIG['NS_PRINTING']:
     EXPORTS += [
         'nsDeviceContextSpecProxy.h',
         'nsPrintOptionsImpl.h',
     ]
     UNIFIED_SOURCES += [
         'nsDeviceContextSpecProxy.cpp',
         'nsPrintOptionsImpl.cpp',