jasonmolenda created this revision.
jasonmolenda added a reviewer: jingham.
jasonmolenda added a project: LLDB.
Herald added a subscriber: JDevlieghere.
Herald added a project: All.
jasonmolenda requested review of this revision.
Herald added a subscriber: lldb-commits.

On Darwin, we first get a process' mach task port with task_for_pid(), and then 
we do a ptrace(PT_ATTACHEXC).  We need to complete both before we are 
successfully attached.  There are unusual failures where we get the task port 
and the ptrace may not have completed entirely, so lldb is going to exit out.  
An error message isn't created at the layer where this failure was detected, 
and then at a higher layer where we try to find a reason why the attach failed, 
we notice that the process is being "debugged" -- by ourselves -- and emit an 
error message saying it's being debugged.

This patch adds an error string at all the points where we can fail to complete 
this two-step attach process, and also adds a refinement to the "last ditch 
error reporting" scheme to confirm that the process' parent process isn't 
already this debugserver.  (we half-attached to it)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155037

Files:
  lldb/tools/debugserver/source/MacOSX/MachProcess.mm
  lldb/tools/debugserver/source/RNBRemote.cpp

Index: lldb/tools/debugserver/source/RNBRemote.cpp
===================================================================
--- lldb/tools/debugserver/source/RNBRemote.cpp
+++ lldb/tools/debugserver/source/RNBRemote.cpp
@@ -3636,10 +3636,23 @@
   if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &kinfo, &len, NULL, 0) != 0) {
     return false; // pid doesn't exist? well, it's not being debugged...
   }
-  if (kinfo.kp_proc.p_flag & P_TRACED)
-    return true; // is being debugged already
-  else
-    return false;
+  struct proc_bsdshortinfo proc;
+  int ppid = 0;
+  if (proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc,
+                   PROC_PIDT_SHORTBSDINFO_SIZE) == sizeof(proc)) {
+    ppid = proc.pbsi_ppid;
+  }
+  if (kinfo.kp_proc.p_flag & P_TRACED) {
+    if (ppid != getpid()) {
+      return true; // is being debugged already
+    } else {
+      // being debugged, but by us. The attach
+      // failed for some reason after we had
+      // ptrace'd the process and become parent.
+      return false;
+    }
+  }
+  return false;
 }
 
 // Test if this current login session has a connection to the
Index: lldb/tools/debugserver/source/MacOSX/MachProcess.mm
===================================================================
--- lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -2821,16 +2821,31 @@
           "attach to pid %d",
           getpid(), pid);
 
+      struct proc_bsdshortinfo proc;
+      int ppid = 0;
+      if (proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc,
+                       PROC_PIDT_SHORTBSDINFO_SIZE) == sizeof(proc)) {
+        ppid = proc.pbsi_ppid;
+      }
       struct kinfo_proc kinfo;
       int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
       size_t len = sizeof(struct kinfo_proc);
       if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &kinfo, &len, NULL, 0) == 0 && len > 0) {
         if (kinfo.kp_proc.p_flag & P_TRACED) {
-          ::snprintf(err_str, err_len, "%s - process %d is already being debugged", err.AsString(), pid);
-          DNBLogError(
-              "[LaunchAttach] (%d) MachProcess::AttachForDebug pid %d is "
-              "already being debugged",
-              getpid(), pid);
+          if (ppid != getpid()) {
+            snprintf(err_str, err_len,
+                     "%s - process %d is already being debugged by pid %d",
+                     err.AsString(), pid, ppid);
+            DNBLogError(
+                "[LaunchAttach] (%d) MachProcess::AttachForDebug pid %d is "
+                "already being debugged by pid %d",
+                getpid(), pid, ppid);
+          } else {
+            snprintf(err_str, err_len,
+                     "%s - Failed to attach to pid %d, AttachForDebug() "
+                     "unable to ptrace(PT_ATTACHEXC)",
+                     err.AsString(), m_pid);
+          }
         }
       }
     }
@@ -3401,7 +3416,13 @@
                                       "%d (err = %i, errno = %i (%s))",
                          m_pid, err, ptrace_err.Status(),
                          ptrace_err.AsString());
-        launch_err.SetError(NUB_GENERIC_ERROR, DNBError::Generic);
+        char err_msg[PATH_MAX];
+
+        snprintf(err_msg, sizeof(err_msg),
+                 "Failed to attach to pid %d, LaunchForDebug() unable to "
+                 "ptrace(PT_ATTACHEXC)",
+                 m_pid);
+        launch_err.SetErrorString(err_msg);
       }
     } else {
       launch_err.Clear();
@@ -3777,6 +3798,10 @@
       m_flags |= eMachProcessFlagsAttached;
       DNBLogThreadedIf(LOG_PROCESS, "successfully attached to pid %d", m_pid);
     } else {
+      launch_err.SetErrorString(
+          "Failed to attach to pid %d, SBLaunchForDebug() unable to "
+          "ptrace(PT_ATTACHEXC)",
+          m_pid);
       SetState(eStateExited);
       DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", m_pid);
     }
@@ -3996,6 +4021,10 @@
       m_flags |= eMachProcessFlagsAttached;
       DNBLog("[LaunchAttach] successfully attached to pid %d", m_pid);
     } else {
+      launch_err.SetErrorString(
+          "Failed to attach to pid %d, BoardServiceLaunchForDebug() unable to "
+          "ptrace(PT_ATTACHEXC)",
+          m_pid);
       SetState(eStateExited);
       DNBLog("[LaunchAttach] END (%d) error: failed to attach to pid %d",
              getpid(), m_pid);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to