Skip to content

Commit d5c33aa

Browse files
committed
[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. (cherry picked from commit e660e65)
1 parent c60c1ea commit d5c33aa

File tree

11 files changed

+73
-17
lines changed

11 files changed

+73
-17
lines changed

lldb/include/lldb/API/SBFrame.h

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

130+
/// Language plugins can use this API to report language-specific
131+
/// runtime information about this compile unit, such as additional
132+
/// language version details or feature flags.
133+
SBStructuredData GetLanguageInfo();
134+
130135
/// Gets the lexical block that defines the stack frame. Another way to think
131136
/// of this is it will return the block that contains all of the variables
132137
/// for a stack frame. Inlined functions are represented as SBBlock objects

lldb/include/lldb/Target/LanguageRuntime.h

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

288+
/// Language runtime plugins can use this API to report
289+
/// language-specific runtime information about this compile unit,
290+
/// such as additional language version details or feature flags.
291+
virtual StructuredData::ObjectSP GetLanguageInfo(SymbolContext sc);
292+
288293
protected:
289294
// The static GetRuntimeUnwindPlan method above is only implemented in the
290295
// base class; subclasses may override this protected member if they can

lldb/include/lldb/Target/StackFrame.h

Lines changed: 5 additions & 6 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

@@ -416,12 +417,10 @@ class StackFrame : public ExecutionContextScope,
416417
LLDB_DEPRECATED("Use IsHidden() instead.")
417418
bool IsSwiftThunk();
418419

419-
/// Get this frame language specific data.
420-
///
421-
/// \return
422-
/// The StructuredDataImpl object containing the language specific data. Can
423-
/// be null.
424-
StructuredDataImpl *GetLanguageSpecificData();
420+
/// Language plugins can use this API to report language-specific
421+
/// runtime information about this compile unit, such as additional
422+
/// language version details or feature flags.
423+
StructuredData::ObjectSP GetLanguageInfo();
425424

426425
/// Get the frame's demangled name.
427426
///

lldb/source/API/SBFrame.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,21 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
11561156
return expr_result;
11571157
}
11581158

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

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

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

3414+
StructuredData::ObjectSP AppleObjCRuntimeV2::GetLanguageInfo(SymbolContext sc) {
3415+
auto dict_up = std::make_unique<StructuredData::Dictionary>();
3416+
dict_up->AddItem("Objective-C runtime version",
3417+
std::make_unique<StructuredData::UnsignedInteger>(2));
3418+
return dict_up;
3419+
}
3420+
34143421
#pragma mark Frame recognizers
34153422

34163423
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: 9 additions & 11 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"
@@ -1237,18 +1238,15 @@ bool StackFrame::IsSwiftThunk() {
12371238
return runtime->IsSymbolARuntimeThunk(*sc.symbol);
12381239
}
12391240

1240-
StructuredDataImpl *StackFrame::GetLanguageSpecificData() {
1241-
ThreadSP thread_sp = GetThread();
1242-
if (!thread_sp)
1241+
StructuredData::ObjectSP StackFrame::GetLanguageInfo() {
1242+
auto process_sp = CalculateProcess();
1243+
SourceLanguage language = GetLanguage();
1244+
if (!language)
12431245
return {};
1244-
ProcessSP process_sp = thread_sp->GetProcess();
1245-
if (!process_sp)
1246-
return {};
1247-
1248-
if (auto *runtime =
1249-
process_sp->GetLanguageRuntime(GuessLanguage().AsLanguageType()))
1250-
if (auto *data = runtime->GetLanguageSpecificData(*this))
1251-
return data;
1246+
if (auto runtime_sp =
1247+
process_sp->GetLanguageRuntime(language.AsLanguageType()))
1248+
return runtime_sp->GetLanguageInfo(
1249+
GetSymbolContext(eSymbolContextFunction));
12521250
return {};
12531251
}
12541252

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)