[Lldb-commits] [lldb] e660e65 - [lldb] Add an API to derive language-specific runtime information (#116904)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Nov 20 08:49:11 PST 2024
Author: Adrian Prantl
Date: 2024-11-20T08:49:07-08:00
New Revision: e660e6503ba14684bd460b7baaf3da7336d0f46e
URL: https://github.com/llvm/llvm-project/commit/e660e6503ba14684bd460b7baaf3da7336d0f46e
DIFF: https://github.com/llvm/llvm-project/commit/e660e6503ba14684bd460b7baaf3da7336d0f46e.diff
LOG: [lldb] Add an API to derive language-specific runtime information (#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.
Added:
lldb/test/API/lang/objc/languageinfo/Makefile
lldb/test/API/lang/objc/languageinfo/TestObjCLanguageInfo.py
lldb/test/API/lang/objc/languageinfo/main.m
Modified:
lldb/include/lldb/API/SBFrame.h
lldb/include/lldb/API/SBStructuredData.h
lldb/include/lldb/Target/LanguageRuntime.h
lldb/include/lldb/Target/StackFrame.h
lldb/source/API/SBFrame.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
lldb/source/Target/LanguageRuntime.cpp
lldb/source/Target/StackFrame.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h
index e0d15c3ecc5b1c..e1ff217767cb98 100644
--- a/lldb/include/lldb/API/SBFrame.h
+++ b/lldb/include/lldb/API/SBFrame.h
@@ -122,6 +122,11 @@ class LLDB_API SBFrame {
lldb::SBValue EvaluateExpression(const char *expr,
const SBExpressionOptions &options);
+ /// Language plugins can use this API to report language-specific
+ /// runtime information about this compile unit, such as additional
+ /// language version details or feature flags.
+ SBStructuredData GetLanguageInfo();
+
/// Gets the lexical block that defines the stack frame. Another way to think
/// of this is it will return the block that contains all of the variables
/// for a stack frame. Inlined functions are represented as SBBlock objects
diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h
index ccdd12cab94b2f..c0d214a7374c65 100644
--- a/lldb/include/lldb/API/SBStructuredData.h
+++ b/lldb/include/lldb/API/SBStructuredData.h
@@ -114,6 +114,7 @@ class SBStructuredData {
friend class SBCommandReturnObject;
friend class SBLaunchInfo;
friend class SBDebugger;
+ friend class SBFrame;
friend class SBTarget;
friend class SBProcess;
friend class SBThread;
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 21bdc61b8cbcf0..4f4d426eaa1dab 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -241,6 +241,11 @@ class LanguageRuntime : public Runtime, public PluginInterface {
lldb_private::RegisterContext *regctx,
bool &behaves_like_zeroth_frame);
+ /// Language runtime plugins can use this API to report
+ /// language-specific runtime information about this compile unit,
+ /// such as additional language version details or feature flags.
+ virtual StructuredData::ObjectSP GetLanguageInfo(SymbolContext sc);
+
protected:
// The static GetRuntimeUnwindPlan method above is only implemented in the
// base class; subclasses may override this protected member if they can
diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h
index e85430791b7d93..5e82657706339c 100644
--- a/lldb/include/lldb/Target/StackFrame.h
+++ b/lldb/include/lldb/Target/StackFrame.h
@@ -22,6 +22,7 @@
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UserID.h"
#include "lldb/ValueObject/ValueObjectList.h"
@@ -408,6 +409,11 @@ class StackFrame : public ExecutionContextScope,
/// system implementation details this way.
bool IsHidden();
+ /// Language plugins can use this API to report language-specific
+ /// runtime information about this compile unit, such as additional
+ /// language version details or feature flags.
+ StructuredData::ObjectSP GetLanguageInfo();
+
/// Get the frame's demangled name.
///
/// /// \return
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index e2c691fa9bfd45..d17bb5cc146086 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -47,6 +47,7 @@
#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFormat.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBSymbolContext.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBValue.h"
@@ -1154,6 +1155,21 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
return expr_result;
}
+SBStructuredData SBFrame::GetLanguageInfo() {
+ LLDB_INSTRUMENT_VA(this);
+
+ SBStructuredData sb_data;
+ std::unique_lock<std::recursive_mutex> lock;
+ ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (!frame)
+ return sb_data;
+
+ StructuredData::ObjectSP data(frame->GetLanguageInfo());
+ sb_data.m_impl_up->SetObjectSP(data);
+ return sb_data;
+}
+
bool SBFrame::IsInlined() {
LLDB_INSTRUMENT_VA(this);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 4c794b81809c6e..7298ab0e7336bf 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -3398,6 +3398,13 @@ std::optional<uint64_t> AppleObjCRuntimeV2::GetSharedCacheImageHeaderVersion() {
return std::nullopt;
}
+StructuredData::ObjectSP AppleObjCRuntimeV2::GetLanguageInfo(SymbolContext sc) {
+ auto dict_up = std::make_unique<StructuredData::Dictionary>();
+ dict_up->AddItem("Objective-C runtime version",
+ std::make_unique<StructuredData::UnsignedInteger>(2));
+ return dict_up;
+}
+
#pragma mark Frame recognizers
class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index c9d0b3a907b54b..7117b778a1c0e9 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -106,6 +106,8 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime {
std::optional<uint64_t> GetSharedCacheImageHeaderVersion();
+ StructuredData::ObjectSP GetLanguageInfo(SymbolContext sc) override;
+
protected:
lldb::BreakpointResolverSP
CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
diff --git a/lldb/source/Target/LanguageRuntime.cpp b/lldb/source/Target/LanguageRuntime.cpp
index ce3646c8b05c88..89bad75995ff14 100644
--- a/lldb/source/Target/LanguageRuntime.cpp
+++ b/lldb/source/Target/LanguageRuntime.cpp
@@ -277,6 +277,10 @@ LanguageRuntime::GetRuntimeUnwindPlan(Thread &thread, RegisterContext *regctx,
return UnwindPlanSP();
}
+StructuredData::ObjectSP LanguageRuntime::GetLanguageInfo(SymbolContext sc) {
+ return {};
+}
+
void LanguageRuntime::InitializeCommands(CommandObject *parent) {
if (!parent)
return;
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index ca02de15295cac..e7d3b883bdec56 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -22,6 +22,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrameRecognizer.h"
@@ -1230,6 +1231,18 @@ bool StackFrame::IsHidden() {
return false;
}
+StructuredData::ObjectSP StackFrame::GetLanguageInfo() {
+ auto process_sp = CalculateProcess();
+ SourceLanguage language = GetLanguage();
+ if (!language)
+ return {};
+ if (auto runtime_sp =
+ process_sp->GetLanguageRuntime(language.AsLanguageType()))
+ return runtime_sp->GetLanguageInfo(
+ GetSymbolContext(eSymbolContextFunction));
+ return {};
+}
+
const char *StackFrame::GetFunctionName() {
const char *name = nullptr;
SymbolContext sc = GetSymbolContext(
diff --git a/lldb/test/API/lang/objc/languageinfo/Makefile b/lldb/test/API/lang/objc/languageinfo/Makefile
new file mode 100644
index 00000000000000..11fce1e5c52196
--- /dev/null
+++ b/lldb/test/API/lang/objc/languageinfo/Makefile
@@ -0,0 +1,4 @@
+OBJC_SOURCES := main.m
+LD_EXTRAS := -lobjc
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/objc/languageinfo/TestObjCLanguageInfo.py b/lldb/test/API/lang/objc/languageinfo/TestObjCLanguageInfo.py
new file mode 100644
index 00000000000000..18e04c9e8bac50
--- /dev/null
+++ b/lldb/test/API/lang/objc/languageinfo/TestObjCLanguageInfo.py
@@ -0,0 +1,16 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class ObjCiVarIMPTestCase(TestBase):
+ @skipUnlessDarwin
+ @no_debug_info_test
+ def test_imp_ivar_type(self):
+ self.build()
+ target, process, thread, bkpt = lldbutil.run_to_name_breakpoint(self, "main")
+ frame = thread.GetFrameAtIndex(0)
+ lang_info = frame.GetLanguageInfo()
+ version = lang_info.GetValueForKey("Objective-C runtime version")
+ self.assertEqual(version.GetIntegerValue(), 2)
diff --git a/lldb/test/API/lang/objc/languageinfo/main.m b/lldb/test/API/lang/objc/languageinfo/main.m
new file mode 100644
index 00000000000000..06e216a2fde641
--- /dev/null
+++ b/lldb/test/API/lang/objc/languageinfo/main.m
@@ -0,0 +1 @@
+int main(int argc, char const *argv[]) { return 0; }
More information about the lldb-commits
mailing list