[Lldb-commits] [lldb] bff4673 - Add a darwin platform setting to specify which exceptions debugserver

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Wed May 18 10:16:19 PDT 2022


Author: Jim Ingham
Date: 2022-05-18T10:16:11-07:00
New Revision: bff4673b41781ec5bff6b96b52cf321d2271726c

URL: https://github.com/llvm/llvm-project/commit/bff4673b41781ec5bff6b96b52cf321d2271726c
DIFF: https://github.com/llvm/llvm-project/commit/bff4673b41781ec5bff6b96b52cf321d2271726c.diff

LOG: Add a darwin platform setting to specify which exceptions debugserver
should not receive as exceptions (some will get converted to BSD
signals instead).  This is really the only stable way to ensure that
a Mach exception gets converted to it's equivalent BSD signal.  For
programs that rely on BSD signal handlers, this has to happen or you
can't even get the program to invoke the signal handler when under
the debugger.

This builds on a previous solution to this problem which required you
start debugserver with the -U flag.  This was not very discoverable
and required lldb be the one to launch debugserver, which is not always
the case.

Differential Revision: https://reviews.llvm.org/D125434

Added: 
    lldb/test/API/macosx/ignore_exceptions/Makefile
    lldb/test/API/macosx/ignore_exceptions/TestIgnoredExceptions.py
    lldb/test/API/macosx/ignore_exceptions/main.c

Modified: 
    lldb/include/lldb/Interpreter/OptionValueString.h
    lldb/include/lldb/Target/Platform.h
    lldb/include/lldb/Utility/StringExtractorGDBRemote.h
    lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
    lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td
    lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/source/Target/Platform.cpp
    lldb/source/Utility/StringExtractorGDBRemote.cpp
    lldb/tools/debugserver/source/DNB.cpp
    lldb/tools/debugserver/source/DNB.h
    lldb/tools/debugserver/source/MacOSX/MachException.cpp
    lldb/tools/debugserver/source/MacOSX/MachException.h
    lldb/tools/debugserver/source/MacOSX/MachProcess.h
    lldb/tools/debugserver/source/MacOSX/MachProcess.mm
    lldb/tools/debugserver/source/MacOSX/MachTask.h
    lldb/tools/debugserver/source/MacOSX/MachTask.mm
    lldb/tools/debugserver/source/RNBContext.cpp
    lldb/tools/debugserver/source/RNBContext.h
    lldb/tools/debugserver/source/RNBRemote.cpp
    lldb/tools/debugserver/source/RNBRemote.h
    lldb/tools/debugserver/source/debugserver.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Interpreter/OptionValueString.h b/lldb/include/lldb/Interpreter/OptionValueString.h
