Read Linux si_code in minidump_processor.

For common signals: SIGILL, SIGFPE, SIGSEGV, and SIGBUS.

Change-Id: I80048f70445c3fa6accd548704c5700b3bed12a4
Reviewed-on: https://chromium-review.googlesource.com/1012589
Reviewed-by: Robert Sesek <rsesek@chromium.org>
diff --git a/src/google_breakpad/common/minidump_exception_linux.h b/src/google_breakpad/common/minidump_exception_linux.h
index 9e7e4f1..6138d5d 100644
--- a/src/google_breakpad/common/minidump_exception_linux.h
+++ b/src/google_breakpad/common/minidump_exception_linux.h
@@ -84,4 +84,42 @@
                                                        dump requested. */
 } MDExceptionCodeLinux;
 
+/* For (MDException).exception_flags.  These values come from
+ * asm-generic/siginfo.h.
+ */
+typedef enum {
+  /* SIGILL */
+  MD_EXCEPTION_FLAG_LIN_ILL_ILLOPC = 1,
+  MD_EXCEPTION_FLAG_LIN_ILL_ILLOPN = 2,
+  MD_EXCEPTION_FLAG_LIN_ILL_ILLADR = 3,
+  MD_EXCEPTION_FLAG_LIN_ILL_ILLTRP = 4,
+  MD_EXCEPTION_FLAG_LIN_ILL_PRVOPC = 5,
+  MD_EXCEPTION_FLAG_LIN_ILL_PRVREG = 6,
+  MD_EXCEPTION_FLAG_LIN_ILL_COPROC = 7,
+  MD_EXCEPTION_FLAG_LIN_ILL_BADSTK = 8,
+
+  /* SIGFPE */
+  MD_EXCEPTION_FLAG_LIN_FPE_INTDIV = 1,
+  MD_EXCEPTION_FLAG_LIN_FPE_INTOVF = 2,
+  MD_EXCEPTION_FLAG_LIN_FPE_FLTDIV = 3,
+  MD_EXCEPTION_FLAG_LIN_FPE_FLTOVF = 4,
+  MD_EXCEPTION_FLAG_LIN_FPE_FLTUND = 5,
+  MD_EXCEPTION_FLAG_LIN_FPE_FLTRES = 6,
+  MD_EXCEPTION_FLAG_LIN_FPE_FLTINV = 7,
+  MD_EXCEPTION_FLAG_LIN_FPE_FLTSUB = 8,
+
+  /* SIGSEGV */
+  MD_EXCEPTION_FLAG_LIN_SEGV_MAPERR = 1,
+  MD_EXCEPTION_FLAG_LIN_SEGV_ACCERR = 2,
+  MD_EXCEPTION_FLAG_LIN_SEGV_BNDERR = 3,
+  MD_EXCEPTION_FLAG_LIN_SEGV_PKUERR = 4,
+
+  /* SIGBUS */
+  MD_EXCEPTION_FLAG_LIN_BUS_ADRALN = 1,
+  MD_EXCEPTION_FLAG_LIN_BUS_ADRERR = 2,
+  MD_EXCEPTION_FLAG_LIN_BUS_OBJERR = 3,
+  MD_EXCEPTION_FLAG_LIN_BUS_MCEERR_AR = 4,
+  MD_EXCEPTION_FLAG_LIN_BUS_MCEERR_AO = 5,
+} MDExceptionFlagLinux;
+
 #endif  /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_EXCEPTION_LINUX_H__ */
