Skip to content

Commit 82dffd2

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) (cherry picked from commit d5c33aa) Conflicts: lldb/source/Target/StackFrame.cpp
1 parent badfa3b commit 82dffd2

File tree

11 files changed

+94
-6
lines changed

11 files changed

+94
-6
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

@@ -412,12 +413,10 @@ class StackFrame : public ExecutionContextScope,
412413
LLDB_DEPRECATED("Use IsHidden() instead.")
413414
bool IsSwiftThunk();
414415

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

422421
/// Get the frame's demangled name.
423422
///

lldb/source/API/SBFrame.cpp

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

1166+
SBStructuredData SBFrame::GetLanguageInfo() {
1167+
LLDB_INSTRUMENT_VA(this);
1168+
1169+
SBStructuredData sb_data;
1170+
std::unique_lock<std::recursive_mutex> lock;
1171+
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1172+
StackFrame *frame = exe_ctx.GetFramePtr();
1173+
if (!frame)
1174+
return sb_data;
1175+
1176+
StructuredData::ObjectSP data(frame->GetLanguageInfo());
1177+
sb_data.m_impl_up->SetObjectSP(data);
1178+
return sb_data;
1179+
}
1180+
11661181
bool SBFrame::IsInlined() {
11671182
LLDB_INSTRUMENT_VA(this);
11681183

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: 30 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"
@@ -1237,6 +1238,35 @@ bool StackFrame::IsHidden() {
12371238
return false;
12381239
}
12391240

1241+
bool StackFrame::IsSwiftThunk() {
1242+
ThreadSP thread_sp = GetThread();
1243+
if (!thread_sp)
1244+
return false;
1245+
ProcessSP process_sp = thread_sp->GetProcess();
1246+
if (!process_sp)
1247+
return false;
1248+
1249+
SymbolContext sc = GetSymbolContext(eSymbolContextSymbol);
1250+
if (!sc.symbol)
1251+
return false;
1252+
auto *runtime = process_sp->GetLanguageRuntime(eLanguageTypeSwift);
1253+
if (!runtime)
1254+
return false;
1255+
return runtime->IsSymbolARuntimeThunk(*sc.symbol);
1256+
}
1257+
1258+
StructuredData::ObjectSP StackFrame::GetLanguageInfo() {
1259+
auto process_sp = CalculateProcess();
1260+
SourceLanguage language = GetLanguage();
1261+
if (!language)
1262+
return {};
1263+
if (auto runtime_sp =
1264+
process_sp->GetLanguageRuntime(language.AsLanguageType()))
1265+
return runtime_sp->GetLanguageInfo(
1266+
GetSymbolContext(eSymbolContextFunction));
1267+
return {};
1268+
}
1269+
12401270
const char *StackFrame::GetFunctionName() {
12411271
const char *name = nullptr;
12421272
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)