[Lldb-commits] [lldb] 27012c0 - [debugserver] Add option to propagate SIGSEGV to target process

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Tue Nov 17 09:27:59 PST 2020


Author: Alessandro Arzilli
Date: 2020-11-17T09:27:52-08:00
New Revision: 27012c0f75c2e4891277d0d14f9f97a9f564d596

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

LOG: [debugserver] Add option to propagate SIGSEGV to target process

Adds a command line option that makes debugserver propagate the SIGSEGV
signal to the target process.

Motivation: I'm one of the maintainers of Delve [1] a debugger for Go.
We use debugserver as our backend on macOS and one of the most often
reported bugs is that, on macOS, we don't propagate SIGSEGV back to the
target process [2]. Sometimes some programs will actually cause a
SIGSEGV, by design, and then handle it. Those programs can not be
debugged at all.

Since catching signals isn't very important for a Go debugger I'd much
rather have a command line option in debugserver that causes it to let
SIGSEGV go directly to the target process.

[1] https://github.com/go-delve/delve/
[2] https://github.com/go-delve/delve/issues/852

Differential revision: https://reviews.llvm.org/D89315

Added: 
    

Modified: 
    lldb/tools/debugserver/source/DNB.cpp
    lldb/tools/debugserver/source/DNB.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.h
    lldb/tools/debugserver/source/RNBRemote.cpp
    lldb/tools/debugserver/source/debugserver.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index afafe0d0474a..2d6516e8c654 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -319,20 +319,21 @@ static bool spawn_waitpid_thread(pid_t pid) {
 }
 
 nub_process_t DNBProcessLaunch(
-    const char *path, char const *argv[], const char *envp[],
+    RNBContext *ctx, const char *path, char const *argv[], const char *envp[],
     const char *working_directory, // NULL => don't change, non-NULL => set
                                    // 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, char *err_str, size_t err_len) {
-  DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, "
-                                "working_dir=%s, stdin=%s, stdout=%s, "
-                                "stderr=%s, no-stdio=%i, launch_flavor = %u, "
-                                "disable_aslr = %d, err = %p, err_len = "
-                                "%llu) called...",
+    bool no_stdio, int disable_aslr, const char *event_data, char *err_str,
+    size_t err_len) {
+  DNBLogThreadedIf(LOG_PROCESS,
+                   "%s ( path='%s', argv = %p, envp = %p, "
+                   "working_dir=%s, stdin=%s, stdout=%s, "
+                   "stderr=%s, no-stdio=%i, launch_flavor = %u, "
+                   "disable_aslr = %d, err = %p, err_len = "
+                   "%llu) called...",
                    __FUNCTION__, path, static_cast<void *>(argv),
                    static_cast<void *>(envp), working_directory, stdin_path,
-                   stdout_path, stderr_path, no_stdio, launch_flavor,
+                   stdout_path, stderr_path, no_stdio, ctx->LaunchFlavor(),
                    disable_aslr, static_cast<void *>(err_str),
                    static_cast<uint64_t>(err_len));
 
@@ -349,10 +350,10 @@ nub_process_t DNBProcessLaunch(
   MachProcessSP processSP(new MachProcess);
   if (processSP.get()) {
     DNBError launch_err;
-    pid_t pid = processSP->LaunchForDebug(path, argv, envp, working_directory,
-                                          stdin_path, stdout_path, stderr_path,
-                                          no_stdio, launch_flavor, disable_aslr,
-                                          event_data, launch_err);
+    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);
     if (err_str) {
       *err_str = '\0';
       if (launch_err.Fail()) {
@@ -412,7 +413,8 @@ nub_process_t DNBProcessGetPIDByName(const char *name) {
 }
 
 nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
-                                     char *err_str, size_t err_len) {
+                                     bool unmask_signals, char *err_str,
+                                     size_t err_len) {
   if (err_str && err_len > 0)
     err_str[0] = '\0';
   std::vector<struct kinfo_proc> matching_proc_infos;
@@ -433,12 +435,12 @@ nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
   }
 
   return DNBProcessAttach(matching_proc_infos[0].kp_proc.p_pid, timeout,
-                          err_str, err_len);
+                          unmask_signals, err_str, err_len);
 }
 
 nub_process_t DNBProcessAttach(nub_process_t attach_pid,
-                               struct timespec *timeout, char *err_str,
-                               size_t err_len) {
+                               struct timespec *timeout, bool unmask_signals,
+                               char *err_str, size_t err_len) {
   if (err_str && err_len > 0)
     err_str[0] = '\0';
 
@@ -480,7 +482,8 @@ nub_process_t DNBProcessAttach(nub_process_t attach_pid,
   if (processSP.get()) {
     DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) attaching to pid %d...",
                      attach_pid);
-    pid = processSP->AttachForDebug(attach_pid, err_str, err_len);
+    pid =
+        processSP->AttachForDebug(attach_pid, unmask_signals, err_str, err_len);
 
     if (pid != INVALID_NUB_PROCESS) {
       bool res = AddProcessToMap(pid, processSP);
@@ -667,15 +670,18 @@ GetAllInfosMatchingName(const char *full_process_name,
   return matching_proc_infos.size();
 }
 
-nub_process_t DNBProcessAttachWait(
-    const char *waitfor_process_name, nub_launch_flavor_t launch_flavor,
-    bool ignore_existing, struct timespec *timeout_abstime,
-    useconds_t waitfor_interval, char *err_str, size_t err_len,
-    DNBShouldCancelCallback should_cancel_callback, void *callback_data) {
+nub_process_t
+DNBProcessAttachWait(RNBContext *ctx, const char *waitfor_process_name,
+                     bool ignore_existing, struct timespec *timeout_abstime,
+                     useconds_t waitfor_interval, char *err_str, size_t err_len,
+                     DNBShouldCancelCallback should_cancel_callback,
+                     void *callback_data) {
   DNBError prepare_error;
   std::vector<struct kinfo_proc> exclude_proc_infos;
   size_t num_exclude_proc_infos;
 
+  nub_launch_flavor_t launch_flavor = ctx->LaunchFlavor();
+
   // If the PrepareForAttach returns a valid token, use  MachProcess to check
   // for the process, otherwise scan the process table.
 
@@ -771,8 +777,8 @@ nub_process_t DNBProcessAttachWait(
   if (waitfor_pid != INVALID_NUB_PROCESS) {
     DNBLogThreadedIf(LOG_PROCESS, "Attaching to %s with pid %i...\n",
                      waitfor_process_name, waitfor_pid);
-    waitfor_pid =
-        DNBProcessAttach(waitfor_pid, timeout_abstime, err_str, err_len);
+    waitfor_pid = DNBProcessAttach(waitfor_pid, timeout_abstime,
+                                   ctx->GetUnmaskSignals(), 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 8364ec0c1162..069c62dc41d8 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -18,10 +18,11 @@
 #include "MacOSX/DarwinLog/DarwinLogEvent.h"
 #include "MacOSX/Genealogy.h"
 #include "MacOSX/ThreadInfo.h"
-#include <mach/thread_info.h>
-#include <string>
+#include "RNBContext.h"
 #include <Availability.h>
 #include <mach/machine.h>
+#include <mach/thread_info.h>
+#include <string>
 
 #define DNB_EXPORT __attribute__((visibility("default")))
 
@@ -42,24 +43,27 @@ nub_bool_t DNBSetArchitecture(const char *arch);
 
 // Process control
 nub_process_t DNBProcessLaunch(
-    const char *path, char const *argv[], const char *envp[],
+    RNBContext *ctx, const char *path, char const *argv[], const char *envp[],
     const char *working_directory, // NULL => don't change, non-NULL => set
                                    // 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, char *err_str, size_t err_len);
+    bool no_stdio, int disable_aslr, const char *event_data, char *err_str,
+    size_t err_len);
 
 nub_process_t DNBProcessGetPIDByName(const char *name);
 nub_process_t DNBProcessAttach(nub_process_t pid, struct timespec *timeout,
-                               char *err_str, size_t err_len);
+                               bool unmask_signals, char *err_str,
+                               size_t err_len);
 nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
-                                     char *err_str, size_t err_len);
-nub_process_t
-DNBProcessAttachWait(const char *wait_name, nub_launch_flavor_t launch_flavor,
-                     bool ignore_existing, struct timespec *timeout,
-                     useconds_t interval, char *err_str, size_t err_len,
-                     DNBShouldCancelCallback should_cancel = NULL,
-                     void *callback_data = NULL);
+                                     bool unmask_signals, char *err_str,
+                                     size_t err_len);
+nub_process_t DNBProcessAttachWait(RNBContext *ctx, const char *wait_name,
+                                   bool ignore_existing,
+                                   struct timespec *timeout,
+                                   useconds_t interval, char *err_str,
+                                   size_t err_len,
+                                   DNBShouldCancelCallback should_cancel = NULL,
+                                   void *callback_data = NULL);
 // Resume a process with exact instructions on what to do with each thread:
 // - If no thread actions are supplied (actions is NULL or num_actions is zero),
 //   then all threads are continued.

diff  --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index 7eb663cc2d51..a41b137c3fd0 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -78,12 +78,14 @@ class MachProcess {
   };
 
   // Child process control
-  pid_t AttachForDebug(pid_t pid, char *err_str, size_t err_len);
+  pid_t AttachForDebug(pid_t pid, bool unmask_signals, 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, DNBError &err);
+                       int disable_aslr, const char *event_data,
+                       bool unmask_signals, DNBError &err);
 
   static uint32_t GetCPUTypeForLocalProcess(pid_t pid);
   static pid_t ForkChildForPTraceDebugging(const char *path, char const *argv[],
@@ -107,7 +109,7 @@ 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,
+                                   const char *event_data, bool unmask_signals,
                                    DNBError &launch_err);
   pid_t BoardServiceForkChildForPTraceDebugging(
       const char *path, char const *argv[], char const *envp[], bool no_stdio,
@@ -128,7 +130,7 @@ class MachProcess {
 #ifdef WITH_SPRINGBOARD
   pid_t SBLaunchForDebug(const char *app_bundle_path, char const *argv[],
                          char const *envp[], bool no_stdio, bool disable_aslr,
-                         DNBError &launch_err);
+                         bool unmask_signals, DNBError &launch_err);
   static pid_t SBForkChildForPTraceDebugging(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 80792f07214b..0206fa636e11 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -2600,7 +2600,8 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
   return NULL;
 }
 
-pid_t MachProcess::AttachForDebug(pid_t pid, char *err_str, size_t err_len) {
+pid_t MachProcess::AttachForDebug(pid_t pid, bool unmask_signals, char *err_str,
+                                  size_t err_len) {
   // Clear out and clean up from any current state
   Clear();
   if (pid != 0) {
@@ -2617,7 +2618,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
 
     SetState(eStateAttaching);
     m_pid = pid;
-    if (!m_task.StartExceptionThread(err)) {
+    if (!m_task.StartExceptionThread(unmask_signals, err)) {
       const char *err_cstr = err.AsString();
       ::snprintf(err_str, err_len, "%s",
                  err_cstr ? err_cstr : "unable to start the exception thread");
@@ -3077,7 +3078,7 @@ 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, DNBError &launch_err) {
+    const char *event_data, bool unmask_signals, DNBError &launch_err) {
   // Clear out and clean up from any current state
   Clear();
 
@@ -3182,7 +3183,7 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
     for (i = 0; (arg = argv[i]) != NULL; i++)
       m_args.push_back(arg);
 
-    m_task.StartExceptionThread(launch_err);
+    m_task.StartExceptionThread(unmask_signals, launch_err);
     if (launch_err.Fail()) {
       if (launch_err.AsString() == NULL)
         launch_err.SetErrorString("unable to start the exception thread");
@@ -3525,7 +3526,8 @@ 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, DNBError &launch_err) {
+                                    bool disable_aslr, bool unmask_signals,
+                                    DNBError &launch_err) {
   // Clear out and clean up from any current state
   Clear();
 
@@ -3541,7 +3543,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(launch_err);
+    m_task.StartExceptionThread(unmask_signals, launch_err);
 
     if (launch_err.Fail()) {
       if (launch_err.AsString() == NULL)
@@ -3738,7 +3740,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, DNBError &launch_err) {
+    bool disable_aslr, const char *event_data, bool unmask_signals,
+    DNBError &launch_err) {
   DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path);
 
   // Fork a child process for debugging
@@ -3751,7 +3754,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(launch_err);
+    m_task.StartExceptionThread(unmask_signals, 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 36e31dddd455..e9cb885bfdb9 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.h
@@ -67,7 +67,7 @@ class MachTask {
   kern_return_t RestoreExceptionPortInfo();
   kern_return_t ShutDownExcecptionThread();
 
-  bool StartExceptionThread(DNBError &err);
+  bool StartExceptionThread(bool unmask_signals, 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 fcbe6e71389e..1d977191c009 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
@@ -595,7 +595,7 @@ static void get_threads_profile_data(DNBProfileDataScanType scanType,
   return false;
 }
 
-bool MachTask::StartExceptionThread(DNBError &err) {
+bool MachTask::StartExceptionThread(bool unmask_signals, DNBError &err) {
   DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s ( )", __FUNCTION__);
 
   task_t task = TaskPortForProcessID(err);
@@ -624,6 +624,12 @@ 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);
+    }
+
     // Set the ability to get all exceptions on this port
     err = ::task_set_exception_ports(
         task, m_exc_port_info.mask, m_exception_port,

diff  --git a/lldb/tools/debugserver/source/RNBContext.h b/lldb/tools/debugserver/source/RNBContext.h
index 7d8f458ce0f9..0b46151e4785 100644
--- a/lldb/tools/debugserver/source/RNBContext.h
+++ b/lldb/tools/debugserver/source/RNBContext.h
@@ -124,6 +124,11 @@ 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 GetUnmaskSignals() { return m_unmask_signals; }
+
 protected:
   // Classes that inherit from RNBContext can see and modify these
   nub_process_t m_pid;
@@ -147,6 +152,7 @@ class RNBContext {
   void StartProcessStatusThread();
   void StopProcessStatusThread();
   static void *ThreadFunctionProcessStatus(void *arg);
+  bool m_unmask_signals;
 
 private:
   RNBContext(const RNBContext &rhs) = delete;

diff  --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index aef41a5dba43..1f3a830a1dce 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -3927,8 +3927,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
       }
       const bool ignore_existing = true;
       attach_pid = DNBProcessAttachWait(
-          attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL,
-          1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
+          &m_ctx, attach_name.c_str(), ignore_existing, NULL, 1000, err_str,
+          sizeof(err_str), RNBRemoteShouldCancelCallback);
 
     } else if (strstr(p, "vAttachOrWait;") == p) {
       p += strlen("vAttachOrWait;");
@@ -3939,8 +3939,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
       }
       const bool ignore_existing = false;
       attach_pid = DNBProcessAttachWait(
-          attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL,
-          1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
+          &m_ctx, attach_name.c_str(), ignore_existing, NULL, 1000, err_str,
+          sizeof(err_str), RNBRemoteShouldCancelCallback);
     } else if (strstr(p, "vAttachName;") == p) {
       p += strlen("vAttachName;");
       if (!GetProcessNameFrom_vAttach(p, attach_name)) {
@@ -3948,7 +3948,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
             __FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt");
       }
 
-      attach_pid = DNBProcessAttachByName(attach_name.c_str(), NULL, err_str,
+      attach_pid = DNBProcessAttachByName(attach_name.c_str(), NULL,
+                                          Context().GetUnmaskSignals(), err_str,
                                           sizeof(err_str));
 
     } else if (strstr(p, "vAttach;") == p) {
@@ -3961,7 +3962,7 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
         struct timespec attach_timeout_abstime;
         DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
         attach_pid = DNBProcessAttach(pid_attaching_to, &attach_timeout_abstime,
-                                      err_str, sizeof(err_str));
+                                      false, err_str, sizeof(err_str));
       }
     } else {
       return HandlePacket_UNIMPLEMENTED(p);

diff  --git a/lldb/tools/debugserver/source/debugserver.cpp b/lldb/tools/debugserver/source/debugserver.cpp
index feb65eb6d3fb..fed24fe0648a 100644
--- a/lldb/tools/debugserver/source/debugserver.cpp
+++ b/lldb/tools/debugserver/source/debugserver.cpp
@@ -245,8 +245,8 @@ RNBRunLoopMode RNBRunLoopLaunchInferior(RNBRemote *remote,
                                        : ctx.GetWorkingDirectory());
   const char *process_event = ctx.GetProcessEvent();
   nub_process_t pid = DNBProcessLaunch(
-      resolved_path, &inferior_argv[0], &inferior_envp[0], cwd, stdin_path,
-      stdout_path, stderr_path, no_stdio, launch_flavor, g_disable_aslr,
+      &ctx, resolved_path, &inferior_argv[0], &inferior_envp[0], cwd,
+      stdin_path, stdout_path, stderr_path, no_stdio, g_disable_aslr,
       process_event, launch_err_str, sizeof(launch_err_str));
 
   g_pid = pid;
@@ -368,7 +368,8 @@ 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, err_str, sizeof(err_str));
+  pid = DNBProcessAttach(attach_pid, NULL, ctx.GetUnmaskSignals(), err_str,
+                         sizeof(err_str));
   g_pid = pid;
 
   if (pid == INVALID_NUB_PROCESS) {
@@ -889,6 +890,10 @@ static struct option g_long_options[] = {
      'F'}, // When debugserver launches the process, forward debugserver's
            // current environment variables to the child process ("./debugserver
            // -F localhost:1234 -- /bin/ls"
+    {"unmask-signals", no_argument, NULL,
+     'U'}, // debugserver will ignore EXC_MASK_BAD_ACCESS,
+           // EXC_MASK_BAD_INSTRUCTION and EXC_MASK_ARITHMETIC, which results in
+           // SIGSEGV, SIGILL and SIGFPE being propagated to the target process.
     {NULL, 0, NULL, 0}};
 
 int communication_fd = -1;
@@ -1260,6 +1265,10 @@ int main(int argc, char *argv[]) {
       forward_env = true;
       break;
 
+    case 'U':
+      ctx.SetUnmaskSignals(true);
+      break;
+
     case '2':
       // File descriptor passed to this process during fork/exec and is already
       // open and ready for communication.
@@ -1514,8 +1523,8 @@ int main(int argc, char *argv[]) {
         RNBLogSTDOUT("Waiting to attach to process %s...\n",
                      waitfor_pid_name.c_str());
         nub_process_t pid = DNBProcessAttachWait(
-            waitfor_pid_name.c_str(), launch_flavor, ignore_existing,
-            timeout_ptr, waitfor_interval, err_str, sizeof(err_str));
+            &ctx, waitfor_pid_name.c_str(), ignore_existing, timeout_ptr,
+            waitfor_interval, err_str, sizeof(err_str));
         g_pid = pid;
 
         if (pid == INVALID_NUB_PROCESS) {
@@ -1550,7 +1559,8 @@ 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, err_str, sizeof(err_str));
+            attach_pid_name.c_str(), timeout_ptr, ctx.GetUnmaskSignals(),
+            err_str, sizeof(err_str));
         g_pid = pid;
         if (pid == INVALID_NUB_PROCESS) {
           ctx.LaunchStatus().SetError(-1, DNBError::Generic);


        


More information about the lldb-commits mailing list