diff --git a/src/processor/minidump_processor.cc b/src/processor/minidump_processor.cc
index f2360e6..2fe4fee 100644
--- a/src/processor/minidump_processor.cc
+++ b/src/processor/minidump_processor.cc
@@ -1218,6 +1218,8 @@
 
     case MD_OS_ANDROID:
     case MD_OS_LINUX: {
+      char flags_string[11];
+      snprintf(flags_string, sizeof(flags_string), "0x%08x", exception_flags);
       switch (exception_code) {
         case MD_EXCEPTION_CODE_LIN_SIGHUP:
           reason = "SIGHUP";
@@ -1229,7 +1231,37 @@
           reason = "SIGQUIT";
           break;
         case MD_EXCEPTION_CODE_LIN_SIGILL:
-          reason = "SIGILL";
+          reason = "SIGILL / ";
+          switch (exception_flags) {
+            case MD_EXCEPTION_FLAG_LIN_ILL_ILLOPC:
+              reason.append("ILL_ILLOPC");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_ILL_ILLOPN:
+              reason.append("ILL_ILLOPN");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_ILL_ILLADR:
+              reason.append("ILL_ILLADR");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_ILL_ILLTRP:
+              reason.append("ILL_ILLTRP");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_ILL_PRVOPC:
+              reason.append("ILL_PRVOPC");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_ILL_PRVREG:
+              reason.append("ILL_PRVREG");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_ILL_COPROC:
+              reason.append("ILL_COPROC");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_ILL_BADSTK:
+              reason.append("ILL_BADSTK");
+              break;
+            default:
+              reason.append(flags_string);
+              BPLOG(INFO) << "Unknown exception reason " << reason;
+              break;
+          }
           break;
         case MD_EXCEPTION_CODE_LIN_SIGTRAP:
           reason = "SIGTRAP";
@@ -1238,10 +1270,61 @@
           reason = "SIGABRT";
           break;
         case MD_EXCEPTION_CODE_LIN_SIGBUS:
-          reason = "SIGBUS";
+          reason = "SIGBUS / ";
+          switch (exception_flags) {
+            case MD_EXCEPTION_FLAG_LIN_BUS_ADRALN:
+              reason.append("BUS_ADALN");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_BUS_ADRERR:
+              reason.append("BUS_ADRERR");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_BUS_OBJERR:
+              reason.append("BUS_OBJERR");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_BUS_MCEERR_AR:
+              reason.append("BUS_MCEERR_AR");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_BUS_MCEERR_AO:
+              reason.append("BUS_MCEERR_AO");
+              break;
+            default:
+              reason.append(flags_string);
+              BPLOG(INFO) << "Unknown exception reason " << reason;
+              break;
+          }
           break;
         case MD_EXCEPTION_CODE_LIN_SIGFPE:
-          reason = "SIGFPE";
+          reason = "SIGFPE / ";
+          switch (exception_flags) {
+            case MD_EXCEPTION_FLAG_LIN_FPE_INTDIV:
+              reason.append("FPE_INTDIV");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_FPE_INTOVF:
+              reason.append("FPE_INTOVF");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_FPE_FLTDIV:
+              reason.append("FPE_FLTDIV");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_FPE_FLTOVF:
+              reason.append("FPE_FLTOVF");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_FPE_FLTUND:
+              reason.append("FPE_FLTUND");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_FPE_FLTRES:
+              reason.append("FPE_FLTRES");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_FPE_FLTINV:
+              reason.append("FPE_FLTINV");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_FPE_FLTSUB:
+              reason.append("FPE_FLTSUB");
+              break;
+            default:
+              reason.append(flags_string);
+              BPLOG(INFO) << "Unknown exception reason " << reason;
+              break;
+          }
           break;
         case MD_EXCEPTION_CODE_LIN_SIGKILL:
           reason = "SIGKILL";
@@ -1250,7 +1333,25 @@
           reason = "SIGUSR1";
           break;
         case MD_EXCEPTION_CODE_LIN_SIGSEGV:
-          reason = "SIGSEGV";
+          reason = "SIGSEGV /";
+          switch (exception_flags) {
+            case MD_EXCEPTION_FLAG_LIN_SEGV_MAPERR:
+              reason.append("SEGV_MAPERR");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_SEGV_ACCERR:
+              reason.append("SEGV_ACCERR");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_SEGV_BNDERR:
+              reason.append("SEGV_BNDERR");
+              break;
+            case MD_EXCEPTION_FLAG_LIN_SEGV_PKUERR:
+              reason.append("SEGV_PKUERR");
+              break;
+            default:
+              reason.append(flags_string);
+              BPLOG(INFO) << "Unknown exception reason " << reason;
+              break;
+          }
           break;
         case MD_EXCEPTION_CODE_LIN_SIGUSR2:
           reason = "SIGUSR2";