18
18
#include " lldb/Target/Process.h"
19
19
#include " lldb/Target/RegisterContext.h"
20
20
#include " lldb/Target/StackFrame.h"
21
+ #include " lldb/Target/StackFrameRecognizer.h"
21
22
#include " lldb/Target/StopInfo.h"
22
23
#include " lldb/Target/Target.h"
23
24
#include " lldb/Target/Thread.h"
@@ -38,7 +39,7 @@ StackFrameList::StackFrameList(Thread &thread,
38
39
const lldb::StackFrameListSP &prev_frames_sp,
39
40
bool show_inline_frames)
40
41
: m_thread(thread), m_prev_frames_sp(prev_frames_sp), m_mutex(), m_frames(),
41
- m_selected_frame_idx(0 ), m_concrete_frames_fetched(0 ),
42
+ m_selected_frame_idx(), m_concrete_frames_fetched(0 ),
42
43
m_current_inlined_depth(UINT32_MAX),
43
44
m_current_inlined_pc(LLDB_INVALID_ADDRESS),
44
45
m_show_inlined_frames(show_inline_frames) {
@@ -252,7 +253,7 @@ struct CallDescriptor {
252
253
using CallSequence = std::vector<CallDescriptor>;
253
254
254
255
// / Find the unique path through the call graph from \p begin (with return PC
255
- // / \p return_pc) to \p end. On success this path is stored into \p path, and
256
+ // / \p return_pc) to \p end. On success this path is stored into \p path, and
256
257
// / on failure \p path is unchanged.
257
258
static void FindInterveningFrames (Function &begin, Function &end,
258
259
ExecutionContext &exe_ctx, Target &target,
@@ -776,9 +777,46 @@ bool StackFrameList::SetFrameAtIndex(uint32_t idx, StackFrameSP &frame_sp) {
776
777
return false ; // resize failed, out of memory?
777
778
}
778
779
779
- uint32_t StackFrameList::GetSelectedFrameIndex () const {
780
+ void StackFrameList::SelectMostRelevantFrame () {
781
+ // Don't call into the frame recognizers on the private state thread as
782
+ // they can cause code to run in the target, and that can cause deadlocks
783
+ // when fetching stop events for the expression.
784
+ if (m_thread.GetProcess ()->CurrentThreadIsPrivateStateThread ())
785
+ return ;
786
+
787
+ Log *log = GetLog (LLDBLog::Thread);
788
+
789
+ // Only the top frame should be recognized.
790
+ StackFrameSP frame_sp = GetFrameAtIndex (0 );
791
+ if (!frame_sp) {
792
+ LLDB_LOG (log, " Failed to construct Frame #0" );
793
+ return ;
794
+ }
795
+
796
+ RecognizedStackFrameSP recognized_frame_sp = frame_sp->GetRecognizedFrame ();
797
+
798
+ if (!recognized_frame_sp) {
799
+ LLDB_LOG (log, " Frame #0 not recognized" );
800
+ return ;
801
+ }
802
+
803
+ if (StackFrameSP most_relevant_frame_sp =
804
+ recognized_frame_sp->GetMostRelevantFrame ()) {
805
+ LLDB_LOG (log, " Found most relevant frame at index {0}" ,
806
+ most_relevant_frame_sp->GetFrameIndex ());
807
+ SetSelectedFrame (most_relevant_frame_sp.get ());
808
+ } else {
809
+ LLDB_LOG (log, " No relevant frame!" );
810
+ }
811
+ }
812
+
813
+ uint32_t StackFrameList::GetSelectedFrameIndex () {
780
814
std::lock_guard<std::recursive_mutex> guard (m_mutex);
781
- return m_selected_frame_idx;
815
+ if (!m_selected_frame_idx)
816
+ SelectMostRelevantFrame ();
817
+ if (!m_selected_frame_idx)
818
+ m_selected_frame_idx = 0 ;
819
+ return *m_selected_frame_idx;
782
820
}
783
821
784
822
uint32_t StackFrameList::SetSelectedFrame (lldb_private::StackFrame *frame) {
@@ -787,17 +825,19 @@ uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) {
787
825
const_iterator begin = m_frames.begin ();
788
826
const_iterator end = m_frames.end ();
789
827
m_selected_frame_idx = 0 ;
828
+
790
829
for (pos = begin; pos != end; ++pos) {
791
830
if (pos->get () == frame) {
792
831
m_selected_frame_idx = std::distance (begin, pos);
793
832
uint32_t inlined_depth = GetCurrentInlinedDepth ();
794
833
if (inlined_depth != UINT32_MAX)
795
- m_selected_frame_idx -= inlined_depth;
834
+ m_selected_frame_idx = *m_selected_frame_idx - inlined_depth;
796
835
break ;
797
836
}
798
837
}
838
+
799
839
SetDefaultFileAndLineToSelectedFrame ();
800
- return m_selected_frame_idx;
840
+ return * m_selected_frame_idx;
801
841
}
802
842
803
843
bool StackFrameList::SetSelectedFrameByIndex (uint32_t idx) {
@@ -825,10 +865,16 @@ void StackFrameList::SetDefaultFileAndLineToSelectedFrame() {
825
865
826
866
// The thread has been run, reset the number stack frames to zero so we can
827
867
// determine how many frames we have lazily.
868
+ // Note, we don't actually re-use StackFrameLists, we always make a new
869
+ // StackFrameList every time we stop, and then copy frame information frame
870
+ // by frame from the old to the new StackFrameList. So the comment above,
871
+ // does not describe how StackFrameLists are currently used.
872
+ // Clear is currently only used to clear the list in the destructor.
828
873
void StackFrameList::Clear () {
829
874
std::lock_guard<std::recursive_mutex> guard (m_mutex);
830
875
m_frames.clear ();
831
876
m_concrete_frames_fetched = 0 ;
877
+ m_selected_frame_idx.reset ();
832
878
}
833
879
834
880
lldb::StackFrameSP
0 commit comments