Index: include/lldb/API/SBThread.h =================================================================== --- include/lldb/API/SBThread.h +++ include/lldb/API/SBThread.h @@ -176,6 +176,8 @@ bool GetDescription(lldb::SBStream &description) const; + bool GetDescription(lldb::SBStream &description, bool stop_format) const; + bool GetStatus(lldb::SBStream &status) const; SBThread GetExtendedBacktraceThread(const char *type); Index: include/lldb/Core/Debugger.h =================================================================== --- include/lldb/Core/Debugger.h +++ include/lldb/Core/Debugger.h @@ -218,6 +218,8 @@ const FormatEntity::Entry *GetThreadFormat() const; + const FormatEntity::Entry *GetThreadStopFormat() const; + lldb::ScriptLanguage GetScriptLanguage() const; bool SetScriptLanguage(lldb::ScriptLanguage script_lang); Index: include/lldb/Core/FormatEntity.h =================================================================== --- include/lldb/Core/FormatEntity.h +++ include/lldb/Core/FormatEntity.h @@ -62,6 +62,7 @@ File, Lang, FrameIndex, + FrameNoDebug, FrameRegisterPC, FrameRegisterSP, FrameRegisterFP, Index: include/lldb/Target/Process.h =================================================================== --- include/lldb/Target/Process.h +++ include/lldb/Target/Process.h @@ -1508,7 +1508,8 @@ size_t GetThreadStatus(Stream &ostrm, bool only_threads_with_stop_reason, uint32_t start_frame, uint32_t num_frames, - uint32_t num_frames_with_source); + uint32_t num_frames_with_source, + bool stop_format); void SendAsyncInterrupt(); Index: include/lldb/Target/Thread.h =================================================================== --- include/lldb/Target/Thread.h +++ include/lldb/Target/Thread.h @@ -499,8 +499,11 @@ // thread for all memory threads each time we stop. } - void DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx); - + // If stop_format is true, this will be the form used when we print stop info. + // If false, it will be the form we use for thread list and co. + void DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx, + bool stop_format); + bool GetDescription(Stream &s, lldb::DescriptionLevel level, bool print_json_thread, bool print_json_stopinfo); @@ -1150,7 +1153,8 @@ GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr); size_t GetStatus(Stream &strm, uint32_t start_frame, uint32_t num_frames, - uint32_t num_frames_with_source); + uint32_t num_frames_with_source, + bool stop_format); size_t GetStackFrameStatus(Stream &strm, uint32_t first_frame, uint32_t num_frames, bool show_frame_info, Index: scripts/interface/SBThread.i =================================================================== --- scripts/interface/SBThread.i +++ scripts/interface/SBThread.i @@ -323,6 +323,15 @@ bool GetDescription (lldb::SBStream &description) const; + %feature("docstring", " + //-------------------------------------------------------------------------- + /// Get the description strings for this thread that match what the + /// lldb driver will present, using the thread-format (stop_format==false) + /// or thread-stop-format (stop_format = true). + //-------------------------------------------------------------------------- + ") GetDescription; + bool GetDescription(lldb::SBStream &description, bool stop_format) const; + bool GetStatus (lldb::SBStream &status) const; Index: source/API/SBThread.cpp =================================================================== --- source/API/SBThread.cpp +++ source/API/SBThread.cpp @@ -1328,7 +1328,7 @@ ExecutionContext exe_ctx(m_opaque_sp.get(), lock); if (exe_ctx.HasThreadScope()) { - exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); + exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true); } else strm.PutCString("No status"); @@ -1336,6 +1336,10 @@ } bool SBThread::GetDescription(SBStream &description) const { + return GetDescription(description, false); +} + +bool SBThread::GetDescription(SBStream &description, bool stop_format) const { Stream &strm = description.ref(); std::unique_lock lock; @@ -1343,7 +1347,8 @@ if (exe_ctx.HasThreadScope()) { exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, - LLDB_INVALID_THREAD_ID); + LLDB_INVALID_THREAD_ID, + stop_format); // strm.Printf("SBThread: tid = 0x%4.4" PRIx64, // exe_ctx.GetThreadPtr()->GetID()); } else Index: source/Commands/CommandObjectMemory.cpp =================================================================== --- source/Commands/CommandObjectMemory.cpp +++ source/Commands/CommandObjectMemory.cpp @@ -1672,8 +1672,9 @@ HistoryThreads thread_list = memory_history->GetHistoryThreads(addr); + const bool stop_format = false; for (auto thread : thread_list) { - thread->GetStatus(*output_stream, 0, UINT32_MAX, 0); + thread->GetStatus(*output_stream, 0, UINT32_MAX, 0, stop_format); } result.SetStatus(eReturnStatusSuccessFinishResult); Index: source/Commands/CommandObjectProcess.cpp =================================================================== --- source/Commands/CommandObjectProcess.cpp +++ source/Commands/CommandObjectProcess.cpp @@ -1352,9 +1352,10 @@ const uint32_t start_frame = 0; const uint32_t num_frames = 1; const uint32_t num_frames_with_source = 1; + const bool stop_format = true; process->GetStatus(strm); process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame, - num_frames, num_frames_with_source); + num_frames, num_frames_with_source, stop_format); return result.Succeeded(); } }; Index: source/Commands/CommandObjectTarget.cpp =================================================================== --- source/Commands/CommandObjectTarget.cpp +++ source/Commands/CommandObjectTarget.cpp @@ -107,10 +107,11 @@ const uint32_t start_frame = 0; const uint32_t num_frames = 1; const uint32_t num_frames_with_source = 1; + const bool stop_format = false; process_sp->GetStatus(strm); process_sp->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame, num_frames, - num_frames_with_source); + num_frames_with_source, stop_format); } } Index: source/Commands/CommandObjectThread.cpp =================================================================== --- source/Commands/CommandObjectThread.cpp +++ source/Commands/CommandObjectThread.cpp @@ -248,9 +248,11 @@ thread->shared_from_this(), type); if (ext_thread_sp && ext_thread_sp->IsValid()) { const uint32_t num_frames_with_source = 0; + const bool stop_format = false; if (ext_thread_sp->GetStatus(strm, m_options.m_start, m_options.m_count, - num_frames_with_source)) { + num_frames_with_source, + stop_format)) { DoExtendedBacktrace(ext_thread_sp.get(), result); } } @@ -277,7 +279,7 @@ const uint32_t num_frames_with_source = 0; if (!thread->GetStatus(strm, m_options.m_start, m_options.m_count, - num_frames_with_source)) { + num_frames_with_source, false)) { result.AppendErrorWithFormat( "error displaying backtrace for thread: \"0x%4.4x\"\n", thread->GetIndexID()); @@ -1308,7 +1310,7 @@ const uint32_t num_frames_with_source = 0; process->GetStatus(strm); process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame, - num_frames, num_frames_with_source); + num_frames, num_frames_with_source, false); return result.Succeeded(); } }; Index: source/Core/Debugger.cpp =================================================================== --- source/Core/Debugger.cpp +++ source/Core/Debugger.cpp @@ -97,7 +97,8 @@ #define MODULE_WITH_FUNC \ "{ " \ - "${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" + "${module.file.basename}{`${function.name-with-args}" \ + "{${frame.no-debug}${function.pc-offset}}}}" #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" #define IS_OPTIMIZED "{${function.is-optimized} [opt]}" @@ -113,8 +114,18 @@ "{\\nCompleted expression: ${thread.completed-expression}}" \ "\\n" +#define DEFAULT_THREAD_STOP_FORMAT \ + "thread #${thread.index}{, name = '${thread.name}'}" \ + "{, queue = '${thread.queue}'}" \ + "{, activity = '${thread.info.activity.name}'}" \ + "{, ${thread.info.trace_messages} messages}" \ + "{, stop reason = ${thread.stop-reason}}" \ + "{\\nReturn value: ${thread.return-value}}" \ + "{\\nCompleted expression: ${thread.completed-expression}}" \ + "\\n" + #define DEFAULT_FRAME_FORMAT \ - "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC FILE_AND_LINE \ + "frame #${frame.index}:{ ${frame.no-debug}${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \ IS_OPTIMIZED "\\n" // Three parts to this disassembly format specification: @@ -210,6 +221,10 @@ {"thread-format", OptionValue::eTypeFormatEntity, true, 0, DEFAULT_THREAD_FORMAT, nullptr, "The default thread format string to use " "when displaying thread information."}, + {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0, + DEFAULT_THREAD_STOP_FORMAT, nullptr, "The default thread format " + "string to usewhen displaying thread " + "information as part of the stop display."}, {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "Whether to use an external editor or not."}, {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, @@ -247,6 +262,7 @@ ePropertyStopShowColumnAnsiSuffix, ePropertyTerminalWidth, ePropertyThreadFormat, + ePropertyThreadStopFormat, ePropertyUseExternalEditor, ePropertyUseColor, ePropertyAutoOneLineSummaries, @@ -359,6 +375,11 @@ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); } +const FormatEntity::Entry *Debugger::GetThreadStopFormat() const { + const uint32_t idx = ePropertyThreadStopFormat; + return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); +} + lldb::ScriptLanguage Debugger::GetScriptLanguage() const { const uint32_t idx = ePropertyScriptLanguage; return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration( @@ -1460,12 +1481,13 @@ // and all we do for that is just reprint the thread status for that thread. using namespace lldb; const uint32_t event_type = event_sp->GetType(); + const bool stop_format = true; if (event_type == Thread::eBroadcastBitStackChanged || event_type == Thread::eBroadcastBitThreadSelected) { ThreadSP thread_sp( Thread::ThreadEventData::GetThreadFromEvent(event_sp.get())); if (thread_sp) { - thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1); + thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format); } } } Index: source/Core/FormatEntity.cpp =================================================================== --- source/Core/FormatEntity.cpp +++ source/Core/FormatEntity.cpp @@ -97,6 +97,7 @@ ENTRY("fp", FrameRegisterFP, UInt64), ENTRY("sp", FrameRegisterSP, UInt64), ENTRY("flags", FrameRegisterFlags, UInt64), + ENTRY("no-debug", FrameNoDebug, None), ENTRY_CHILDREN("reg", FrameRegisterByName, UInt64, g_string_entry), }; @@ -320,6 +321,7 @@ ENUM_TO_CSTR(File); ENUM_TO_CSTR(Lang); ENUM_TO_CSTR(FrameIndex); + ENUM_TO_CSTR(FrameNoDebug); ENUM_TO_CSTR(FrameRegisterPC); ENUM_TO_CSTR(FrameRegisterSP); ENUM_TO_CSTR(FrameRegisterFP); @@ -1445,6 +1447,15 @@ } return false; + case Entry::Type::FrameNoDebug: + if (exe_ctx) { + StackFrame *frame = exe_ctx->GetFramePtr(); + if (frame) { + return !frame->HasDebugInformation(); + } + } + return true; + case Entry::Type::FrameRegisterByName: if (exe_ctx) { StackFrame *frame = exe_ctx->GetFramePtr(); Index: source/Target/Process.cpp =================================================================== --- source/Target/Process.cpp +++ source/Target/Process.cpp @@ -1199,10 +1199,12 @@ const uint32_t start_frame = 0; const uint32_t num_frames = 1; const uint32_t num_frames_with_source = 1; + const bool stop_format = true; process_sp->GetStatus(*stream); process_sp->GetThreadStatus(*stream, only_threads_with_stop_reason, start_frame, num_frames, - num_frames_with_source); + num_frames_with_source, + stop_format); if (curr_thread_stop_info_sp) { lldb::addr_t crashing_address; ValueObjectSP valobj_sp = StopInfo::GetCrashingDereference( @@ -5789,7 +5791,8 @@ size_t Process::GetThreadStatus(Stream &strm, bool only_threads_with_stop_reason, uint32_t start_frame, uint32_t num_frames, - uint32_t num_frames_with_source) { + uint32_t num_frames_with_source, + bool stop_format) { size_t num_thread_infos_dumped = 0; // You can't hold the thread list lock while calling Thread::GetStatus. That @@ -5820,7 +5823,8 @@ continue; } thread_sp->GetStatus(strm, start_frame, num_frames, - num_frames_with_source); + num_frames_with_source, + stop_format); ++num_thread_infos_dumped; } else { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); Index: source/Target/Thread.cpp =================================================================== --- source/Target/Thread.cpp +++ source/Target/Thread.cpp @@ -1769,7 +1769,8 @@ return Error(); } -void Thread::DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx) { +void Thread::DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx, + bool stop_format) { ExecutionContext exe_ctx(shared_from_this()); Process *process = exe_ctx.GetProcessPtr(); if (process == nullptr) @@ -1785,8 +1786,12 @@ } } - const FormatEntity::Entry *thread_format = - exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat(); + const FormatEntity::Entry *thread_format; + if (stop_format) + thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadStopFormat(); + else + thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat(); + assert(thread_format); FormatEntity::Format(*thread_format, strm, frame_sp ? &frame_sc : nullptr, @@ -1876,7 +1881,8 @@ } size_t Thread::GetStatus(Stream &strm, uint32_t start_frame, - uint32_t num_frames, uint32_t num_frames_with_source) { + uint32_t num_frames, uint32_t num_frames_with_source, + bool stop_format) { ExecutionContext exe_ctx(shared_from_this()); Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); @@ -1900,7 +1906,7 @@ } } - DumpUsingSettingsFormat(strm, start_frame); + DumpUsingSettingsFormat(strm, start_frame, stop_format); if (num_frames > 0) { strm.IndentMore(); @@ -1926,7 +1932,8 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level, bool print_json_thread, bool print_json_stopinfo) { - DumpUsingSettingsFormat(strm, 0); + const bool stop_format = false; + DumpUsingSettingsFormat(strm, 0, stop_format); strm.Printf("\n"); StructuredData::ObjectSP thread_info = GetExtendedInfo(); Index: www/formats.html =================================================================== --- www/formats.html +++ www/formats.html @@ -75,6 +75,7 @@ file.fullpathThe current compile unit file fullpath for the current frame. languageThe current compile unit language for the current frame. frame.indexThe frame index (0, 1, 2, 3...) + frame.no-debugEvaluates to true if the frame has no debug info. frame.pcThe generic frame register for the program counter. frame.spThe generic frame register for the stack pointer. frame.fpThe generic frame register for the frame pointer.