Factored the code that implements breakpoints on
exceptions for different languages out of
ThreadPlanCallFunction and put it into the
appropriate language runtimes.
llvm-svn: 118200
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 425c8f7..8a7cfc2c 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -9,6 +9,7 @@
#include "ItaniumABILanguageRuntime.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
@@ -17,6 +18,7 @@
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -116,3 +118,89 @@
{
return NULL;
}
+
+void
+ItaniumABILanguageRuntime::SetExceptionBreakpoints ()
+{
+ if (!m_process)
+ return;
+
+ if (!m_cxx_exception_bp_sp)
+ m_cxx_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
+ "__cxa_throw",
+ eFunctionNameTypeBase,
+ true);
+
+ if (!m_cxx_exception_alloc_bp_sp)
+ m_cxx_exception_alloc_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
+ "__cxa_allocate",
+ eFunctionNameTypeBase,
+ true);
+}
+
+void
+ItaniumABILanguageRuntime::ClearExceptionBreakpoints ()
+{
+ if (!m_process)
+ return;
+
+ if (m_cxx_exception_bp_sp.get())
+ {
+ m_process->GetTarget().RemoveBreakpointByID(m_cxx_exception_bp_sp->GetID());
+ m_cxx_exception_bp_sp.reset();
+ }
+
+ if (m_cxx_exception_alloc_bp_sp.get())
+ {
+ m_process->GetTarget().RemoveBreakpointByID(m_cxx_exception_alloc_bp_sp->GetID());
+ m_cxx_exception_bp_sp.reset();
+ }
+}
+
+bool
+ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
+{
+ if (!m_process)
+ return false;
+
+ if (!stop_reason ||
+ stop_reason->GetStopReason() != eStopReasonBreakpoint)
+ return false;
+
+ uint64_t break_site_id = stop_reason->GetValue();
+ lldb::BreakpointSiteSP bp_site_sp = m_process->GetBreakpointSiteList().FindByID(break_site_id);
+
+ if (!bp_site_sp)
+ return false;
+
+ uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
+
+ bool check_cxx_exception = false;
+ break_id_t cxx_exception_bid;
+
+ bool check_cxx_exception_alloc = false;
+ break_id_t cxx_exception_alloc_bid;
+
+ if (m_cxx_exception_bp_sp)
+ {
+ check_cxx_exception = true;
+ cxx_exception_bid = m_cxx_exception_bp_sp->GetID();
+ }
+
+ if (m_cxx_exception_alloc_bp_sp)
+ {
+ check_cxx_exception_alloc = true;
+ cxx_exception_alloc_bid = m_cxx_exception_alloc_bp_sp->GetID();
+ }
+
+ for (uint32_t i = 0; i < num_owners; i++)
+ {
+ break_id_t bid = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().GetID();
+
+ if ((check_cxx_exception && (bid == cxx_exception_bid)) ||
+ (check_cxx_exception_alloc && (bid == cxx_exception_alloc_bid)))
+ return true;
+ }
+
+ return false;
+}
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index 817c076..113ed51 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -65,9 +65,22 @@
virtual lldb_private::Log *
EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
+
+ virtual void
+ SetExceptionBreakpoints ();
+
+ virtual void
+ ClearExceptionBreakpoints ();
+
+ virtual bool
+ ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason);
+
protected:
private:
ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead.
+
+ lldb::BreakpointSP m_cxx_exception_bp_sp;
+ lldb::BreakpointSP m_cxx_exception_alloc_bp_sp;
};
} // namespace lldb_private