Skip to content

Commit 93e584a

Browse files
Merge pull request #9179 from adrian-prantl/126629381-swift
Implement Swift hidden frame recognizers
2 parents d781e3c + e07af78 commit 93e584a

File tree

60 files changed

+891
-430
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+891
-430
lines changed

lldb/bindings/python/python-wrapper.swig

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSWIGPython_CreateFrameRecogni
813813
}
814814

815815
PyObject *lldb_private::python::SWIGBridge::LLDBSwigPython_GetRecognizedArguments(
816-
PyObject * implementor, const lldb::StackFrameSP &frame_sp) {
816+
PyObject *implementor, const lldb::StackFrameSP &frame_sp) {
817817
static char callee_name[] = "get_recognized_arguments";
818818

819819
PythonObject arg = SWIGBridge::ToSWIGWrapper(frame_sp);
@@ -824,6 +824,22 @@ PyObject *lldb_private::python::SWIGBridge::LLDBSwigPython_GetRecognizedArgument
824824
return result;
825825
}
826826

827+
bool lldb_private::python::SWIGBridge::LLDBSwigPython_ShouldHide(
828+
PyObject *implementor, const lldb::StackFrameSP &frame_sp) {
829+
static char callee_name[] = "should_hide";
830+
831+
PythonObject arg = SWIGBridge::ToSWIGWrapper(frame_sp);
832+
833+
PythonString str(callee_name);
834+
835+
PyObject *result =
836+
PyObject_CallMethodObjArgs(implementor, str.get(), arg.get(), NULL);
837+
bool ret_val = result ? PyObject_IsTrue(result) : false;
838+
Py_XDECREF(result);
839+
840+
return ret_val;
841+
}
842+
827843
void *lldb_private::python::SWIGBridge::LLDBSWIGPython_GetDynamicSetting(
828844
void *module, const char *setting, const lldb::TargetSP &target_sp) {
829845
if (!module || !setting)

lldb/include/lldb/API/SBFrame.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ class LLDB_API SBFrame {
108108

109109
bool IsArtificial() const;
110110

111+
/// Return whether a frame recognizer decided this frame should not
112+
/// be displayes in backtraces etc.
113+
bool IsHidden() const;
114+
111115
/// The version that doesn't supply a 'use_dynamic' value will use the
112116
/// target's default.
113117
lldb::SBValue EvaluateExpression(const char *expr);

lldb/include/lldb/Interpreter/CommandObject.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -369,13 +369,14 @@ class CommandObject : public std::enable_shared_from_this<CommandObject> {
369369
"currently stopped.";
370370
}
371371

372-
// This is for use in the command interpreter, when you either want the
373-
// selected target, or if no target is present you want to prime the dummy
374-
// target with entities that will be copied over to new targets.
375-
Target &GetSelectedOrDummyTarget(bool prefer_dummy = false);
376-
Target &GetSelectedTarget();
377372
Target &GetDummyTarget();
378373

374+
// This is for use in the command interpreter, and returns the most relevant
375+
// target. In order of priority, that's the target from the command object's
376+
// execution context, the target from the interpreter's execution context, the
377+
// selected target or the dummy target.
378+
Target &GetTarget();
379+
379380
// If a command needs to use the "current" thread, use this call. Command
380381
// objects will have an ExecutionContext to use, and that may or may not have
381382
// a thread in it. If it does, you should use that by default, if not, then

lldb/include/lldb/Interpreter/ScriptInterpreter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ class ScriptInterpreter : public PluginInterface {
252252
return lldb::ValueObjectListSP();
253253
}
254254

255+
virtual bool ShouldHide(const StructuredData::ObjectSP &implementor,
256+
lldb::StackFrameSP frame_sp) {
257+
return false;
258+
}
259+
255260
virtual StructuredData::GenericSP
256261
CreateScriptedBreakpointResolver(const char *class_name,
257262
const StructuredDataImpl &args_data,

lldb/include/lldb/Target/StackFrame.h

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,11 @@ class StackFrame : public ExecutionContextScope,
407407
/// may have limited support for inspecting variables.
408408
bool IsArtificial() const;
409409

410+
/// Query whether this frame should be hidden from backtraces. Frame
411+
/// recognizers can customize this behavior and hide distracting
412+
/// system implementation details this way.
413+
bool IsHidden();
414+
410415
/// Query this frame to find what frame it is in this Thread's
411416
/// StackFrameList.
412417
///
@@ -518,33 +523,36 @@ class StackFrame : public ExecutionContextScope,
518523
bool HasCachedData() const;
519524

520525
private:
521-
// For StackFrame only
526+
/// For StackFrame only.
527+
/// \{
522528
lldb::ThreadWP m_thread_wp;
523529
uint32_t m_frame_index;
524530
uint32_t m_concrete_frame_index;
525531
lldb::RegisterContextSP m_reg_context_sp;
526532
StackID m_id;
527-
Address m_frame_code_addr; // The frame code address (might not be the same as
528-
// the actual PC for inlined frames) as a
529-
// section/offset address
533+
/// \}
534+
535+
/// The frame code address (might not be the same as the actual PC
536+
/// for inlined frames) as a section/offset address.
537+
Address m_frame_code_addr;
530538
SymbolContext m_sc;
531539
Flags m_flags;
532540
Scalar m_frame_base;
533541
Status m_frame_base_error;
534-
bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA ==
535-
// LLDB_INVALID_ADDRESS
542+
uint16_t m_frame_recognizer_generation = 0;
543+
/// Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS.
544+
bool m_cfa_is_valid;
536545
Kind m_stack_frame_kind;
537546

538-
// Whether this frame behaves like the zeroth frame, in the sense
539-
// that its pc value might not immediately follow a call (and thus might
540-
// be the first address of its function). True for actual frame zero as
541-
// well as any other frame with the same trait.
547+
/// Whether this frame behaves like the zeroth frame, in the sense
548+
/// that its pc value might not immediately follow a call (and thus might
549+
/// be the first address of its function). True for actual frame zero as
550+
/// well as any other frame with the same trait.
542551
bool m_behaves_like_zeroth_frame;
543552
lldb::VariableListSP m_variable_list_sp;
544-
ValueObjectList m_variable_list_value_objects; // Value objects for each
545-
// variable in
546-
// m_variable_list_sp
547-
lldb::RecognizedStackFrameSP m_recognized_frame_sp;
553+
/// Value objects for each variable in m_variable_list_sp.
554+
ValueObjectList m_variable_list_value_objects;
555+
std::optional<lldb::RecognizedStackFrameSP> m_recognized_frame_sp;
548556
StreamString m_disassembly;
549557
std::recursive_mutex m_mutex;
550558

lldb/include/lldb/Target/StackFrameList.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class StackFrameList {
9191

9292
size_t GetStatus(Stream &strm, uint32_t first_frame, uint32_t num_frames,
9393
bool show_frame_info, uint32_t num_frames_with_source,
94-
bool show_unique = false,
94+
bool show_unique = false, bool show_hidden = false,
9595
const char *frame_marker = nullptr);
9696

9797
protected:

lldb/include/lldb/Target/StackFrameRecognizer.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "lldb/lldb-private-forward.h"
1818
#include "lldb/lldb-public.h"
1919

20+
#include <cstdint>
2021
#include <deque>
2122
#include <optional>
2223
#include <vector>
@@ -28,20 +29,23 @@ namespace lldb_private {
2829
/// This class provides extra information about a stack frame that was
2930
/// provided by a specific stack frame recognizer. Right now, this class only
3031
/// holds recognized arguments (via GetRecognizedArguments).
31-
3232
class RecognizedStackFrame
3333
: public std::enable_shared_from_this<RecognizedStackFrame> {
3434
public:
35+
virtual ~RecognizedStackFrame() = default;
36+
3537
virtual lldb::ValueObjectListSP GetRecognizedArguments() {
3638
return m_arguments;
3739
}
3840
virtual lldb::ValueObjectSP GetExceptionObject() {
3941
return lldb::ValueObjectSP();
4042
}
41-
virtual lldb::StackFrameSP GetMostRelevantFrame() { return nullptr; };
42-
virtual ~RecognizedStackFrame() = default;
43+
virtual lldb::StackFrameSP GetMostRelevantFrame() { return nullptr; }
4344

4445
std::string GetStopDescription() { return m_stop_desc; }
46+
/// Controls whether this frame should be filtered out when
47+
/// displaying backtraces, for example.
48+
virtual bool ShouldHide() { return false; }
4549

4650
protected:
4751
lldb::ValueObjectListSP m_arguments;
@@ -53,7 +57,6 @@ class RecognizedStackFrame
5357
/// A base class for frame recognizers. Subclasses (actual frame recognizers)
5458
/// should implement RecognizeFrame to provide a RecognizedStackFrame for a
5559
/// given stack frame.
56-
5760
class StackFrameRecognizer
5861
: public std::enable_shared_from_this<StackFrameRecognizer> {
5962
public:
@@ -73,10 +76,10 @@ class StackFrameRecognizer
7376
/// Python implementation for frame recognizers. An instance of this class
7477
/// tracks a particular Python classobject, which will be asked to recognize
7578
/// stack frames.
76-
7779
class ScriptedStackFrameRecognizer : public StackFrameRecognizer {
7880
lldb_private::ScriptInterpreter *m_interpreter;
7981
lldb_private::StructuredData::ObjectSP m_python_object_sp;
82+
8083
std::string m_python_class;
8184

8285
public:
@@ -106,15 +109,21 @@ class StackFrameRecognizerManager {
106109
ConstString module, llvm::ArrayRef<ConstString> symbols,
107110
bool first_instruction_only = true);
108111

112+
/// Add a new recognizer that triggers on a symbol regex.
113+
///
114+
/// \param symbol_mangling controls whether the regex should apply
115+
/// to the mangled or demangled name.
109116
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
110117
lldb::RegularExpressionSP module,
111118
lldb::RegularExpressionSP symbol,
119+
Mangled::NamePreference symbol_mangling,
112120
bool first_instruction_only = true);
113121

114122
void ForEach(std::function<
115123
void(uint32_t recognizer_id, std::string recognizer_name,
116124
std::string module, llvm::ArrayRef<ConstString> symbols,
117-
bool regexp)> const &callback);
125+
Mangled::NamePreference name_reference, bool regexp)> const
126+
&callback);
118127

119128
bool RemoveRecognizerWithID(uint32_t recognizer_id);
120129

@@ -123,8 +132,14 @@ class StackFrameRecognizerManager {
123132
lldb::StackFrameRecognizerSP GetRecognizerForFrame(lldb::StackFrameSP frame);
124133

125134
lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame);
135+
/// Returns a number that changes whenever the list of recognizers
136+
/// has been modified.
137+
uint16_t GetGeneration() const { return m_generation; }
126138

127139
private:
140+
/// Increase the generation counter.
141+
void BumpGeneration();
142+
128143
struct RegisteredEntry {
129144
uint32_t recognizer_id;
130145
lldb::StackFrameRecognizerSP recognizer;
@@ -133,18 +148,19 @@ class StackFrameRecognizerManager {
133148
lldb::RegularExpressionSP module_regexp;
134149
std::vector<ConstString> symbols;
135150
lldb::RegularExpressionSP symbol_regexp;
151+
Mangled::NamePreference symbol_mangling;
136152
bool first_instruction_only;
137153
};
138154

139155
std::deque<RegisteredEntry> m_recognizers;
156+
uint16_t m_generation = 0;
140157
};
141158

142159
/// \class ValueObjectRecognizerSynthesizedValue
143160
///
144161
/// ValueObject subclass that presents the passed ValueObject as a recognized
145162
/// value with the specified ValueType. Frame recognizers should return
146163
/// instances of this class as the returned objects in GetRecognizedArguments().
147-
148164
class ValueObjectRecognizerSynthesizedValue : public ValueObject {
149165
public:
150166
static lldb::ValueObjectSP Create(ValueObject &parent, lldb::ValueType type) {

lldb/include/lldb/Target/Thread.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,11 +1158,11 @@ class Thread : public std::enable_shared_from_this<Thread>,
11581158

11591159
size_t GetStatus(Stream &strm, uint32_t start_frame, uint32_t num_frames,
11601160
uint32_t num_frames_with_source, bool stop_format,
1161-
bool only_stacks = false);
1161+
bool show_hidden, bool only_stacks = false);
11621162

11631163
size_t GetStackFrameStatus(Stream &strm, uint32_t first_frame,
11641164
uint32_t num_frames, bool show_frame_info,
1165-
uint32_t num_frames_with_source);
1165+
uint32_t num_frames_with_source, bool show_hidden);
11661166

11671167
// We need a way to verify that even though we have a thread in a shared
11681168
// pointer that the object itself is still valid. Currently this won't be the

lldb/source/API/SBFrame.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,13 +1204,24 @@ bool SBFrame::IsArtificial() const {
12041204
std::unique_lock<std::recursive_mutex> lock;
12051205
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12061206

1207-
StackFrame *frame = exe_ctx.GetFramePtr();
1208-
if (frame)
1207+
if (StackFrame *frame = exe_ctx.GetFramePtr())
12091208
return frame->IsArtificial();
12101209

12111210
return false;
12121211
}
12131212

1213+
bool SBFrame::IsHidden() const {
1214+
LLDB_INSTRUMENT_VA(this);
1215+
1216+
std::unique_lock<std::recursive_mutex> lock;
1217+
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1218+
1219+
if (StackFrame *frame = exe_ctx.GetFramePtr())
1220+
return frame->IsHidden();
1221+
1222+
return false;
1223+
}
1224+
12141225
const char *SBFrame::GetFunctionName() {
12151226
LLDB_INSTRUMENT_VA(this);
12161227

lldb/source/API/SBThread.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,8 @@ bool SBThread::GetStatus(SBStream &status) const {
12291229
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
12301230

12311231
if (exe_ctx.HasThreadScope()) {
1232-
exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1232+
exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true,
1233+
/*show_hidden=*/true);
12331234
} else
12341235
strm.PutCString("No status");
12351236

lldb/source/Commands/CommandCompletions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ void CommandCompletions::ThreadIndexes(CommandInterpreter &interpreter,
791791
lldb::ThreadSP thread_sp;
792792
for (uint32_t idx = 0; (thread_sp = threads.GetThreadAtIndex(idx)); ++idx) {
793793
StreamString strm;
794-
thread_sp->GetStatus(strm, 0, 1, 1, true);
794+
thread_sp->GetStatus(strm, 0, 1, 1, true, /*show_hidden*/ true);
795795
request.TryCompleteCurrentArg(std::to_string(thread_sp->GetIndexID()),
796796
strm.GetString());
797797
}
@@ -835,7 +835,7 @@ void CommandCompletions::ThreadIDs(CommandInterpreter &interpreter,
835835
lldb::ThreadSP thread_sp;
836836
for (uint32_t idx = 0; (thread_sp = threads.GetThreadAtIndex(idx)); ++idx) {
837837
StreamString strm;
838-
thread_sp->GetStatus(strm, 0, 1, 1, true);
838+
thread_sp->GetStatus(strm, 0, 1, 1, true, /*show_hidden*/ true);
839839
request.TryCompleteCurrentArg(std::to_string(thread_sp->GetID()),
840840
strm.GetString());
841841
}

0 commit comments

Comments
 (0)