diff options
| author | Med Ismail Bennani <medismail.bennani@gmail.com> | 2020-01-23 15:11:53 +0100 |
|---|---|---|
| committer | Med Ismail Bennani <medismail.bennani@gmail.com> | 2020-01-28 18:21:29 +0100 |
| commit | 03a6b858fde5c644ec16b1fddd8e10aa9ef3f0ad (patch) | |
| tree | b28dcf032fd397b646789512e937c9fcf812a378 /lldb/source/Target/Thread.cpp | |
| parent | 7f93ff58e1bfbfdbb91a4be5271f9f880016e950 (diff) | |
[lldb/Target] Add Assert StackFrame Recognizer
When a thread stops, this checks depending on the platform if the top frame is
an abort stack frame. If so, it looks for an assert stack frame in the upper
frames and set it as the most relavant frame when found.
To do so, the StackFrameRecognizer class holds a "Most Relevant Frame" and a
"cooked" stop reason description. When the thread is about to stop, it checks
if the current frame is recognized, and if so, it fetches the recognized frame's
attributes and applies them.
rdar://58528686
Differential Revision: https://reviews.llvm.org/D73303
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
Diffstat (limited to 'lldb/source/Target/Thread.cpp')
| -rw-r--r-- | lldb/source/Target/Thread.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 82930ded21a1..75df5310f488 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -573,9 +573,64 @@ void Thread::SetState(StateType state) { m_state = state; } +llvm::StringRef Thread::GetStopDescription() { + StackFrameSP frame_sp = GetStackFrameAtIndex(0); + + if (!frame_sp) + return GetStopDescriptionRaw(); + + auto recognized_frame_sp = frame_sp->GetRecognizedFrame(); + + if (!recognized_frame_sp) + return GetStopDescriptionRaw(); + + llvm::StringRef recognized_stop_description = + recognized_frame_sp->GetStopDescription(); + + if (!recognized_stop_description.empty()) + return recognized_stop_description; + + return GetStopDescriptionRaw(); +} + +llvm::StringRef Thread::GetStopDescriptionRaw() { + StopInfoSP stop_info_sp = GetStopInfo(); + llvm::StringRef raw_stop_description; + if (stop_info_sp && stop_info_sp->IsValid()) + raw_stop_description = stop_info_sp->GetDescription(); + return raw_stop_description; +} + +void Thread::SelectMostRelevantFrame() { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD); + + auto frames_list_sp = GetStackFrameList(); + + // Only the top frame should be recognized. + auto frame_sp = frames_list_sp->GetFrameAtIndex(0); + + auto recognized_frame_sp = frame_sp->GetRecognizedFrame(); + + if (!recognized_frame_sp) { + LLDB_LOG(log, "Frame #0 not recognized"); + return; + } + + if (StackFrameSP most_relevant_frame_sp = + recognized_frame_sp->GetMostRelevantFrame()) { + LLDB_LOG(log, "Found most relevant frame at index {0}", + most_relevant_frame_sp->GetFrameIndex()); + SetSelectedFrame(most_relevant_frame_sp.get()); + } else { + LLDB_LOG(log, "No relevant frame!"); + } +} + void Thread::WillStop() { ThreadPlan *current_plan = GetCurrentPlan(); + SelectMostRelevantFrame(); + // FIXME: I may decide to disallow threads with no plans. In which // case this should go to an assert. |
