forked from OSchip/llvm-project
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
This commit is contained in:
parent
49b0c45ecf
commit
f211510ff6
|
@ -45,6 +45,21 @@ public:
|
|||
virtual lldb::ValueObjectSP
|
||||
GetDynamicValue (lldb::ValueObjectSP in_value, ExecutionContextScope *exe_scope) = 0;
|
||||
|
||||
virtual void
|
||||
SetExceptionBreakpoints ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
ClearExceptionBreakpoints ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool
|
||||
ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Classes that inherit from LanguageRuntime can see and modify these
|
||||
|
|
|
@ -97,9 +97,8 @@ private:
|
|||
Thread &m_thread;
|
||||
Thread::RegisterCheckpoint m_register_backup;
|
||||
lldb::ThreadPlanSP m_subplan_sp;
|
||||
lldb::BreakpointSP m_cxx_exception_bp_sp;
|
||||
lldb::BreakpointSP m_cxx_exception_alloc_bp_sp;
|
||||
lldb::BreakpointSP m_objc_exception_bp_sp;
|
||||
LanguageRuntime *m_cxx_language_runtime;
|
||||
LanguageRuntime *m_objc_language_runtime;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallFunction);
|
||||
};
|
||||
|
|
|
@ -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 @@ ItaniumABILanguageRuntime::EnablePluginLogging (Stream *strm, Args &command)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -65,9 +65,22 @@ namespace lldb_private {
|
|||
|
||||
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
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
#include "AppleObjCRuntimeV2.h"
|
||||
#include "AppleObjCTrampolineHandler.h"
|
||||
|
||||
#include "llvm/Support/MachO.h"
|
||||
#include "clang/AST/Type.h"
|
||||
|
||||
#include "lldb/Breakpoint/BreakpointLocation.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
|
@ -24,6 +26,7 @@
|
|||
#include "lldb/Target/ExecutionContext.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"
|
||||
|
||||
|
@ -286,3 +289,84 @@ AppleObjCRuntimeV2::EnablePluginLogging (Stream *strm, Args &command)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
AppleObjCRuntimeV2::SetExceptionBreakpoints ()
|
||||
{
|
||||
if (!m_process)
|
||||
return;
|
||||
|
||||
if (!m_objc_exception_bp_sp)
|
||||
{
|
||||
ArchSpec arch_spec = m_process->GetTarget().GetArchitecture();
|
||||
|
||||
switch (arch_spec.GetCPUType())
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case llvm::MachO::CPUTypeI386:
|
||||
m_objc_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
|
||||
"objc_exception_throw",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
break;
|
||||
case llvm::MachO::CPUTypeX86_64:
|
||||
m_objc_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
|
||||
"__cxa_throw",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AppleObjCRuntimeV2::ClearExceptionBreakpoints ()
|
||||
{
|
||||
if (!m_process)
|
||||
return;
|
||||
|
||||
if (m_objc_exception_bp_sp.get())
|
||||
{
|
||||
m_process->GetTarget().RemoveBreakpointByID(m_objc_exception_bp_sp->GetID());
|
||||
m_objc_exception_bp_sp.reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AppleObjCRuntimeV2::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_objc_exception = false;
|
||||
break_id_t objc_exception_bid;
|
||||
|
||||
if (m_objc_exception_bp_sp)
|
||||
{
|
||||
check_objc_exception = true;
|
||||
objc_exception_bid = m_objc_exception_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_objc_exception && (bid == objc_exception_bid)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,15 @@ public:
|
|||
|
||||
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:
|
||||
Address *
|
||||
GetPrintForDebuggerAddr();
|
||||
|
@ -95,6 +104,7 @@ private:
|
|||
std::auto_ptr<Address> m_PrintForDebugger_addr;
|
||||
bool m_read_objc_library;
|
||||
std::auto_ptr<lldb_private::AppleObjCTrampolineHandler> m_objc_trampoline_handler_ap;
|
||||
lldb::BreakpointSP m_objc_exception_bp_sp;
|
||||
|
||||
AppleObjCRuntimeV2(Process *process) :
|
||||
lldb_private::ObjCLanguageRuntime(process),
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "lldb/Core/Address.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Target/LanguageRuntime.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/StopInfo.h"
|
||||
|
@ -328,122 +329,36 @@ ThreadPlanCallFunction::MischiefManaged ()
|
|||
void
|
||||
ThreadPlanCallFunction::SetBreakpoints ()
|
||||
{
|
||||
Target& target = m_process.GetTarget();
|
||||
m_cxx_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeC_plus_plus);
|
||||
m_objc_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeObjC);
|
||||
|
||||
ArchSpec arch_spec = target.GetArchitecture();
|
||||
|
||||
switch (arch_spec.GetCPUType())
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case llvm::MachO::CPUTypeI386:
|
||||
m_cxx_exception_bp_sp = target.CreateBreakpoint (NULL,
|
||||
"__cxa_throw",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
m_cxx_exception_alloc_bp_sp = target.CreateBreakpoint (NULL,
|
||||
"__cxa_allocate",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
m_objc_exception_bp_sp = target.CreateBreakpoint (NULL,
|
||||
"objc_exception_throw",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
break;
|
||||
case llvm::MachO::CPUTypeX86_64:
|
||||
m_cxx_exception_bp_sp = target.CreateBreakpoint (NULL,
|
||||
"__cxa_throw",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
m_cxx_exception_alloc_bp_sp = target.CreateBreakpoint (NULL,
|
||||
"__cxa_allocate",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
break;
|
||||
}
|
||||
if (m_cxx_language_runtime)
|
||||
m_cxx_language_runtime->SetExceptionBreakpoints();
|
||||
if (m_objc_language_runtime)
|
||||
m_objc_language_runtime->SetExceptionBreakpoints();
|
||||
}
|
||||
|
||||
void
|
||||
ThreadPlanCallFunction::ClearBreakpoints ()
|
||||
{
|
||||
Target& target = m_process.GetTarget();
|
||||
|
||||
if (m_cxx_exception_bp_sp.get())
|
||||
{
|
||||
target.RemoveBreakpointByID(m_cxx_exception_bp_sp->GetID());
|
||||
m_cxx_exception_bp_sp.reset();
|
||||
}
|
||||
|
||||
if (m_cxx_exception_alloc_bp_sp.get())
|
||||
{
|
||||
target.RemoveBreakpointByID(m_cxx_exception_alloc_bp_sp->GetID());
|
||||
m_cxx_exception_bp_sp.reset();
|
||||
}
|
||||
|
||||
if (m_objc_exception_bp_sp.get())
|
||||
{
|
||||
target.RemoveBreakpointByID(m_objc_exception_bp_sp->GetID());
|
||||
m_cxx_exception_bp_sp.reset();
|
||||
}
|
||||
if (m_cxx_language_runtime)
|
||||
m_cxx_language_runtime->ClearExceptionBreakpoints();
|
||||
if (m_objc_language_runtime)
|
||||
m_objc_language_runtime->ClearExceptionBreakpoints();
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadPlanCallFunction::BreakpointsExplainStop()
|
||||
{
|
||||
// A temporary fix to set breakpoints at points where exceptions are being
|
||||
// thrown. This functionality will migrate into the Target.
|
||||
|
||||
lldb::StopInfoSP stop_info_sp = GetPrivateStopReason();
|
||||
|
||||
if (!stop_info_sp ||
|
||||
stop_info_sp->GetStopReason() != eStopReasonBreakpoint)
|
||||
return false;
|
||||
if (m_cxx_language_runtime &&
|
||||
m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
|
||||
return true;
|
||||
|
||||
uint64_t break_site_id = stop_info_sp->GetValue();
|
||||
lldb::BreakpointSiteSP bp_site_sp = m_thread.GetProcess().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;
|
||||
|
||||
bool check_objc_exception = false;
|
||||
break_id_t objc_exception_bid;
|
||||
|
||||
if (m_cxx_exception_bp_sp.get())
|
||||
{
|
||||
check_cxx_exception = true;
|
||||
cxx_exception_bid = m_cxx_exception_bp_sp->GetID();
|
||||
}
|
||||
|
||||
if (m_cxx_exception_bp_sp.get())
|
||||
{
|
||||
check_cxx_exception_alloc = true;
|
||||
cxx_exception_alloc_bid = m_cxx_exception_alloc_bp_sp->GetID();
|
||||
}
|
||||
|
||||
if (m_cxx_exception_bp_sp.get())
|
||||
{
|
||||
check_objc_exception = true;
|
||||
objc_exception_bid = m_objc_exception_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)) ||
|
||||
(check_objc_exception && (bid == objc_exception_bid)))
|
||||
return true;
|
||||
}
|
||||
if (m_objc_language_runtime &&
|
||||
m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue