[Lldb-commits] [lldb] r346571 - Enable listening for EXC_RESOURCE events, and format mach

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Fri Nov 9 16:14:14 PST 2018


Author: jmolenda
Date: Fri Nov  9 16:14:14 2018
New Revision: 346571

URL: http://llvm.org/viewvc/llvm-project?rev=346571&view=rev
Log:
Enable listening for EXC_RESOURCE events, and format mach
event as a thread stop reason if we receive one, using 
some macros to decode the payload.  

Patch originally written by Fred Riss, with a few small changes
by myself.

Writing a test for this is a little tricky because the 
mach exception data interpretation relies on header macros
or function calls - it may change over time and writing
a gdb_remote_client test for this would break as older 
encoding interpretation is changed.  I'll tak with Fred
about this more, but neither of us has been thrilled with
the kind of tests we could write for it.

<rdar://problem/13097323>, <rdar://problem/40144456> 

Modified:
    lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachException.cpp

Modified: lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp?rev=346571&r1=346570&r2=346571&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp Fri Nov  9 16:14:14 2018
@@ -10,6 +10,8 @@
 #include "StopInfoMachException.h"
 
 // C Includes
+#include <kern/exc_resource.h>
+
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
@@ -41,6 +43,10 @@ const char *StopInfoMachException::GetDe
     const char *code_desc = NULL;
     const char *subcode_label = "subcode";
     const char *subcode_desc = NULL;
+
+    char code_desc_buf[32];
+    char subcode_desc_buf[32];
+
     switch (m_value) {
     case 1: // EXC_BAD_ACCESS
       exc_desc = "EXC_BAD_ACCESS";
@@ -275,6 +281,45 @@ const char *StopInfoMachException::GetDe
       break;
     case 11:
       exc_desc = "EXC_RESOURCE";
+      {
+        int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code);
+
+        code_label = "limit";
+        code_desc = code_desc_buf;
+        subcode_label = "observed";
+        subcode_desc = subcode_desc_buf;
+
+        switch (resource_type) {
+        case RESOURCE_TYPE_CPU:
+          exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU";
+          snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%",
+            (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code));
+          snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%",
+            (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(m_exc_subcode));
+          break;
+        case RESOURCE_TYPE_WAKEUPS:
+          exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS";
+          snprintf(code_desc_buf, sizeof(code_desc_buf), "%d w/s",
+            (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code));
+          snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s",
+            (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(m_exc_subcode));
+          break;
+        case RESOURCE_TYPE_MEMORY:
+          exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY";
+          snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
+            (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code));
+          subcode_desc = nullptr;
+          subcode_label = "unused";
+          break;
+        case RESOURCE_TYPE_IO:
+          exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO";
+          snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
+            (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code));
+          snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB",
+            (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));;
+          break;
+        }
+      }
       break;
     case 12:
       exc_desc = "EXC_GUARD";

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachException.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachException.cpp?rev=346571&r1=346570&r2=346571&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachException.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachException.cpp Fri Nov  9 16:14:14 2018
@@ -386,24 +386,29 @@ void MachException::Data::Dump() const {
   }
 }
 
-#define PREV_EXC_MASK_ALL                                                      \
-  (EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC |      \
-   EXC_MASK_EMULATION | EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT |              \
-   EXC_MASK_SYSCALL | EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT |             \
-   EXC_MASK_MACHINE)
+// The EXC_MASK_ALL value hard-coded here so that lldb can be built
+// on a new OS with an older deployment target .  The new OS may have
+// an addition to its EXC_MASK_ALL that the old OS will not recognize -
+// <mach/exception_types.h> doesn't vary the value based on the deployment
+// target.  So we need a known set of masks that can be assumed to be
+// valid when running on an older OS.  We'll fall back to trying
+// PREV_EXC_MASK_ALL if the EXC_MASK_ALL value lldb was compiled with is
+// not recognized.
+
+#define PREV_EXC_MASK_ALL (EXC_MASK_BAD_ACCESS |                \
+                         EXC_MASK_BAD_INSTRUCTION |             \
+                         EXC_MASK_ARITHMETIC |                  \
+                         EXC_MASK_EMULATION |                   \
+                         EXC_MASK_SOFTWARE |                    \
+                         EXC_MASK_BREAKPOINT |                  \
+                         EXC_MASK_SYSCALL |                     \
+                         EXC_MASK_MACH_SYSCALL |                \
+                         EXC_MASK_RPC_ALERT |                   \
+                         EXC_MASK_RESOURCE |                    \
+                         EXC_MASK_GUARD |                       \
+                         EXC_MASK_MACHINE)
 
-// Don't listen for EXC_RESOURCE, it should really get handled by the system
-// handler.
-
-#ifndef EXC_RESOURCE
-#define EXC_RESOURCE 11
-#endif
-
-#ifndef EXC_MASK_RESOURCE
-#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE)
-#endif
-
-#define LLDB_EXC_MASK (EXC_MASK_ALL & ~EXC_MASK_RESOURCE)
+#define LLDB_EXC_MASK EXC_MASK_ALL
 
 kern_return_t MachException::PortInfo::Save(task_t task) {
   DNBLogThreadedIf(LOG_EXCEPTIONS | LOG_VERBOSE,
@@ -485,9 +490,21 @@ const char *MachException::Name(exceptio
     return "EXC_MACH_SYSCALL";
   case EXC_RPC_ALERT:
     return "EXC_RPC_ALERT";
-#ifdef EXC_CRASH
   case EXC_CRASH:
     return "EXC_CRASH";
+  case EXC_RESOURCE:
+    return "EXC_RESOURCE";
+#ifdef EXC_GUARD
+  case EXC_GUARD:
+    return "EXC_GUARD";
+#endif
+#ifdef EXC_CORPSE_NOTIFY
+  case EXC_CORPSE_NOTIFY:
+    return "EXC_CORPSE_NOTIFY";
+#endif
+#ifdef EXC_CORPSE_VARIANT_BIT
+  case EXC_CORPSE_VARIANT_BIT:
+    return "EXC_CORPSE_VARIANT_BIT";
 #endif
   default:
     break;




More information about the lldb-commits mailing list