Author: Jason Molenda Date: 2023-07-12T15:01:39-07:00 New Revision: bb136f5b393c7c7fe821242d2734bbc5c7287560
URL: https://github.com/llvm/llvm-project/commit/bb136f5b393c7c7fe821242d2734bbc5c7287560 DIFF: https://github.com/llvm/llvm-project/commit/bb136f5b393c7c7fe821242d2734bbc5c7287560.diff LOG: Improve error messaging when debugserver fails to complete attaching When debugserver is attaching to a process, it first task_for_pid()'s and then ptrace(PT_ATTACHEXC)'s. When that ptrace() fails to complete, we are in a semi-attached state that we need to give up from, and our error reporting isn't ideal -- we can even claim that the process is already being debugged (by ourselves). Differential Revision: https://reviews.llvm.org/D155037 rdar://101152233 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/RNBRemote.cpp Removed: ################################################################################ diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index 7b86ca0bfb9dc7..e01d449261cdf2 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -1848,3 +1848,11 @@ bool DNBGetAddressingBits(uint32_t &addressing_bits) { 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/DNB.h b/lldb/tools/debugserver/source/DNB.h index d8ccdea20f692b..97de83ef9ff80d 100644 --- a/lldb/tools/debugserver/source/DNB.h +++ b/lldb/tools/debugserver/source/DNB.h @@ -247,4 +247,9 @@ std::string DNBGetMacCatalystVersionString(); 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/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h index a84bfb94d09c1d..8432bdb36c0cf8 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h @@ -126,6 +126,11 @@ class MachProcess { 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 index dcc1579f70251d..29fabd087ecbe1 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm @@ -2821,16 +2821,21 @@ static uint64_t bits(uint64_t value, uint32_t msbit, uint32_t lsbit) { "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 @@ static uint64_t bits(uint64_t value, uint32_t msbit, uint32_t lsbit) { 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 @@ static uint64_t bits(uint64_t value, uint32_t msbit, uint32_t lsbit) { "%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 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path, 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 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path, 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 index db0dc5fc4d166a..68ac61aab434df 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -3630,14 +3630,8 @@ static bool attach_failed_due_to_uid_mismatch (nub_process_t pid, // 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; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits