Skip to content

Commit e660e65

Browse files
[lldb] Add an API to derive language-specific runtime information (llvm#116904)
This is motivated by exposing some Swift language-specific flags through the API, in the example here it is used to communicate the Objective-C runtime version. This could also be a meaningful extension point to get information about "embedded: languages, such as extracting the C++ version in an Objective-C++ frame or something along those lines.
1 parent fb4ecad commit e660e65

File tree

12 files changed

+80
-0
lines changed

12 files changed

+80
-0
lines changed

lldb/include/lldb/API/SBFrame.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ class LLDB_API SBFrame {
122122
lldb::SBValue EvaluateExpression(const char *expr,
123123
const SBExpressionOptions &options);
124124

125+
/// Language plugins can use this API to report language-specific
126+
/// runtime information about this compile unit, such as additional
127+
/// language version details or feature flags.
128+
SBStructuredData GetLanguageInfo();
129+
125130
/// Gets the lexical block that defines the stack frame. Another way to think
126131
/// of this is it will return the block that contains all of the variables
127132
/// for a stack frame. Inlined functions are represented as SBBlock objects

lldb/include/lldb/API/SBStructuredData.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class SBStructuredData {
114114
friend class SBCommandReturnObject;
115115
friend class SBLaunchInfo;
116116
friend class SBDebugger;
117+
friend class SBFrame;
117118
friend class SBTarget;
118119
friend class SBProcess;
119120
friend class SBThread;

lldb/include/lldb/Target/LanguageRuntime.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ class LanguageRuntime : public Runtime, public PluginInterface {
241241
lldb_private::RegisterContext *regctx,
242242
bool &behaves_like_zeroth_frame);
243243

244+
/// Language runtime plugins can use this API to report
245+
/// language-specific runtime information about this compile unit,
246+
/// such as additional language version details or feature flags.
247+
virtual StructuredData::ObjectSP GetLanguageInfo(SymbolContext sc);
248+
244249
protected:
245250
// The static GetRuntimeUnwindPlan method above is only implemented in the
246251
// base class; subclasses may override this protected member if they can

lldb/include/lldb/Target/StackFrame.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lldb/Utility/Scalar.h"
2323
#include "lldb/Utility/Status.h"
2424
#include "lldb/Utility/StreamString.h"
25+
#include "lldb/Utility/StructuredData.h"
2526
#include "lldb/Utility/UserID.h"
2627
#include "lldb/ValueObject/ValueObjectList.h"
2728

@@ -408,6 +409,11 @@ class StackFrame : public ExecutionContextScope,
408409
/// system implementation details this way.
409410
bool IsHidden();
410411

412+
/// Language plugins can use this API to report language-specific
413+
/// runtime information about this compile unit, such as additional
414+
/// language version details or feature flags.
415+
StructuredData::ObjectSP GetLanguageInfo();
416+
411417
/// Get the frame's demangled name.
412418
///
413419
/// /// \return

lldb/source/API/SBFrame.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "lldb/API/SBExpressionOptions.h"
4848
#include "lldb/API/SBFormat.h"
4949
#include "lldb/API/SBStream.h"
50+
#include "lldb/API/SBStructuredData.h"
5051
#include "lldb/API/SBSymbolContext.h"
5152
#include "lldb/API/SBThread.h"
5253
#include "lldb/API/SBValue.h"
@@ -1154,6 +1155,21 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
11541155
return expr_result;
11551156
}
11561157

1158+
SBStructuredData SBFrame::GetLanguageInfo() {
1159+
LLDB_INSTRUMENT_VA(this);
1160+
1161+
SBStructuredData sb_data;
1162+
std::unique_lock<std::recursive_mutex> lock;
1163+
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1164+
StackFrame *frame = exe_ctx.GetFramePtr();
1165+
if (!frame)
1166+
return sb_data;
1167+
1168+
StructuredData::ObjectSP data(frame->GetLanguageInfo());
1169+
sb_data.m_impl_up->SetObjectSP(data);
1170+
return sb_data;
1171+
}
1172+
11571173
bool SBFrame::IsInlined() {
11581174
LLDB_INSTRUMENT_VA(this);
11591175

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,6 +3398,13 @@ std::optional<uint64_t> AppleObjCRuntimeV2::GetSharedCacheImageHeaderVersion() {
33983398
return std::nullopt;
33993399
}
34003400

3401+
StructuredData::ObjectSP AppleObjCRuntimeV2::GetLanguageInfo(SymbolContext sc) {
3402+
auto dict_up = std::make_unique<StructuredData::Dictionary>();
3403+
dict_up->AddItem("Objective-C runtime version",
3404+
std::make_unique<StructuredData::UnsignedInteger>(2));
3405+
return dict_up;
3406+
}
3407+
34013408
#pragma mark Frame recognizers
34023409

34033410
class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime {
106106

107107
std::optional<uint64_t> GetSharedCacheImageHeaderVersion();
108108

109+
StructuredData::ObjectSP GetLanguageInfo(SymbolContext sc) override;
110+
109111
protected:
110112
lldb::BreakpointResolverSP
111113
CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,

lldb/source/Target/LanguageRuntime.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ LanguageRuntime::GetRuntimeUnwindPlan(Thread &thread, RegisterContext *regctx,
277277
return UnwindPlanSP();
278278
}
279279

280+
StructuredData::ObjectSP LanguageRuntime::GetLanguageInfo(SymbolContext sc) {
281+
return {};
282+
}
283+
280284
void LanguageRuntime::InitializeCommands(CommandObject *parent) {
281285
if (!parent)
282286
return;

lldb/source/Target/StackFrame.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lldb/Symbol/VariableList.h"
2323
#include "lldb/Target/ABI.h"
2424
#include "lldb/Target/ExecutionContext.h"
25+
#include "lldb/Target/LanguageRuntime.h"
2526
#include "lldb/Target/Process.h"
2627
#include "lldb/Target/RegisterContext.h"
2728
#include "lldb/Target/StackFrameRecognizer.h"
@@ -1230,6 +1231,18 @@ bool StackFrame::IsHidden() {
12301231
return false;
12311232
}
12321233

1234+
StructuredData::ObjectSP StackFrame::GetLanguageInfo() {
1235+
auto process_sp = CalculateProcess();
1236+
SourceLanguage language = GetLanguage();
1237+
if (!language)
1238+
return {};
1239+
if (auto runtime_sp =
1240+
process_sp->GetLanguageRuntime(language.AsLanguageType()))
1241+
return runtime_sp->GetLanguageInfo(
1242+
GetSymbolContext(eSymbolContextFunction));
1243+
return {};
1244+
}
1245+
12331246
const char *StackFrame::GetFunctionName() {
12341247
const char *name = nullptr;
12351248
SymbolContext sc = GetSymbolContext(
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
OBJC_SOURCES := main.m
2+
LD_EXTRAS := -lobjc
3+
4+
include Makefile.rules
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
7+
class ObjCiVarIMPTestCase(TestBase):
8+
@skipUnlessDarwin
9+
@no_debug_info_test
10+
def test_imp_ivar_type(self):
11+
self.build()
12+
target, process, thread, bkpt = lldbutil.run_to_name_breakpoint(self, "main")
13+
frame = thread.GetFrameAtIndex(0)
14+
lang_info = frame.GetLanguageInfo()
15+
version = lang_info.GetValueForKey("Objective-C runtime version")
16+
self.assertEqual(version.GetIntegerValue(), 2)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int main(int argc, char const *argv[]) { return 0; }

0 commit comments

Comments
 (0)