index be42deb80da77..820656d19e2cb 100644
--- a/lldb/include/lldb/Interpreter/OptionValueString.h
+++ b/lldb/include/lldb/Interpreter/OptionValueString.h
@@ -109,6 +109,11 @@ class OptionValueString : public Cloneable<OptionValueString, OptionValue> {
   bool IsCurrentValueEmpty() const { return m_current_value.empty(); }
 
   bool IsDefaultValueEmpty() const { return m_default_value.empty(); }
+  
+  void SetValidator(ValidatorCallback validator, void *baton = nullptr) {
+    m_validator = validator;
+    m_validator_baton = baton;
+  }
 
 protected:
   std::string m_current_value;

diff  --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 8b8ca6268071f..603200820478c 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -847,6 +847,8 @@ class Platform : public PluginInterface {
   }
 
   virtual CompilerType GetSiginfoType(const llvm::Triple &triple);
+  
+  virtual Args GetExtraStartupCommands();
 
 protected:
   /// Create a list of ArchSpecs with the given OS and a architectures. The

diff  --git a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
index 459adae044526..f10bfb14e2b55 100644
--- a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
+++ b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
@@ -174,6 +174,7 @@ class StringExtractorGDBRemote : public StringExtractor {
     eServerPacketType_QMemTags, // write memory tags
 
     eServerPacketType_qLLDBSaveCore,
+    eServerPacketType_QSetIgnoredExceptions
   };
 
   ServerPacketType GetServerPacketType() const;

diff  --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index cac9c672afb4c..455b760cb27a9 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -19,11 +19,15 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Host/XML.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/Options.h"
 #include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolFile.h"
@@ -48,12 +52,137 @@
 using namespace lldb;
 using namespace lldb_private;
 
+static Status ExceptionMaskValidator(const char *string, void *unused) {
+  Status error;
+  llvm::StringRef str_ref(string);
+  llvm::SmallVector<llvm::StringRef> candidates;
+  str_ref.split(candidates, '|');
+  for (auto candidate : candidates) {
+    if (!(candidate == "EXC_BAD_ACCESS"
+          || candidate == "EXC_BAD_INSTRUCTION"
+          || candidate == "EXC_ARITHMETIC"
+          || candidate == "EXC_RESOURCE"
+          || candidate == "EXC_GUARD")) {
+      error.SetErrorStringWithFormat("invalid exception type: '%s'", 
+          candidate.str().c_str());
+      return error;
+    }
+  }
+  return {};
+}
+
 /// Destructor.
 ///
 /// The destructor is virtual since this class is designed to be
 /// inherited from by the plug-in instance.
 PlatformDarwin::~PlatformDarwin() = default;
 
+// Static Variables
+static uint32_t g_initialize_count = 0;
+
+void PlatformDarwin::Initialize() {
+  Platform::Initialize();
+
+  if (g_initialize_count++ == 0) {
+    PluginManager::RegisterPlugin(PlatformDarwin::GetPluginNameStatic(),
+                                  PlatformDarwin::GetDescriptionStatic(),
+                                  PlatformDarwin::CreateInstance,
+                                  PlatformDarwin::DebuggerInitialize);
+  }
+}
+
+void PlatformDarwin::Terminate() {
+  if (g_initialize_count > 0) {
+    if (--g_initialize_count == 0) {
+      PluginManager::UnregisterPlugin(PlatformDarwin::CreateInstance);
+    }
+  }
+
+  Platform::Terminate();
+}
+
+llvm::StringRef PlatformDarwin::GetDescriptionStatic() {
+  return "Darwin platform plug-in.";
+}
+
+PlatformSP PlatformDarwin::CreateInstance(bool force, const ArchSpec *arch) {
+   // We only create subclasses of the PlatformDarwin plugin.
+   return PlatformSP();
+}
+
+#define LLDB_PROPERTIES_platformdarwin
+#include "PlatformMacOSXProperties.inc"
+
+#define LLDB_PROPERTIES_platformdarwin
+enum {
+#include "PlatformMacOSXPropertiesEnum.inc"
+};
+
+class PlatformDarwinProperties : public Properties {
+public:
+  static ConstString &GetSettingName() {
+    static ConstString g_setting_name("darwin");
+    return g_setting_name;
+  }
+
+  PlatformDarwinProperties() : Properties() {
+    m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
+    m_collection_sp->Initialize(g_platformdarwin_properties);
+  }
+
+  ~PlatformDarwinProperties() override = default;
+
+  const char *GetIgnoredExceptions() const {
+    const uint32_t idx = ePropertyIgnoredExceptions;
+    const OptionValueString *option_value =
+        m_collection_sp->GetPropertyAtIndexAsOptionValueString(
+            NULL, false, idx);
+    assert(option_value);
+    return option_value->GetCurrentValue();
+  }
+    
+  OptionValueString *GetIgnoredExceptionValue() {
+    const uint32_t idx = ePropertyIgnoredExceptions;
+    OptionValueString *option_value =
+        m_collection_sp->GetPropertyAtIndexAsOptionValueString(
+            NULL, false, idx);
+    assert(option_value);
+    return option_value;
+  }
+};
+
+static PlatformDarwinProperties &GetGlobalProperties() {
+  static PlatformDarwinProperties g_settings;
+  return g_settings;
+}
+
+void PlatformDarwin::DebuggerInitialize(
+    lldb_private::Debugger &debugger) {
+  if (!PluginManager::GetSettingForPlatformPlugin(
+          debugger, PlatformDarwinProperties::GetSettingName())) {
+    const bool is_global_setting = false;
+    PluginManager::CreateSettingForPlatformPlugin(
+        debugger, GetGlobalProperties().GetValueProperties(),
+        ConstString("Properties for the Darwin platform plug-in."),
+        is_global_setting);
+    OptionValueString *value = GetGlobalProperties().GetIgnoredExceptionValue();
+    value->SetValidator(ExceptionMaskValidator);
+  }
+}
+
+Args
+PlatformDarwin::GetExtraStartupCommands() {
+  std::string ignored_exceptions 
+      = GetGlobalProperties().GetIgnoredExceptions();
+  if (ignored_exceptions.empty())
+    return {};
+  Args ret_args;
+  std::string packet = "QSetIgnoredExceptions:";
+  packet.append(ignored_exceptions);
+  ret_args.AppendArgument(packet);
+  return ret_args;
+}
+
 lldb_private::Status
 PlatformDarwin::PutFile(const lldb_private::FileSpec &source,
                         const lldb_private::FileSpec &destination, uint32_t uid,

diff  --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index b4c791e707a98..334410e91b4a2 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -48,6 +48,18 @@ class PlatformDarwin : public PlatformPOSIX {
 
   ~PlatformDarwin() override;
 
+  static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+
+  static void DebuggerInitialize(lldb_private::Debugger &debugger);
+  
+  static void Initialize();
+
+  static void Terminate();
+
+  static llvm::StringRef GetPluginNameStatic() { return "darwin"; }
+
+  static llvm::StringRef GetDescriptionStatic();
+
   Status PutFile(const FileSpec &source, const FileSpec &destination,
                  uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override;
 
@@ -96,6 +108,8 @@ class PlatformDarwin : public PlatformPOSIX {
   FileSpec LocateExecutable(const char *basename) override;
 
   Status LaunchProcess(ProcessLaunchInfo &launch_info) override;
+  
+  Args GetExtraStartupCommands() override;
 
   static std::tuple<llvm::VersionTuple, llvm::StringRef>
   ParseVersionBuildDir(llvm::StringRef str);

diff  --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td
index 39e9641daae04..f0d305a63085c 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td
@@ -5,3 +5,12 @@ let Definition = "platformdarwinkernel" in {
     DefaultStringValue<"">,
     Desc<"Directories/KDKs to search for kexts in when starting a kernel debug session.">;
 }
+
+let Definition = "platformdarwin" in {
+  def IgnoredExceptions: Property<"ignored-exceptions", "String">,
+    DefaultStringValue<"">,
+    Desc<"List the mach exceptions to ignore, separated by '|' "
+         "(e.g. 'EXC_BAD_ACCESS|EXC_BAD_INSTRUCTION'). "
+         "lldb will instead stop on the BSD signal the exception was converted "
+         "into, if there is one.">;
+}

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index f7e21882aabbc..a00961daf2755 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -954,12 +954,23 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
   m_gdb_comm.GetVAttachOrWaitSupported();
   m_gdb_comm.EnableErrorStringInPacket();
 
-  size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
-  for (size_t idx = 0; idx < num_cmds; idx++) {
-    StringExtractorGDBRemote response;
-    m_gdb_comm.SendPacketAndWaitForResponse(
-        GetExtraStartupCommands().GetArgumentAtIndex(idx), response);
+  // First dispatch any commands from the platform:
+  auto handle_cmds = [&] (const Args &args) ->  void {
+    for (const Args::ArgEntry &entry : args) {
+      StringExtractorGDBRemote response;
+      m_gdb_comm.SendPacketAndWaitForResponse(
+          entry.c_str(), response);
+    }
+  };
+  
+  PlatformSP platform_sp = GetTarget().GetPlatform();
+  if (platform_sp) {
+    handle_cmds(platform_sp->GetExtraStartupCommands());
   }
+  
+  // Then dispatch any process commands:
+  handle_cmds(GetExtraStartupCommands());
+
   return error;
 }
 

diff  --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 1976aa636a046..559f7664c72ef 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -1945,6 +1945,10 @@ CompilerType Platform::GetSiginfoType(const llvm::Triple& triple) {
   return CompilerType();
 }
 
+Args Platform::GetExtraStartupCommands() {
+  return {};
+}
+
 PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   for (const PlatformSP &platform_sp : m_platforms) {

diff  --git a/lldb/source/Utility/StringExtractorGDBRemote.cpp b/lldb/source/Utility/StringExtractorGDBRemote.cpp
index d6bbf7171916a..f1e54b35ee125 100644
--- a/lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ b/lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -126,6 +126,8 @@ StringExtractorGDBRemote::GetServerPacketType() const {
         return eServerPacketType_QSetWorkingDir;
       if (PACKET_STARTS_WITH("QSetLogging:"))
         return eServerPacketType_QSetLogging;
+      if (PACKET_STARTS_WITH("QSetIgnoredExceptions"))
+        return eServerPacketType_QSetIgnoredExceptions;
       if (PACKET_STARTS_WITH("QSetMaxPacketSize:"))
         return eServerPacketType_QSetMaxPacketSize;
       if (PACKET_STARTS_WITH("QSetMaxPayloadSize:"))

diff  --git a/lldb/test/API/macosx/ignore_exceptions/Makefile b/lldb/test/API/macosx/ignore_exceptions/Makefile
new file mode 100644
index 0000000000000..695335e068c0c
--- /dev/null
+++ b/lldb/test/API/macosx/ignore_exceptions/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c99
+
+include Makefile.rules

diff  --git a/lldb/test/API/macosx/ignore_exceptions/TestIgnoredExceptions.py b/lldb/test/API/macosx/ignore_exceptions/TestIgnoredExceptions.py
new file mode 100644
index 0000000000000..378ce7a7b6b01
--- /dev/null
+++ b/lldb/test/API/macosx/ignore_exceptions/TestIgnoredExceptions.py
@@ -0,0 +1,60 @@
+"""
+Test that by turning off EXC_BAD_ACCESS catching, we can
+debug into and out of a signal handler.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class TestDarwinSignalHandlers(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    NO_DEBUG_INFO_TESTCASE = True
+
+    @skipUnlessDarwin
+    def test_ignored_thread(self):
+        """It isn't possible to convert an EXC_BAD_ACCESS to a signal when
+        running under the debugger, which makes debugging SIGBUS handlers
+        and so forth 
diff icult.  This test sends QIgnoreExceptions and that
+        should get us into the signal handler and out again. """
+        self.build()
+        self.main_source_file = lldb.SBFileSpec("main.c")
+        self.suspended_thread_test()
+
+    def suspended_thread_test(self):
+        # Make sure that we don't accept bad values:
+        self.match("settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_AXESS", "EXC_BAD_AXESS", error=True)
+        # Now set ourselves to ignore some exceptions.  The test depends on ignoring EXC_BAD_ACCESS, but I passed a couple
+        # to make sure they parse:
+        self.runCmd("settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_ACCESS|EXC_ARITHMETIC")
+        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
+                                   "Stop here to get things going", self.main_source_file)
+
+        sig_bkpt = target.BreakpointCreateBySourceRegex("stop here in the signal handler",
+                                                        self.main_source_file)
+        self.assertEqual(sig_bkpt.GetNumLocations(), 1, "Found sig handler breakpoint")
+        return_bkpt = target.BreakpointCreateBySourceRegex("Break here to make sure we got past the signal handler",
+                                                        self.main_source_file)
+        self.assertEqual(return_bkpt.GetNumLocations(), 1, "Found return breakpoint")
+        # Now continue, and we should stop with a stop reason of SIGBUS:
+        process.Continue()
+        self.assertEqual(process.state, lldb.eStateStopped, "Stopped after continue to SIGBUS")
+        self.assertEqual(thread.stop_reason, lldb.eStopReasonSignal)
+        self.assertEqual(thread.GetStopReasonDataAtIndex(0), 10, "Got a SIGBUS")
+
+        # Now when we continue, we'll find our way into the signal handler:
+        threads = lldbutil.continue_to_breakpoint(process, sig_bkpt)
+        self.assertEqual(len(threads), 1, "Stopped at sig breakpoint")
+
+        threads = lldbutil.continue_to_breakpoint(process, return_bkpt)
+        self.assertEqual(len(threads), 1, "Stopped at return breakpoint")
+
+        # Make sure we really changed the value:
+        
+        process.Continue()
+        self.assertEqual(process.state, lldb.eStateExited, "Process exited")
+        self.assertEqual(process.exit_state, 20, "Got the right exit status")
+                         

diff  --git a/lldb/test/API/macosx/ignore_exceptions/main.c b/lldb/test/API/macosx/ignore_exceptions/main.c
new file mode 100644
index 0000000000000..7b89dbf88152b
--- /dev/null
+++ b/lldb/test/API/macosx/ignore_exceptions/main.c
@@ -0,0 +1,27 @@
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <stdio.h>
+
+int g_ints[] = {10, 20, 30, 40, 50, 60};
+
+void
+saction_handler(int signo, siginfo_t info, void *baton) {
+  printf("Got into handler.\n");
+  mprotect(g_ints, sizeof(g_ints), PROT_READ|PROT_WRITE); // stop here in the signal handler
+  g_ints[0] = 20;
+}
+int
+main()
+{
+  mprotect(g_ints, 10*sizeof(int) , PROT_NONE);
+  struct sigaction my_action;
+  sigemptyset(&my_action.sa_mask);
+  my_action.sa_handler = (void (*)(int)) saction_handler;
+  my_action.sa_flags = SA_SIGINFO;
+
+  sigaction(SIGBUS, &my_action, NULL); // Stop here to get things going.
+  int local_value = g_ints[1];
+  return local_value; // Break here to make sure we got past the signal handler
+}

diff  --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index c037c48c02868..ebb76074670b1 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -352,7 +352,7 @@ nub_process_t DNBProcessLaunch(
     pid_t pid = processSP->LaunchForDebug(
         path, argv, envp, working_directory, stdin_path, stdout_path,
         stderr_path, no_stdio, ctx->LaunchFlavor(), disable_aslr, event_data,
-        ctx->GetUnmaskSignals(), launch_err);
+        ctx->GetIgnoredExceptions(), launch_err);
     if (err_str) {
       *err_str = '\0';
       if (launch_err.Fail()) {
@@ -412,7 +412,8 @@ nub_process_t DNBProcessGetPIDByName(const char *name) {
 }
 
 nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
-                                     bool unmask_signals, char *err_str,
+                                     const RNBContext::IgnoredExceptions 
+                                             &ignored_exceptions, char *err_str,
                                      size_t err_len) {
   if (err_str && err_len > 0)
     err_str[0] = '\0';
@@ -434,11 +435,13 @@ nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
   }
 
   return DNBProcessAttach(matching_proc_infos[0].kp_proc.p_pid, timeout,
-                          unmask_signals, err_str, err_len);
+                          ignored_exceptions, err_str, err_len);
 }
 
 nub_process_t DNBProcessAttach(nub_process_t attach_pid,
-                               struct timespec *timeout, bool unmask_signals,
+                               struct timespec *timeout, 
+                               const RNBContext::IgnoredExceptions 
+                                       &ignored_exceptions,
                                char *err_str, size_t err_len) {
   if (err_str && err_len > 0)
     err_str[0] = '\0';
@@ -487,7 +490,8 @@ nub_process_t DNBProcessAttach(nub_process_t attach_pid,
     DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) attaching to pid %d...",
                      attach_pid);
     pid =
-        processSP->AttachForDebug(attach_pid, unmask_signals, err_str, err_len);
+        processSP->AttachForDebug(attach_pid, ignored_exceptions, err_str, 
+                                  err_len);
 
     if (pid != INVALID_NUB_PROCESS) {
       bool res = AddProcessToMap(pid, processSP);
@@ -782,7 +786,8 @@ DNBProcessAttachWait(RNBContext *ctx, const char *waitfor_process_name,
     DNBLogThreadedIf(LOG_PROCESS, "Attaching to %s with pid %i...\n",
                      waitfor_process_name, waitfor_pid);
     waitfor_pid = DNBProcessAttach(waitfor_pid, timeout_abstime,
-                                   ctx->GetUnmaskSignals(), err_str, err_len);
+                                   ctx->GetIgnoredExceptions(), err_str, 
+                                   err_len);
   }
 
   bool success = waitfor_pid != INVALID_NUB_PROCESS;

diff  --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h
index c04249d672611..f29078ce6c145 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -51,10 +51,14 @@ nub_process_t DNBProcessLaunch(
 
 nub_process_t DNBProcessGetPIDByName(const char *name);
 nub_process_t DNBProcessAttach(nub_process_t pid, struct timespec *timeout,
-                               bool unmask_signals, char *err_str,
+                               const RNBContext::IgnoredExceptions 
+                                   &ignored_exceptions, 
+                               char *err_str,
                                size_t err_len);
 nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
-                                     bool unmask_signals, char *err_str,
+                                     const RNBContext::IgnoredExceptions 
+                                         &ignored_exceptions, 
+                                     char *err_str,
                                      size_t err_len);
 nub_process_t DNBProcessAttachWait(RNBContext *ctx, const char *wait_name,
                                    bool ignore_existing,

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachException.cpp b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
index db154d160b41a..b27ef60fa6d29 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachException.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachException.cpp
@@ -512,3 +512,50 @@ const char *MachException::Name(exception_type_t exc_type) {
   }
   return NULL;
 }
+
+// Returns the exception mask for a given exception name.  
+// 0 is not a legit mask, so we return that in the case of an error.
+exception_mask_t MachException::ExceptionMask(const char *name) {
+  static const char *exception_prefix = "EXC_";
+  static const int prefix_len = strlen(exception_prefix);
+
+  // All mach exceptions start with this prefix:
+  if (strstr(name, exception_prefix) != name)
+    return 0;
+
+  name += prefix_len;
+  std::string name_str = name;
+  if (name_str == "BAD_ACCESS")
+    return EXC_MASK_BAD_ACCESS;
+  if (name_str == "BAD_INSTRUCTION")
+    return EXC_MASK_BAD_INSTRUCTION;
+  if (name_str == "ARITHMETIC")
+    return EXC_MASK_ARITHMETIC;
+  if (name_str == "EMULATION")
+    return EXC_MASK_EMULATION;
+  if (name_str == "SOFTWARE")
+    return EXC_MASK_SOFTWARE;
+  if (name_str == "BREAKPOINT")
+    return EXC_MASK_BREAKPOINT;
+  if (name_str == "SYSCALL")
+    return EXC_MASK_SYSCALL;
+  if (name_str == "MACH_SYSCALL")
+    return EXC_MASK_MACH_SYSCALL;
+  if (name_str == "RPC_ALERT")
+    return EXC_MASK_RPC_ALERT;
+#ifdef EXC_CRASH
+  if (name_str == "CRASH")
+    return EXC_MASK_CRASH;
+#endif
+  if (name_str == "RESOURCE")
+    return EXC_MASK_RESOURCE;
+#ifdef EXC_GUARD
+  if (name_str == "GUARD")
+    return EXC_MASK_GUARD;
+#endif
+#ifdef EXC_CORPSE_NOTIFY
+  if (name_str == "CORPSE_NOTIFY")
+    return EXC_MASK_CORPSE_NOTIFY;
+#endif
+  return 0;
+}

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachException.h b/lldb/tools/debugserver/source/MacOSX/MachException.h
index e6cb317bb51d0..bf9771ef0bf93 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachException.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachException.h
@@ -127,6 +127,7 @@ class MachException {
     uint8_t flags; // Action flags describing what to do with the exception
   };
   static const char *Name(exception_type_t exc_type);
+  static exception_mask_t ExceptionMask(const char *name);
 };
 
 #endif

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index 33c3d628a7a06..3b250bf5ec901 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -34,6 +34,7 @@
 #include "PThreadCondition.h"
 #include "PThreadEvent.h"
 #include "PThreadMutex.h"
+#include "RNBContext.h"
 #include "ThreadInfo.h"
 
 class DNBThreadResumeActions;
@@ -78,14 +79,17 @@ class MachProcess {
   };
 
   // Child process control
-  pid_t AttachForDebug(pid_t pid, bool unmask_signals, char *err_str,
+  pid_t AttachForDebug(pid_t pid,
+                       const RNBContext::IgnoredExceptions &ignored_exceptions,
+                       char *err_str,
                        size_t err_len);
   pid_t LaunchForDebug(const char *path, char const *argv[], char const *envp[],
                        const char *working_directory, const char *stdin_path,
                        const char *stdout_path, const char *stderr_path,
                        bool no_stdio, nub_launch_flavor_t launch_flavor,
                        int disable_aslr, const char *event_data,
-                       bool unmask_signals, DNBError &err);
+                       const RNBContext::IgnoredExceptions &ignored_exceptions,
+                       DNBError &err);
 
   static uint32_t GetCPUTypeForLocalProcess(pid_t pid);
   static pid_t ForkChildForPTraceDebugging(const char *path, char const *argv[],
@@ -109,7 +113,8 @@ class MachProcess {
   pid_t BoardServiceLaunchForDebug(const char *app_bundle_path,
                                    char const *argv[], char const *envp[],
                                    bool no_stdio, bool disable_aslr,
-                                   const char *event_data, bool unmask_signals,
+                                   const char *event_data,
+                                   const RNBContext::IgnoredExceptions &ignored_exceptions,
                                    DNBError &launch_err);
   pid_t BoardServiceForkChildForPTraceDebugging(
       const char *path, char const *argv[], char const *envp[], bool no_stdio,

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
index 9ab33cc4b3aaa..b41cb22bb202d 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -2590,8 +2590,11 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
   return NULL;
 }
 
-pid_t MachProcess::AttachForDebug(pid_t pid, bool unmask_signals, char *err_str,
-                                  size_t err_len) {
+pid_t MachProcess::AttachForDebug(
+    pid_t pid, 
+    const RNBContext::IgnoredExceptions &ignored_exceptions, 
+    char *err_str,
+    size_t err_len) {
   // Clear out and clean up from any current state
   Clear();
   if (pid != 0) {
@@ -2608,7 +2611,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
 
     SetState(eStateAttaching);
     m_pid = pid;
-    if (!m_task.StartExceptionThread(unmask_signals, err)) {
+    if (!m_task.StartExceptionThread(ignored_exceptions, err)) {
       const char *err_cstr = err.AsString();
       ::snprintf(err_str, err_len, "%s",
                  err_cstr ? err_cstr : "unable to start the exception thread");
@@ -3112,7 +3115,9 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
                                    // working directory for inferior to this
     const char *stdin_path, const char *stdout_path, const char *stderr_path,
     bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr,
-    const char *event_data, bool unmask_signals, DNBError &launch_err) {
+    const char *event_data, 
+    const RNBContext::IgnoredExceptions &ignored_exceptions, 
+    DNBError &launch_err) {
   // Clear out and clean up from any current state
   Clear();
 
@@ -3138,7 +3143,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
       m_flags |= (eMachProcessFlagsUsingFBS | eMachProcessFlagsBoardCalculated);
       if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
                                      no_stdio, disable_aslr, event_data,
-                                     unmask_signals, launch_err) != 0)
+                                     ignored_exceptions, launch_err) != 0)
         return m_pid; // A successful SBLaunchForDebug() returns and assigns a
                       // non-zero m_pid.
     }
@@ -3152,7 +3157,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
       m_flags |= (eMachProcessFlagsUsingBKS | eMachProcessFlagsBoardCalculated);
       if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
                                      no_stdio, disable_aslr, event_data,
-                                     unmask_signals, launch_err) != 0)
+                                     ignored_exceptions, launch_err) != 0)
         return m_pid; // A successful SBLaunchForDebug() returns and assigns a
                       // non-zero m_pid.
     }
@@ -3164,7 +3169,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
     std::string app_bundle_path = GetAppBundle(path);
     if (!app_bundle_path.empty()) {
       if (SBLaunchForDebug(app_bundle_path.c_str(), argv, envp, no_stdio,
-                           disable_aslr, unmask_signals, launch_err) != 0)
+                           disable_aslr, ignored_exceptions, launch_err) != 0)
         return m_pid; // A successful SBLaunchForDebug() returns and assigns a
                       // non-zero m_pid.
     }
@@ -3198,7 +3203,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
     for (i = 0; (arg = argv[i]) != NULL; i++)
       m_args.push_back(arg);
 
-    m_task.StartExceptionThread(unmask_signals, launch_err);
+    m_task.StartExceptionThread(ignored_exceptions, launch_err);
     if (launch_err.Fail()) {
       if (launch_err.AsString() == NULL)
         launch_err.SetErrorString("unable to start the exception thread");
@@ -3566,7 +3571,9 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path,
 
 pid_t MachProcess::SBLaunchForDebug(const char *path, char const *argv[],
                                     char const *envp[], bool no_stdio,
-                                    bool disable_aslr, bool unmask_signals,
+                                    bool disable_aslr, 
+                                    const RNBContext::IgnoredExceptions 
+                                        &ignored_exceptions,
                                     DNBError &launch_err) {
   // Clear out and clean up from any current state
   Clear();
@@ -3583,7 +3590,7 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path,
     char const *arg;
     for (i = 0; (arg = argv[i]) != NULL; i++)
       m_args.push_back(arg);
-    m_task.StartExceptionThread(unmask_signals, launch_err);
+    m_task.StartExceptionThread(ignored_exceptions, launch_err);
 
     if (launch_err.Fail()) {
       if (launch_err.AsString() == NULL)
@@ -3784,7 +3791,8 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path,
 #if defined(WITH_BKS) || defined(WITH_FBS)
 pid_t MachProcess::BoardServiceLaunchForDebug(
     const char *path, char const *argv[], char const *envp[], bool no_stdio,
-    bool disable_aslr, const char *event_data, bool unmask_signals,
+    bool disable_aslr, const char *event_data, 
+    const RNBContext::IgnoredExceptions &ignored_exceptions,
     DNBError &launch_err) {
   DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path);
 
@@ -3798,7 +3806,7 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path,
     char const *arg;
     for (i = 0; (arg = argv[i]) != NULL; i++)
       m_args.push_back(arg);
-    m_task.StartExceptionThread(unmask_signals, launch_err);
+    m_task.StartExceptionThread(ignored_exceptions, launch_err);
 
     if (launch_err.Fail()) {
       if (launch_err.AsString() == NULL)

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachTask.h b/lldb/tools/debugserver/source/MacOSX/MachTask.h
index e9cb885bfdb97..a58d5bed3b068 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.h
@@ -21,6 +21,7 @@
 #include <map>
 #include <string>
 #include "DNBDefs.h"
+#include "RNBContext.h"
 #include "MachException.h"
 #include "MachVMMemory.h"
 #include "PThreadMutex.h"
@@ -67,7 +68,8 @@ class MachTask {
   kern_return_t RestoreExceptionPortInfo();
   kern_return_t ShutDownExcecptionThread();
 
-  bool StartExceptionThread(bool unmask_signals, DNBError &err);
+  bool StartExceptionThread(
+      const RNBContext::IgnoredExceptions &ignored_exceptions, DNBError &err);
   nub_addr_t GetDYLDAllImageInfosAddress(DNBError &err);
   kern_return_t BasicInfo(struct task_basic_info *info);
   static kern_return_t BasicInfo(task_t task, struct task_basic_info *info);

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachTask.mm b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
index 767dc59b67808..1e03faf3f2e23 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
@@ -602,7 +602,9 @@ static void get_threads_profile_data(DNBProfileDataScanType scanType,
   return false;
 }
 
-bool MachTask::StartExceptionThread(bool unmask_signals, DNBError &err) {
+bool MachTask::StartExceptionThread(
+        const RNBContext::IgnoredExceptions &ignored_exceptions, 
+        DNBError &err) {
   DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s ( )", __FUNCTION__);
 
   task_t task = TaskPortForProcessID(err);
@@ -631,10 +633,9 @@ static void get_threads_profile_data(DNBProfileDataScanType scanType,
       return false;
     }
 
-    if (unmask_signals) {
-      m_exc_port_info.mask = m_exc_port_info.mask &
-                             ~(EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION |
-                               EXC_MASK_ARITHMETIC);
+    if (!ignored_exceptions.empty()) {
+      for (exception_mask_t mask : ignored_exceptions)
+        m_exc_port_info.mask = m_exc_port_info.mask & ~mask;
     }
 
     // Set the ability to get all exceptions on this port

diff  --git a/lldb/tools/debugserver/source/RNBContext.cpp b/lldb/tools/debugserver/source/RNBContext.cpp
index 0617ef3a67ffb..1518f30807f15 100644
--- a/lldb/tools/debugserver/source/RNBContext.cpp
+++ b/lldb/tools/debugserver/source/RNBContext.cpp
@@ -24,6 +24,7 @@
 #include "DNB.h"
 #include "DNBLog.h"
 #include "RNBRemote.h"
+#include "MacOSX/MachException.h"
 
 // Destructor
 RNBContext::~RNBContext() { SetProcessID(INVALID_NUB_PROCESS); }
@@ -286,3 +287,17 @@ bool RNBContext::ProcessStateRunning() const {
   nub_state_t pid_state = DNBProcessGetState(m_pid);
   return pid_state == eStateRunning || pid_state == eStateStepping;
 }
+
+bool RNBContext::AddIgnoredException(const char *exception_name) {
+  exception_mask_t exc_mask = MachException::ExceptionMask(exception_name);
+  if (exc_mask == 0)
+    return false;
+  m_ignored_exceptions.push_back(exc_mask);
+  return true;
+}
+
+void RNBContext::AddDefaultIgnoredExceptions() {
+  m_ignored_exceptions.push_back(EXC_MASK_BAD_ACCESS);
+  m_ignored_exceptions.push_back(EXC_MASK_BAD_INSTRUCTION);
+  m_ignored_exceptions.push_back(EXC_MASK_ARITHMETIC);
+}

diff  --git a/lldb/tools/debugserver/source/RNBContext.h b/lldb/tools/debugserver/source/RNBContext.h
index 183aa0a3f791f..1abef6b17707a 100644
--- a/lldb/tools/debugserver/source/RNBContext.h
+++ b/lldb/tools/debugserver/source/RNBContext.h
@@ -21,6 +21,7 @@
 
 class RNBContext {
 public:
+  using IgnoredExceptions = std::vector<exception_mask_t>;
   enum {
     event_proc_state_changed = 0x001,
     event_proc_thread_running = 0x002, // Sticky
@@ -118,10 +119,13 @@ class RNBContext {
   void SetDetachOnError(bool detach) { m_detach_on_error = detach; }
   bool GetDetachOnError() { return m_detach_on_error; }
 
-  void SetUnmaskSignals(bool unmask_signals) {
-    m_unmask_signals = unmask_signals;
+  bool AddIgnoredException(const char *exception_name);
+  
+  void AddDefaultIgnoredExceptions();
+
+  const IgnoredExceptions &GetIgnoredExceptions() {
+    return m_ignored_exceptions;
   }
-  bool GetUnmaskSignals() { return m_unmask_signals; }
 
 protected:
   // Classes that inherit from RNBContext can see and modify these
@@ -144,7 +148,7 @@ class RNBContext {
   std::string m_working_directory;
   std::string m_process_event;
   bool m_detach_on_error = false;
-  bool m_unmask_signals = false;
+  IgnoredExceptions m_ignored_exceptions;
 
   void StartProcessStatusThread();
   void StopProcessStatusThread();

diff  --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 7c68f85225a24..ebb2125524e9c 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -394,9 +394,12 @@ void RNBRemote::CreatePacketTable() {
                      "'G', 'p', and 'P') support having the thread ID appended "
                      "to the end of the command"));
   t.push_back(Packet(set_logging_mode, &RNBRemote::HandlePacket_QSetLogging,
-                     NULL, "QSetLogging:", "Check if register packets ('g', "
-                                           "'G', 'p', and 'P' support having "
-                                           "the thread ID prefix"));
+                     NULL, "QSetLogging:", "Turn on log channels in debugserver"));
+  t.push_back(Packet(set_ignored_exceptions, &RNBRemote::HandlePacket_QSetIgnoredExceptions,
+                     NULL, "QSetIgnoredExceptions:", "Set the exception types "
+                                           "debugserver won't wait for, allowing "
+                                           "them to be turned into the equivalent "
+                                           "BSD signals by the normal means."));
   t.push_back(Packet(
       set_max_packet_size, &RNBRemote::HandlePacket_QSetMaxPacketSize, NULL,
       "QSetMaxPacketSize:",
@@ -2210,6 +2213,37 @@ rnb_err_t set_logging(const char *p) {
   return rnb_success;
 }
 
+rnb_err_t RNBRemote::HandlePacket_QSetIgnoredExceptions(const char *p) {
+  // We can't set the ignored exceptions if we have a running process:
+  if (m_ctx.HasValidProcessID())
+    return SendPacket("E35");
+
+  p += sizeof("QSetIgnoredExceptions:") - 1;
+  bool success = true;
+  while(1) {
+    const char *bar  = strchr(p, '|');
+    if (bar == nullptr) {
+      success = m_ctx.AddIgnoredException(p);
+      break;
+    } else {
+      std::string exc_str(p, bar - p);
+      if (exc_str.empty()) {
+        success = false;
+        break;
+      }
+
+      success = m_ctx.AddIgnoredException(exc_str.c_str());
+      if (!success)
+        break;
+      p = bar + 1;
+    }
+  }
+  if (success)
+    return SendPacket("OK");
+  else
+    return SendPacket("E36");
+}
+
 rnb_err_t RNBRemote::HandlePacket_QThreadSuffixSupported(const char *p) {
   m_thread_suffix_supported = true;
   return SendPacket("OK");
@@ -3791,8 +3825,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
              "'%s'",
              getpid(), attach_name.c_str());
       attach_pid = DNBProcessAttachByName(attach_name.c_str(), NULL,
-                                          Context().GetUnmaskSignals(), err_str,
-                                          sizeof(err_str));
+                                          Context().GetIgnoredExceptions(), 
+                                          err_str, sizeof(err_str));
 
     } else if (strstr(p, "vAttach;") == p) {
       p += strlen("vAttach;");
@@ -3806,7 +3840,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
         DNBLog("[LaunchAttach] START %d vAttach to pid %d", getpid(),
                pid_attaching_to);
         attach_pid = DNBProcessAttach(pid_attaching_to, &attach_timeout_abstime,
-                                      false, err_str, sizeof(err_str));
+                                      m_ctx.GetIgnoredExceptions(), 
+                                      err_str, sizeof(err_str));
       }
     } else {
       return HandlePacket_UNIMPLEMENTED(p);

diff  --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index 527b2a7ab605c..41b9aede7d40b 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -110,6 +110,7 @@ class RNBRemote {
     start_noack_mode,                              // 'QStartNoAckMode'
     prefix_reg_packets_with_tid,        // 'QPrefixRegisterPacketsWithThreadID
     set_logging_mode,                   // 'QSetLogging:'
+    set_ignored_exceptions,             // 'QSetIgnoredExceptions'           
     set_max_packet_size,                // 'QSetMaxPacketSize:'
     set_max_payload_size,               // 'QSetMaxPayloadSize:'
     set_environment_variable,           // 'QEnvironment:'
@@ -197,6 +198,7 @@ class RNBRemote {
   rnb_err_t HandlePacket_QStartNoAckMode(const char *p);
   rnb_err_t HandlePacket_QThreadSuffixSupported(const char *p);
   rnb_err_t HandlePacket_QSetLogging(const char *p);
+  rnb_err_t HandlePacket_QSetIgnoredExceptions(const char *p);
   rnb_err_t HandlePacket_QSetDisableASLR(const char *p);
   rnb_err_t HandlePacket_QSetSTDIO(const char *p);
   rnb_err_t HandlePacket_QSetWorkingDir(const char *p);

diff  --git a/lldb/tools/debugserver/source/debugserver.cpp b/lldb/tools/debugserver/source/debugserver.cpp
index 87198717d691b..cbff6ac56f773 100644
--- a/lldb/tools/debugserver/source/debugserver.cpp
+++ b/lldb/tools/debugserver/source/debugserver.cpp
@@ -368,7 +368,7 @@ RNBRunLoopMode RNBRunLoopLaunchAttaching(RNBRemote *remote,
   DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Attaching to pid %i...", __FUNCTION__,
                    attach_pid);
   char err_str[1024];
-  pid = DNBProcessAttach(attach_pid, NULL, ctx.GetUnmaskSignals(), err_str,
+  pid = DNBProcessAttach(attach_pid, NULL, ctx.GetIgnoredExceptions(), err_str,
                          sizeof(err_str));
   g_pid = pid;
 
@@ -1275,7 +1275,7 @@ int main(int argc, char *argv[]) {
       break;
 
     case 'U':
-      ctx.SetUnmaskSignals(true);
+      ctx.AddDefaultIgnoredExceptions();
       break;
 
     case '2':
@@ -1574,7 +1574,7 @@ int main(int argc, char *argv[]) {
 
         RNBLogSTDOUT("Attaching to process %s...\n", attach_pid_name.c_str());
         nub_process_t pid = DNBProcessAttachByName(
-            attach_pid_name.c_str(), timeout_ptr, ctx.GetUnmaskSignals(),
+            attach_pid_name.c_str(), timeout_ptr, ctx.GetIgnoredExceptions(),
             err_str, sizeof(err_str));
         g_pid = pid;
         if (pid == INVALID_NUB_PROCESS) {


        


More information about the lldb-commits mailing list