summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/LanguageRuntime/ObjC
diff options
context:
space:
mode:
authorKuba Mracek <mracek@apple.com>2018-11-28 22:01:52 +0000
committerKuba Mracek <mracek@apple.com>2018-11-28 22:01:52 +0000
commite60bc53b4611d98352345e48be4c25214e0bf858 (patch)
treea608c61b3dd10b4ffc3bb9bd5d48a6bc464218b7 /lldb/source/Plugins/LanguageRuntime/ObjC
parenta3e7a167c499bfe35628676137637c5265bb06aa (diff)
downloadbcm5719-llvm-e60bc53b4611d98352345e48be4c25214e0bf858.tar.gz
bcm5719-llvm-e60bc53b4611d98352345e48be4c25214e0bf858.zip
[lldb] Add GetCurrentException APIs to SBThread, add frame recognizer for objc_exception_throw for Obj-C runtimes
This adds new APIs and a command to deal with exceptions (mostly Obj-C exceptions): SBThread and Thread get GetCurrentException API, which returns an SBValue/ValueObjectSP with the current exception for a thread. "Current" means an exception that is currently being thrown, caught or otherwise processed. In this patch, we only know about the exception when in objc_exception_throw, but subsequent patches will expand this (and add GetCurrentExceptionBacktrace, which will return an SBThread/ThreadSP containing a historical thread backtrace retrieved from the exception object. Currently unimplemented, subsequent patches will implement this). Extracting the exception from objc_exception_throw is implemented by adding a frame recognizer. This also add a new sub-command "thread exception", which prints the current exception. Differential Revision: https://reviews.llvm.org/D43886 llvm-svn: 347813
Diffstat (limited to 'lldb/source/Plugins/LanguageRuntime/ObjC')
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp8
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp5
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp67
4 files changed, 77 insertions, 5 deletions
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index bc574808415..74b17f539d9 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -455,13 +455,19 @@ lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() {
if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) {
FileSpecList filter_modules;
- filter_modules.Append(FileSpec("libobjc.A.dylib"));
+ filter_modules.Append(std::get<0>(GetExceptionThrowLocation()));
return target.GetSearchFilterForModuleList(&filter_modules);
} else {
return LanguageRuntime::CreateExceptionSearchFilter();
}
}
+std::tuple<FileSpec, ConstString>
+AppleObjCRuntime::GetExceptionThrowLocation() {
+ return std::make_tuple(
+ FileSpec("libobjc.A.dylib"), ConstString("objc_exception_throw"));
+}
+
void AppleObjCRuntime::ReadObjCLibraryIfNeeded(const ModuleList &module_list) {
if (!HasReadObjCLibrary()) {
std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
index 46ab11d0da6..ac2f5c83ca7 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
@@ -86,6 +86,8 @@ public:
bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
lldb::SearchFilterSP CreateExceptionSearchFilter() override;
+
+ static std::tuple<FileSpec, ConstString> GetExceptionThrowLocation();
uint32_t GetFoundationVersion();
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index dc3955db9a5..aaecfb27e90 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -113,8 +113,9 @@ AppleObjCRuntimeV1::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp,
if (throw_bp)
resolver_sp.reset(new BreakpointResolverName(
- bkpt, "objc_exception_throw", eFunctionNameTypeBase,
- eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo));
+ bkpt, std::get<1>(GetExceptionThrowLocation()).AsCString(),
+ eFunctionNameTypeBase, eLanguageTypeUnknown, Breakpoint::Exact, 0,
+ eLazyBoolNo));
// FIXME: don't do catch yet.
return resolver_sp;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index b644db41dbf..bbe6dd8e8d1 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -25,6 +25,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
+#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
@@ -39,10 +40,12 @@
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
@@ -373,6 +376,8 @@ ExtractRuntimeGlobalSymbol(Process *process, ConstString name,
}
}
+static void RegisterObjCExceptionRecognizer();
+
AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
const ModuleSP &objc_module_sp)
: AppleObjCRuntime(process), m_get_class_info_code(),
@@ -393,6 +398,7 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
static const ConstString g_gdb_object_getClass("gdb_object_getClass");
m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(
g_gdb_object_getClass, eSymbolTypeCode) != NULL);
+ RegisterObjCExceptionRecognizer();
}
bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
@@ -799,8 +805,9 @@ AppleObjCRuntimeV2::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp,
if (throw_bp)
resolver_sp.reset(new BreakpointResolverName(
- bkpt, "objc_exception_throw", eFunctionNameTypeBase,
- eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo));
+ bkpt, std::get<1>(GetExceptionThrowLocation()).AsCString(),
+ eFunctionNameTypeBase, eLanguageTypeUnknown, Breakpoint::Exact, 0,
+ eLazyBoolNo));
// FIXME: We don't do catch breakpoints for ObjC yet.
// Should there be some way for the runtime to specify what it can do in this
// regard?
@@ -2592,3 +2599,59 @@ void AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
} else
this->AppleObjCRuntime::GetValuesForGlobalCFBooleans(cf_true, cf_false);
}
+
+#pragma mark Frame recognizers
+
+class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
+ public:
+ ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp) {
+ ThreadSP thread_sp = frame_sp->GetThread();
+ ProcessSP process_sp = thread_sp->GetProcess();
+
+ const lldb::ABISP &abi = process_sp->GetABI();
+ if (!abi) return;
+
+ CompilerType voidstar = process_sp->GetTarget()
+ .GetScratchClangASTContext()
+ ->GetBasicType(lldb::eBasicTypeVoid)
+ .GetPointerType();
+
+ ValueList args;
+ Value input_value;
+ input_value.SetCompilerType(voidstar);
+ args.PushValue(input_value);
+
+ if (!abi->GetArgumentValues(*thread_sp, args)) return;
+
+ addr_t exception_addr = args.GetValueAtIndex(0)->GetScalar().ULongLong();
+
+ Value value(exception_addr);
+ value.SetCompilerType(voidstar);
+ exception = ValueObjectConstResult::Create(frame_sp.get(), value,
+ ConstString("exception"));
+ exception = exception->GetDynamicValue(eDynamicDontRunTarget);
+ }
+
+ ValueObjectSP exception;
+
+ lldb::ValueObjectSP GetExceptionObject() override { return exception; }
+};
+
+class ObjCExceptionThrowFrameRecognizer : public StackFrameRecognizer {
+ lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame) {
+ return lldb::RecognizedStackFrameSP(
+ new ObjCExceptionRecognizedStackFrame(frame));
+ };
+};
+
+static void RegisterObjCExceptionRecognizer() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
+ FileSpec module;
+ ConstString function;
+ std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation();
+ StackFrameRecognizerManager::AddRecognizer(
+ StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
+ module.GetFilename(), function, /*first_instruction_only*/ true);
+ });
+}
OpenPOWER on IntegriCloud