diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h --- a/lldb/tools/debugserver/source/DNB.h +++ b/lldb/tools/debugserver/source/DNB.h @@ -247,4 +247,9 @@ bool DNBDebugserverIsTranslated(); bool DNBGetAddressingBits(uint32_t &addressing_bits); + +nub_process_t DNBGetParentProcessID(nub_process_t child_pid); + +bool DNBProcessIsBeingDebugged(nub_process_t pid); + #endif diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -1848,3 +1848,11 @@ return addressing_bits > 0; } + +nub_process_t DNBGetParentProcessID(nub_process_t child_pid) { + return MachProcess::GetParentProcessID(child_pid); +} + +bool DNBProcessIsBeingDebugged(nub_process_t pid) { + return MachProcess::ProcessIsBeingDebugged(pid); +} diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h @@ -126,6 +126,11 @@ static bool GetOSVersionNumbers(uint64_t *major, uint64_t *minor, uint64_t *patch); static std::string GetMacCatalystVersionString(); + + static nub_process_t GetParentProcessID(nub_process_t child_pid); + + static bool ProcessIsBeingDebugged(nub_process_t pid); + #ifdef WITH_BKS static void BKSCleanupAfterAttach(const void *attach_token, DNBError &err_str); diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm @@ -2821,16 +2821,21 @@ "attach to pid %d", getpid(), pid); - 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); + if (ProcessIsBeingDebugged(pid)) { + nub_process_t ppid = GetParentProcessID(pid); + if (ppid == getpid()) { + snprintf(err_str, err_len, + "%s - Failed to attach to pid %d, AttachForDebug() " + "unable to ptrace(PT_ATTACHEXC)", + err.AsString(), m_pid); + } else { + 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", - getpid(), pid); + "already being debugged by pid %d", + getpid(), pid, ppid); } } } @@ -2879,6 +2884,26 @@ return {}; } +nub_process_t MachProcess::GetParentProcessID(nub_process_t child_pid) { + struct proc_bsdshortinfo proc; + if (proc_pidinfo(child_pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, + PROC_PIDT_SHORTBSDINFO_SIZE) == sizeof(proc)) { + return proc.pbsi_ppid; + } + return INVALID_NUB_PROCESS; +} + +bool MachProcess::ProcessIsBeingDebugged(nub_process_t pid) { + 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 && + (kinfo.kp_proc.p_flag & P_TRACED)) + return true; + else + return false; +} + #if defined(WITH_SPRINGBOARD) || defined(WITH_BKS) || defined(WITH_FBS) /// Get the app bundle from the given path. Returns the empty string if the /// path doesn't appear to be an app bundle. @@ -3401,7 +3426,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 +3808,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 +4031,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); diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -3630,14 +3630,8 @@ // processes and step through to find the one we're looking for // (as process_does_not_exist() does). static bool process_is_already_being_debugged (nub_process_t pid) { - 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) { - 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 + if (DNBProcessIsBeingDebugged(pid) && DNBGetParentProcessID(pid) != getpid()) + return true; else return false; }