diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -319,97 +319,72 @@ std::unique_lock lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { + if (dst) + *dst = 0; - StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); - if (stop_info_sp) { - std::string thread_stop_desc = - exe_ctx.GetThreadPtr()->GetStopDescription(); - const char *stop_desc = thread_stop_desc.c_str(); - - if (stop_desc[0] != '\0') { - if (dst) - return ::snprintf(dst, dst_len, "%s", stop_desc); - else { - // NULL dst passed in, return the length needed to contain the - // description - return ::strlen(stop_desc) + 1; // Include the NULL byte for size - } - } else { - size_t stop_desc_len = 0; - switch (stop_info_sp->GetStopReason()) { - case eStopReasonTrace: - case eStopReasonPlanComplete: { - static char trace_desc[] = "step"; - stop_desc = trace_desc; - stop_desc_len = - sizeof(trace_desc); // Include the NULL byte for size - } break; - - case eStopReasonBreakpoint: { - static char bp_desc[] = "breakpoint hit"; - stop_desc = bp_desc; - stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size - } break; - - case eStopReasonWatchpoint: { - static char wp_desc[] = "watchpoint hit"; - stop_desc = wp_desc; - stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size - } break; - - case eStopReasonSignal: { - stop_desc = - exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString( - stop_info_sp->GetValue()); - if (stop_desc == nullptr || stop_desc[0] == '\0') { - static char signal_desc[] = "signal"; - stop_desc = signal_desc; - stop_desc_len = - sizeof(signal_desc); // Include the NULL byte for size - } - } break; - - case eStopReasonException: { - char exc_desc[] = "exception"; - stop_desc = exc_desc; - stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size - } break; - - case eStopReasonExec: { - char exc_desc[] = "exec"; - stop_desc = exc_desc; - stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size - } break; - - case eStopReasonThreadExiting: { - char limbo_desc[] = "thread exiting"; - stop_desc = limbo_desc; - stop_desc_len = sizeof(limbo_desc); - } break; - default: - break; - } + if (!exe_ctx.HasThreadScope()) + return 0; - if (stop_desc && stop_desc[0]) { - if (dst) - return ::snprintf(dst, dst_len, "%s", stop_desc) + - 1; // Include the NULL byte + Process::StopLocker stop_locker; + if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + return 0; - if (stop_desc_len == 0) - stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); + if (!stop_info_sp) + return 0; - return stop_desc_len; - } - } - } - } + std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription(); + if (!thread_stop_desc.empty()) { + if (dst) + return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()); + + // NULL dst passed in, return the length needed to contain the + // description + return thread_stop_desc.size() + 1; // Include the NULL byte for size } + + // No stop description was provided by the thread's StopInfo, try to + // derive a meaningful description from the StopReason. + + auto reason_string = [](StopReason reason) -> llvm::StringRef { + switch (reason) { + case eStopReasonTrace: + case eStopReasonPlanComplete: + return "step"; + case eStopReasonBreakpoint: + return "breakpoint hit"; + case eStopReasonWatchpoint: + return "watchpoint hit"; + case eStopReasonSignal: + return "signal"; + case eStopReasonException: + return "exception"; + case eStopReasonExec: + return "exec"; + case eStopReasonThreadExiting: + return "thread exiting"; + default: + return {}; + } + }; + + StopReason reason = stop_info_sp->GetStopReason(); + llvm::StringRef stop_desc = reason_string(reason); + + if (reason == eStopReasonSignal) + if (const char *signal_name = + exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString( + stop_info_sp->GetValue())) + stop_desc = signal_name; + + if (stop_desc.empty()) + return 0; + if (dst) - *dst = 0; - return 0; + return ::snprintf(dst, dst_len, "%s", stop_desc.data()) + + 1; // Include the NULL byte + + return stop_desc.size() + 1; // Include the NULL byte } SBValue SBThread::GetStopReturnValue() {