kubamracek created this revision.
kubamracek added reviewers: jasonmolenda, jingham.
Herald added a subscriber: mgorny.
This adds new APIs and commands 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.
- SBThread and Thread get GetCurrentExceptionBacktrace, which return an
SBThread/ThreadSP containing a historical thread backtrace retrieved from the
exception object. Currently unimplemented, subsequent patches will implement
this.
To be able to extract the exception when inside objc_exception_throw, this
patch introduces a concept of "frame recognizer" and "recognized frame". This
should be an extensible mechanism that hardcodes knowledge about special frames
(like objc_exception_throw) where we know the ABI, arguments or other special
properties of that frame, even without source code. In this patch, we only
handle objc_exception_throw frame.
https://reviews.llvm.org/D43886
Files:
include/lldb/API/SBThread.h
include/lldb/Target/FrameRecognizer.h
include/lldb/Target/Platform.h
include/lldb/Target/StackFrame.h
include/lldb/Target/Thread.h
lldb.xcodeproj/project.pbxproj
packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py
source/API/SBThread.cpp
source/Commands/CommandObjectThread.cpp
source/Plugins/Platform/MacOSX/CMakeLists.txt
source/Plugins/Platform/MacOSX/DarwinFrameRecognizer.cpp
source/Plugins/Platform/MacOSX/DarwinFrameRecognizer.h
source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
source/Plugins/Platform/MacOSX/PlatformDarwin.h
source/Target/StackFrame.cpp
source/Target/Thread.cpp
Index: source/Target/Thread.cpp
===================================================================
--- source/Target/Thread.cpp
+++ source/Target/Thread.cpp
@@ -2209,3 +2209,20 @@
}
return error;
}
+
+ValueObjectSP Thread::GetCurrentException() {
+ StackFrameSP frame_sp(GetStackFrameAtIndex(0));
+ if (!frame_sp) return ValueObjectSP();
+
+ RecognizedStackFrameSP recognized_frame(frame_sp->GetRecognizedFrame());
+ if (!recognized_frame) return ValueObjectSP();
+
+ if (!recognized_frame->IsThrowingObjCException()) return ValueObjectSP();
+
+ return recognized_frame->GetObjCExceptionObject();
+}
+
+ThreadSP Thread::GetCurrentExceptionBacktrace() {
+ // TODO
+ return ThreadSP();
+}
Index: source/Target/StackFrame.cpp
===================================================================
--- source/Target/StackFrame.cpp
+++ source/Target/StackFrame.cpp
@@ -1918,3 +1918,14 @@
}
return true;
}
+
+RecognizedStackFrameSP StackFrame::GetRecognizedFrame() {
+ if (!m_recognized_frame) {
+ lldb_private::FrameRecognizerSP recognizer_sp =
+ CalculateTarget()->GetPlatform()->GetFrameRecognizer();
+ if (recognizer_sp) {
+ m_recognized_frame = recognizer_sp->RecognizeFrame(CalculateStackFrame());
+ }
+ }
+ return m_recognized_frame;
+}
Index: source/Plugins/Platform/MacOSX/PlatformDarwin.h
===================================================================
--- source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -85,6 +85,8 @@
static std::tuple<uint32_t, uint32_t, uint32_t, llvm::StringRef>
ParseVersionBuildDir(llvm::StringRef str);
+ lldb_private::FrameRecognizerSP GetFrameRecognizer() override;
+
protected:
void ReadLibdispatchOffsetsAddress(lldb_private::Process *process);
@@ -137,6 +139,7 @@
std::string m_developer_directory;
+ lldb_private::FrameRecognizerSP m_frame_recognizer;
private:
DISALLOW_COPY_AND_ASSIGN(PlatformDarwin);
Index: source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
===================================================================
--- source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -42,6 +42,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
+#include "Plugins/Platform/MacOSX/DarwinFrameRecognizer.h"
#if defined(__APPLE__)
#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH
@@ -1825,3 +1826,9 @@
}
return Status();
}
+
+FrameRecognizerSP PlatformDarwin::GetFrameRecognizer() {
+ if (!m_frame_recognizer)
+ m_frame_recognizer.reset(new DarwinFrameRecognizer());
+ return m_frame_recognizer;
+}
Index: source/Plugins/Platform/MacOSX/DarwinFrameRecognizer.h
===================================================================
--- /dev/null
+++ source/Plugins/Platform/MacOSX/DarwinFrameRecognizer.h
@@ -0,0 +1,27 @@
+//===-- DarwinFrameRecognizer.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DarwinFrameRecognizer_h_
+#define liblldb_DarwinFrameRecognizer_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Target/FrameRecognizer.h"
+
+class DarwinFrameRecognizer
+ : public lldb_private::FrameRecognizer,
+ std::enable_shared_from_this<DarwinFrameRecognizer> {
+ public:
+ lldb_private::RecognizedStackFrameSP RecognizeFrame(
+ lldb::StackFrameSP frame) override;
+};
+
+#endif // liblldb_DarwinFrameRecognizer_h_
Index: source/Plugins/Platform/MacOSX/DarwinFrameRecognizer.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Platform/MacOSX/DarwinFrameRecognizer.cpp
@@ -0,0 +1,79 @@
+//===-- DarwinFrameRecognizer.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DarwinFrameRecognizer.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class DarwinObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
+ public:
+ DarwinObjCExceptionRecognizedStackFrame(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();
+
+ lldb_private::formatters::InferiorSizedWord exception_isw(exception_addr,
+ *process_sp);
+ exception = ValueObject::CreateValueObjectFromData(
+ "exception", exception_isw.GetAsData(process_sp->GetByteOrder()),
+ *frame_sp, voidstar);
+ exception = exception->GetDynamicValue(eDynamicDontRunTarget);
+ }
+
+ ValueObjectSP exception;
+
+ bool IsThrowingObjCException() override { return true; }
+
+ lldb::ValueObjectSP GetObjCExceptionObject() override { return exception; }
+};
+
+RecognizedStackFrameSP DarwinFrameRecognizer::RecognizeFrame(
+ StackFrameSP frame) {
+ const SymbolContext &symctx =
+ frame->GetSymbolContext(eSymbolContextModule | eSymbolContextFunction);
+ ConstString func = symctx.GetFunctionName();
+ ConstString mod = symctx.module_sp->GetFileSpec().GetFilename();
+
+ if (mod == ConstString("libobjc.A.dylib")) {
+ if (func == ConstString("objc_exception_throw")) {
+ return RecognizedStackFrameSP(
+ new DarwinObjCExceptionRecognizedStackFrame(frame));
+ }
+ }
+
+ return RecognizedStackFrameSP(new RecognizedStackFrame());
+}
Index: source/Plugins/Platform/MacOSX/CMakeLists.txt
===================================================================
--- source/Plugins/Platform/MacOSX/CMakeLists.txt
+++ source/Plugins/Platform/MacOSX/CMakeLists.txt
@@ -1,4 +1,5 @@
list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
+ DarwinFrameRecognizer.cpp
PlatformDarwin.cpp
PlatformDarwinKernel.cpp
PlatformMacOSX.cpp
Index: source/Commands/CommandObjectThread.cpp
===================================================================
--- source/Commands/CommandObjectThread.cpp
+++ source/Commands/CommandObjectThread.cpp
@@ -1511,6 +1511,113 @@
CommandOptions m_options;
};
+//-------------------------------------------------------------------------
+// CommandObjectThreadException
+//-------------------------------------------------------------------------
+
+static OptionDefinition g_thread_exception_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)" },
+ { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace" },
+ // clang-format on
+};
+
+class CommandObjectThreadException : public CommandObjectIterateOverThreads {
+ public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c': {
+ int32_t input_count = 0;
+ if (option_arg.getAsInteger(0, m_count)) {
+ m_count = UINT32_MAX;
+ error.SetErrorStringWithFormat(
+ "invalid integer value for option '%c'", short_option);
+ } else if (input_count < 0)
+ m_count = UINT32_MAX;
+ } break;
+ case 's':
+ if (option_arg.getAsInteger(0, m_start))
+ error.SetErrorStringWithFormat(
+ "invalid integer value for option '%c'", short_option);
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_count = UINT32_MAX;
+ m_start = 0;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_exception_options);
+ }
+
+ // Instance variables to hold the values for command options.
+ uint32_t m_count;
+ uint32_t m_start;
+ };
+
+ CommandObjectThreadException(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread exception",
+ "Display the current exception object for a thread. Defaults to "
+ "the current thread.",
+ "thread exception",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options() {
+ m_add_return = false;
+ }
+
+ ~CommandObjectThreadException() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ ThreadSP thread_sp =
+ m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ if (!thread_sp) {
+ result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
+ tid);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Stream &strm = result.GetOutputStream();
+ ValueObjectSP exception_object_sp = thread_sp->GetCurrentException();
+ if (exception_object_sp) {
+ exception_object_sp->Dump(strm);
+ }
+
+ ThreadSP exception_thread_sp = thread_sp->GetCurrentExceptionBacktrace();
+ if (exception_thread_sp && exception_thread_sp->IsValid()) {
+ const uint32_t num_frames_with_source = 0;
+ const bool stop_format = false;
+ exception_thread_sp->GetStatus(strm, m_options.m_start, m_options.m_count,
+ num_frames_with_source, stop_format);
+ }
+
+ return true;
+ }
+
+ CommandOptions m_options;
+};
+
//-------------------------------------------------------------------------
// CommandObjectThreadReturn
//-------------------------------------------------------------------------
@@ -2054,6 +2161,9 @@
CommandObjectSP(new CommandObjectThreadUntil(interpreter)));
LoadSubCommand("info",
CommandObjectSP(new CommandObjectThreadInfo(interpreter)));
+ LoadSubCommand(
+ "exception",
+ CommandObjectSP(new CommandObjectThreadException(interpreter)));
LoadSubCommand("step-in",
CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
interpreter, "thread step-in",
Index: source/API/SBThread.cpp
===================================================================
--- source/API/SBThread.cpp
+++ source/API/SBThread.cpp
@@ -1416,6 +1416,20 @@
return LLDB_INVALID_INDEX32;
}
+SBThread SBThread::GetCurrentExceptionBacktrace() {
+ ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
+ if (!thread_sp) return SBThread();
+
+ return SBThread(thread_sp->GetCurrentExceptionBacktrace());
+}
+
+SBValue SBThread::GetCurrentException() {
+ ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
+ if (!thread_sp) return SBValue();
+
+ return SBValue(thread_sp->GetCurrentException());
+}
+
bool SBThread::SafeToCallFunctions() {
ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
if (thread_sp)
Index: packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py
===================================================================
--- packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py
+++ packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py
@@ -30,12 +30,20 @@
lldbutil.run_break_set_by_file_and_line(
self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+ lldbutil.run_break_set_by_symbol(self, "objc_exception_throw")
self.runCmd("run", RUN_SUCCEEDED)
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs=['stopped', 'stop reason = breakpoint'])
+ self.expect('thread exception', substrs=[
+ '(NSException *) exception = ',
+ 'name: "ThrownException" - reason: "SomeReason"',
+ ])
+
+ self.runCmd("continue")
+
self.expect(
'frame variable e1',
substrs=[
Index: lldb.xcodeproj/project.pbxproj
===================================================================
--- lldb.xcodeproj/project.pbxproj
+++ lldb.xcodeproj/project.pbxproj
@@ -784,6 +784,7 @@
8CF02AEF19DD16B100B14BE0 /* InstrumentationRuntimeStopInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CF02AED19DD15CF00B14BE0 /* InstrumentationRuntimeStopInfo.cpp */; };
9404957A1BEC497E00926025 /* NSError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940495781BEC497E00926025 /* NSError.cpp */; };
9404957B1BEC497E00926025 /* NSException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940495791BEC497E00926025 /* NSException.cpp */; };
+ 8CFDB678204677DA0052B399 /* DarwinFrameRecognizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CFDB676204677D10052B399 /* DarwinFrameRecognizer.cpp */; };
94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94094C69163B6CD90083A547 /* ValueObjectCast.cpp */; };
940B02F619DC96E700AD0F52 /* SBExecutionContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940B02F519DC96E700AD0F52 /* SBExecutionContext.cpp */; };
940B04D91A8984FF0045D5F7 /* argdumper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940B04D81A8984FF0045D5F7 /* argdumper.cpp */; };
@@ -2695,6 +2696,9 @@
8CF02AE619DCBF8400B14BE0 /* ASanRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASanRuntime.h; sourceTree = "<group>"; };
8CF02AED19DD15CF00B14BE0 /* InstrumentationRuntimeStopInfo.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InstrumentationRuntimeStopInfo.cpp; path = source/Target/InstrumentationRuntimeStopInfo.cpp; sourceTree = "<group>"; };
8CF02AEE19DD15CF00B14BE0 /* InstrumentationRuntimeStopInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InstrumentationRuntimeStopInfo.h; path = include/lldb/Target/InstrumentationRuntimeStopInfo.h; sourceTree = "<group>"; };
+ 8CFDB676204677D10052B399 /* DarwinFrameRecognizer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DarwinFrameRecognizer.cpp; sourceTree = "<group>"; };
+ 8CFDB677204677D10052B399 /* DarwinFrameRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DarwinFrameRecognizer.h; sourceTree = "<group>"; };
+ 8CFDB67920467B390052B399 /* FrameRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FrameRecognizer.h; path = include/lldb/Target/FrameRecognizer.h; sourceTree = "<group>"; };
94005E0313F438DF001EF42D /* python-wrapper.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-wrapper.swig"; sourceTree = "<group>"; };
94005E0513F45A1B001EF42D /* embedded_interpreter.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = embedded_interpreter.py; path = source/Interpreter/embedded_interpreter.py; sourceTree = "<group>"; };
940495781BEC497E00926025 /* NSError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSError.cpp; path = Language/ObjC/NSError.cpp; sourceTree = "<group>"; };
@@ -5406,6 +5410,7 @@
26BC7DF210F1B81A00F91463 /* ExecutionContext.h */,
26BC7F3510F1B90C00F91463 /* ExecutionContext.cpp */,
26DAFD9711529BC7005A394E /* ExecutionContextScope.h */,
+ 8CFDB67920467B390052B399 /* FrameRecognizer.h */,
26BC179B18C7F2CB00D2196D /* JITLoader.h */,
26BC179718C7F2B300D2196D /* JITLoader.cpp */,
26BC179C18C7F2CB00D2196D /* JITLoaderList.h */,
@@ -5604,6 +5609,8 @@
AF8AD6361BEC28C400150209 /* PlatformRemoteAppleWatch.h */,
2675F6FE1332BE690067997B /* PlatformRemoteiOS.cpp */,
2675F6FF1332BE690067997B /* PlatformRemoteiOS.h */,
+ 8CFDB676204677D10052B399 /* DarwinFrameRecognizer.cpp */,
+ 8CFDB677204677D10052B399 /* DarwinFrameRecognizer.h */,
);
path = MacOSX;
sourceTree = "<group>";
@@ -7824,6 +7831,7 @@
2689010813353E6F00698AC0 /* ThreadPlanStepUntil.cpp in Sources */,
2689010A13353E6F00698AC0 /* ThreadPlanTracer.cpp in Sources */,
AF37E10A17C861F20061E18E /* ProcessRunLock.cpp in Sources */,
+ 8CFDB678204677DA0052B399 /* DarwinFrameRecognizer.cpp in Sources */,
26474CAA18D0CB070073DEBA /* RegisterContextFreeBSD_mips64.cpp in Sources */,
94A5B3971AB9FE8D00A5EE7F /* EmulateInstructionMIPS64.cpp in Sources */,
256CBDC01ADD11C000BC6CDC /* RegisterContextPOSIX_arm.cpp in Sources */,
Index: include/lldb/Target/Thread.h
===================================================================
--- include/lldb/Target/Thread.h
+++ include/lldb/Target/Thread.h
@@ -1249,6 +1249,10 @@
//----------------------------------------------------------------------
virtual uint64_t GetExtendedBacktraceToken() { return LLDB_INVALID_ADDRESS; }
+ lldb::ThreadSP GetCurrentExceptionBacktrace();
+
+ lldb::ValueObjectSP GetCurrentException();
+
protected:
friend class ThreadPlan;
friend class ThreadList;
Index: include/lldb/Target/StackFrame.h
===================================================================
--- include/lldb/Target/StackFrame.h
+++ include/lldb/Target/StackFrame.h
@@ -23,6 +23,7 @@
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/FrameRecognizer.h"
#include "lldb/Target/StackID.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
@@ -516,6 +517,8 @@
void CalculateExecutionContext(ExecutionContext &exe_ctx) override;
+ lldb_private::RecognizedStackFrameSP GetRecognizedFrame();
+
protected:
friend class StackFrameList;
@@ -553,6 +556,7 @@
ValueObjectList m_variable_list_value_objects; // Value objects for each
// variable in
// m_variable_list_sp
+ RecognizedStackFrameSP m_recognized_frame;
StreamString m_disassembly;
std::recursive_mutex m_mutex;
Index: include/lldb/Target/Platform.h
===================================================================
--- include/lldb/Target/Platform.h
+++ include/lldb/Target/Platform.h
@@ -24,6 +24,7 @@
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Interpreter/Options.h"
+#include "lldb/Target/FrameRecognizer.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
@@ -872,6 +873,10 @@
virtual size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
lldb_private::Status &error);
+ virtual FrameRecognizerSP GetFrameRecognizer() {
+ return FrameRecognizerSP();
+ }
+
protected:
bool m_is_host;
// Set to true when we are able to actually set the OS version while
Index: include/lldb/Target/FrameRecognizer.h
===================================================================
--- /dev/null
+++ include/lldb/Target/FrameRecognizer.h
@@ -0,0 +1,50 @@
+//===-- FrameRecognizer.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_FrameRecognizer_h_
+#define liblldb_FrameRecognizer_h_
+
+// C Includes
+// C++ Includes
+#include <memory>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-public.h"
+
+namespace lldb_private {
+
+class RecognizedStackFrame
+ : std::enable_shared_from_this<RecognizedStackFrame> {
+ public:
+ virtual bool IsThrowingObjCException() { return false; }
+
+ virtual lldb::ValueObjectSP GetObjCExceptionObject() {
+ return lldb::ValueObjectSP();
+ }
+
+ virtual ~RecognizedStackFrame(){};
+};
+
+typedef std::shared_ptr<RecognizedStackFrame> RecognizedStackFrameSP;
+
+class FrameRecognizer : std::enable_shared_from_this<FrameRecognizer> {
+ public:
+ virtual RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame) {
+ return RecognizedStackFrameSP(new RecognizedStackFrame());
+ };
+
+ virtual ~FrameRecognizer(){};
+};
+
+typedef std::shared_ptr<FrameRecognizer> FrameRecognizerSP;
+
+} // namespace lldb_private
+
+#endif // liblldb_FrameRecognizer_h_
Index: include/lldb/API/SBThread.h
===================================================================
--- include/lldb/API/SBThread.h
+++ include/lldb/API/SBThread.h
@@ -184,6 +184,10 @@
uint32_t GetExtendedBacktraceOriginatingIndexID();
+ SBThread GetCurrentExceptionBacktrace();
+
+ SBValue GetCurrentException();
+
bool SafeToCallFunctions();
#ifndef SWIG
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits