forked from OSchip/llvm-project
Centralized the Mach exception stop info code by adding it as a first
class citizen on the StopInfo class. llvm-svn: 109235
This commit is contained in:
parent
2e00e3b12d
commit
896dff661a
|
@ -68,7 +68,7 @@ public:
|
|||
SetStopReasonToTrace ();
|
||||
|
||||
void
|
||||
SetStopReasonWithException (uint32_t exc_type, size_t exc_data_count);
|
||||
SetStopReasonWithGenericException (uint32_t exc_type, size_t exc_data_count);
|
||||
|
||||
void
|
||||
SetStopReasonWithPlan (lldb::ThreadPlanSP &plan);
|
||||
|
@ -81,6 +81,11 @@ public:
|
|||
|
||||
void
|
||||
SetStopDescription(const char *desc);
|
||||
|
||||
void
|
||||
SetStopReasonWithMachException (uint32_t exc_type,
|
||||
size_t exc_data_count,
|
||||
const lldb::addr_t *exc_data);
|
||||
|
||||
lldb::user_id_t
|
||||
GetBreakpointSiteID() const;
|
||||
|
|
|
@ -209,42 +209,9 @@ MachException::Data::GetStopInfo(Thread::StopInfo *stop_info) const
|
|||
return true;
|
||||
// We always stop with a mach exceptions
|
||||
const size_t exc_data_count = exc_data.size();
|
||||
stop_info->SetStopReasonWithException(exc_type, exc_data_count);
|
||||
|
||||
// Fill in a text description
|
||||
const char * exc_name = MachException::Name(exc_type);
|
||||
StreamString sstr;
|
||||
if (exc_name)
|
||||
sstr.PutCString(exc_name);
|
||||
else
|
||||
sstr.Printf ("%i", exc_type);
|
||||
|
||||
int signal = SoftSignal();
|
||||
if (signal > 0)
|
||||
{
|
||||
const char *sig_str = Host::GetSignalAsCString(signal);
|
||||
if (sig_str)
|
||||
sstr.Printf (" EXC_SOFT_SIGNAL(%s)", sig_str);
|
||||
else
|
||||
sstr.Printf (" EXC_SOFT_SIGNAL(%i)", signal);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No special disassembly for exception data, just
|
||||
sstr.Printf (" data[%zu] = {", exc_data_count);
|
||||
|
||||
for (size_t idx = 0; idx < exc_data_count; ++idx)
|
||||
sstr.Printf (MACH_EXCEPTION_DATA_FMT_MINHEX "%s", exc_data[idx], ((idx + 1 == exc_data_count) ? "" : ","));
|
||||
|
||||
sstr.PutChar('}');
|
||||
}
|
||||
|
||||
stop_info->SetStopDescription (sstr.GetData());
|
||||
|
||||
// Copy the exception data
|
||||
size_t i;
|
||||
for (i=0; i<exc_data_count; i++)
|
||||
stop_info->SetExceptionDataAtIndex(i, exc_data[i]);
|
||||
stop_info->SetStopReasonWithMachException (exc_type,
|
||||
exc_data_count,
|
||||
exc_data_count ? &exc_data[0] : NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
task_t task_port;
|
||||
lldb::tid_t thread_port;
|
||||
exception_type_t exc_type;
|
||||
std::vector<mach_exception_data_type_t> exc_data;
|
||||
std::vector<lldb::addr_t> exc_data;
|
||||
Data() :
|
||||
task_port(TASK_NULL),
|
||||
thread_port(THREAD_NULL),
|
||||
|
@ -125,7 +125,7 @@ public:
|
|||
|
||||
typedef std::vector<Message> collection;
|
||||
typedef collection::iterator iterator;
|
||||
typedef collection::const_iterator const_iterator;
|
||||
typedef collection::const_iterator const_iterator;
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -964,7 +964,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
std::string value;
|
||||
std::string thread_name;
|
||||
uint32_t exc_type = 0;
|
||||
std::vector<uint64_t> exc_data;
|
||||
std::vector<addr_t> exc_data;
|
||||
uint32_t tid = LLDB_INVALID_THREAD_ID;
|
||||
addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
|
||||
uint32_t exc_data_count = 0;
|
||||
|
@ -1011,245 +1011,17 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
gdb_thread->SetStopInfoStopID (GetStopID());
|
||||
if (exc_type != 0)
|
||||
{
|
||||
bool exc_translated = false;
|
||||
const char *exc_desc = NULL;
|
||||
const char *code_label = "code";
|
||||
const char *code_desc = NULL;
|
||||
const char *subcode_label = "subcode";
|
||||
const char *subcode_desc = NULL;
|
||||
switch (exc_type)
|
||||
{
|
||||
case 1: // EXC_BAD_ACCESS
|
||||
exc_desc = "EXC_BAD_ACCESS";
|
||||
subcode_label = "address";
|
||||
switch (GetArchSpec().GetGenericCPUType())
|
||||
{
|
||||
case ArchSpec::eCPU_arm:
|
||||
switch (exc_data[0])
|
||||
{
|
||||
case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
|
||||
case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_ppc:
|
||||
case ArchSpec::eCPU_ppc64:
|
||||
switch (exc_data[0])
|
||||
{
|
||||
case 0x101: code_desc = "EXC_PPC_VM_PROT_READ"; break;
|
||||
case 0x102: code_desc = "EXC_PPC_BADSPACE"; break;
|
||||
case 0x103: code_desc = "EXC_PPC_UNALIGNED"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // EXC_BAD_INSTRUCTION
|
||||
exc_desc = "EXC_BAD_INSTRUCTION";
|
||||
switch (GetArchSpec().GetGenericCPUType())
|
||||
{
|
||||
case ArchSpec::eCPU_i386:
|
||||
case ArchSpec::eCPU_x86_64:
|
||||
if (exc_data[0] == 1)
|
||||
code_desc = "EXC_I386_INVOP";
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_ppc:
|
||||
case ArchSpec::eCPU_ppc64:
|
||||
switch (exc_data[0])
|
||||
{
|
||||
case 1: code_desc = "EXC_PPC_INVALID_SYSCALL"; break;
|
||||
case 2: code_desc = "EXC_PPC_UNIPL_INST"; break;
|
||||
case 3: code_desc = "EXC_PPC_PRIVINST"; break;
|
||||
case 4: code_desc = "EXC_PPC_PRIVREG"; break;
|
||||
case 5: // EXC_PPC_TRACE
|
||||
stop_info.SetStopReasonToTrace();
|
||||
exc_translated = true;
|
||||
break;
|
||||
case 6: code_desc = "EXC_PPC_PERFMON"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_arm:
|
||||
if (exc_data[0] == 1)
|
||||
code_desc = "EXC_ARM_UNDEFINED";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // EXC_ARITHMETIC
|
||||
exc_desc = "EXC_ARITHMETIC";
|
||||
switch (GetArchSpec().GetGenericCPUType())
|
||||
{
|
||||
case ArchSpec::eCPU_i386:
|
||||
case ArchSpec::eCPU_x86_64:
|
||||
switch (exc_data[0])
|
||||
{
|
||||
case 1: code_desc = "EXC_I386_DIV"; break;
|
||||
case 2: code_desc = "EXC_I386_INTO"; break;
|
||||
case 3: code_desc = "EXC_I386_NOEXT"; break;
|
||||
case 4: code_desc = "EXC_I386_EXTOVR"; break;
|
||||
case 5: code_desc = "EXC_I386_EXTERR"; break;
|
||||
case 6: code_desc = "EXC_I386_EMERR"; break;
|
||||
case 7: code_desc = "EXC_I386_BOUND"; break;
|
||||
case 8: code_desc = "EXC_I386_SSEEXTERR"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_ppc:
|
||||
case ArchSpec::eCPU_ppc64:
|
||||
switch (exc_data[0])
|
||||
{
|
||||
case 1: code_desc = "EXC_PPC_OVERFLOW"; break;
|
||||
case 2: code_desc = "EXC_PPC_ZERO_DIVIDE"; break;
|
||||
case 3: code_desc = "EXC_PPC_FLT_INEXACT"; break;
|
||||
case 4: code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; break;
|
||||
case 5: code_desc = "EXC_PPC_FLT_UNDERFLOW"; break;
|
||||
case 6: code_desc = "EXC_PPC_FLT_OVERFLOW"; break;
|
||||
case 7: code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // EXC_EMULATION
|
||||
exc_desc = "EXC_EMULATION";
|
||||
break;
|
||||
|
||||
|
||||
case 5: // EXC_SOFTWARE
|
||||
exc_desc = "EXC_SOFTWARE";
|
||||
if (exc_data[0] == EXC_SOFT_SIGNAL && exc_data.size() == 2)
|
||||
{
|
||||
stop_info.SetStopReasonWithSignal(exc_data[1]);
|
||||
exc_translated = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
{
|
||||
exc_desc = "EXC_SOFTWARE";
|
||||
bool is_software_breakpoint = false;
|
||||
switch (GetArchSpec().GetGenericCPUType())
|
||||
{
|
||||
case ArchSpec::eCPU_i386:
|
||||
case ArchSpec::eCPU_x86_64:
|
||||
if (exc_data[0] == 1) // EXC_I386_SGL
|
||||
{
|
||||
exc_translated = true;
|
||||
stop_info.SetStopReasonToTrace ();
|
||||
}
|
||||
else if (exc_data[0] == 2) // EXC_I386_BPT
|
||||
{
|
||||
is_software_breakpoint = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_ppc:
|
||||
case ArchSpec::eCPU_ppc64:
|
||||
is_software_breakpoint = exc_data[0] == 1; // EXC_PPC_BREAKPOINT
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_arm:
|
||||
is_software_breakpoint = exc_data[0] == 1; // EXC_ARM_BREAKPOINT
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_software_breakpoint)
|
||||
{
|
||||
addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
|
||||
lldb::BreakpointSiteSP bp_site_sp = GetBreakpointSiteList().FindByAddress(pc);
|
||||
if (bp_site_sp)
|
||||
{
|
||||
exc_translated = true;
|
||||
if (bp_site_sp->ValidForThisThread (thread_sp.get()))
|
||||
{
|
||||
stop_info.Clear ();
|
||||
stop_info.SetStopReasonWithBreakpointSiteID (bp_site_sp->GetID());
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_info.Clear ();
|
||||
stop_info.SetStopReasonToNone();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
exc_desc = "EXC_SYSCALL";
|
||||
break;
|
||||
|
||||
case 8:
|
||||
exc_desc = "EXC_MACH_SYSCALL";
|
||||
break;
|
||||
|
||||
case 9:
|
||||
exc_desc = "EXC_RPC_ALERT";
|
||||
break;
|
||||
|
||||
case 10:
|
||||
exc_desc = "EXC_CRASH";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!exc_translated)
|
||||
{
|
||||
stop_info.SetStopReasonWithException(exc_type, exc_data.size());
|
||||
for (uint32_t i=0; i<exc_data.size(); ++i)
|
||||
stop_info.SetExceptionDataAtIndex(i, exc_data[i]);
|
||||
|
||||
|
||||
StreamString desc_strm;
|
||||
|
||||
if (exc_desc)
|
||||
desc_strm.PutCString(exc_desc);
|
||||
else
|
||||
desc_strm.Printf("EXC_??? (%u)", exc_type);
|
||||
|
||||
if (exc_data.size() >= 1)
|
||||
{
|
||||
if (code_desc)
|
||||
desc_strm.Printf(" (%s=%s", code_label, code_desc);
|
||||
else
|
||||
desc_strm.Printf(" (%s=%llu", code_label, exc_data[0]);
|
||||
}
|
||||
|
||||
if (exc_data.size() >= 2)
|
||||
{
|
||||
if (subcode_desc)
|
||||
desc_strm.Printf(", %s=%s", subcode_label, subcode_desc);
|
||||
else
|
||||
desc_strm.Printf(", %s=0x%llx", subcode_label, exc_data[1]);
|
||||
}
|
||||
|
||||
if (exc_data.empty() == false)
|
||||
desc_strm.PutChar(')');
|
||||
|
||||
stop_info.SetStopDescription(desc_strm.GetString().c_str());
|
||||
}
|
||||
stop_info.SetStopReasonWithMachException (exc_type,
|
||||
exc_data.size(),
|
||||
&exc_data[0]);
|
||||
}
|
||||
else if (signo)
|
||||
{
|
||||
stop_info.SetStopReasonWithSignal(signo);
|
||||
stop_info.SetStopReasonWithSignal (signo);
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_info.SetStopReasonToNone();
|
||||
stop_info.SetStopReasonToNone ();
|
||||
}
|
||||
}
|
||||
return eStateStopped;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/ThreadPlan.h"
|
||||
#include "lldb/Target/ThreadPlanCallFunction.h"
|
||||
|
@ -138,6 +139,254 @@ Thread::StopInfo::SetStopDescription(const char *desc)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Thread::StopInfo::SetStopReasonWithMachException
|
||||
(
|
||||
uint32_t exc_type,
|
||||
size_t exc_data_count,
|
||||
const addr_t *exc_data
|
||||
)
|
||||
{
|
||||
assert (exc_data_count < LLDB_THREAD_MAX_STOP_EXC_DATA);
|
||||
assert (m_thread != NULL);
|
||||
m_reason = eStopReasonException;
|
||||
m_details.exception.type = exc_type;
|
||||
m_details.exception.data_count = exc_data_count;
|
||||
for (size_t i=0; i<exc_data_count; ++i)
|
||||
m_details.exception.data[i] = exc_data[i];
|
||||
|
||||
if (m_details.exception.type != 0)
|
||||
{
|
||||
ArchSpec::CPU cpu = m_thread->GetProcess().GetTarget().GetArchitecture().GetGenericCPUType();
|
||||
|
||||
bool exc_translated = false;
|
||||
const char *exc_desc = NULL;
|
||||
const char *code_label = "code";
|
||||
const char *code_desc = NULL;
|
||||
const char *subcode_label = "subcode";
|
||||
const char *subcode_desc = NULL;
|
||||
switch (m_details.exception.type)
|
||||
{
|
||||
case 1: // EXC_BAD_ACCESS
|
||||
exc_desc = "EXC_BAD_ACCESS";
|
||||
subcode_label = "address";
|
||||
switch (cpu)
|
||||
{
|
||||
case ArchSpec::eCPU_arm:
|
||||
switch (m_details.exception.data[0])
|
||||
{
|
||||
case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
|
||||
case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_ppc:
|
||||
case ArchSpec::eCPU_ppc64:
|
||||
switch (m_details.exception.data[0])
|
||||
{
|
||||
case 0x101: code_desc = "EXC_PPC_VM_PROT_READ"; break;
|
||||
case 0x102: code_desc = "EXC_PPC_BADSPACE"; break;
|
||||
case 0x103: code_desc = "EXC_PPC_UNALIGNED"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // EXC_BAD_INSTRUCTION
|
||||
exc_desc = "EXC_BAD_INSTRUCTION";
|
||||
switch (cpu)
|
||||
{
|
||||
case ArchSpec::eCPU_i386:
|
||||
case ArchSpec::eCPU_x86_64:
|
||||
if (m_details.exception.data[0] == 1)
|
||||
code_desc = "EXC_I386_INVOP";
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_ppc:
|
||||
case ArchSpec::eCPU_ppc64:
|
||||
switch (m_details.exception.data[0])
|
||||
{
|
||||
case 1: code_desc = "EXC_PPC_INVALID_SYSCALL"; break;
|
||||
case 2: code_desc = "EXC_PPC_UNIPL_INST"; break;
|
||||
case 3: code_desc = "EXC_PPC_PRIVINST"; break;
|
||||
case 4: code_desc = "EXC_PPC_PRIVREG"; break;
|
||||
case 5: // EXC_PPC_TRACE
|
||||
SetStopReasonToTrace();
|
||||
exc_translated = true;
|
||||
break;
|
||||
case 6: code_desc = "EXC_PPC_PERFMON"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_arm:
|
||||
if (m_details.exception.data[0] == 1)
|
||||
code_desc = "EXC_ARM_UNDEFINED";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // EXC_ARITHMETIC
|
||||
exc_desc = "EXC_ARITHMETIC";
|
||||
switch (cpu)
|
||||
{
|
||||
case ArchSpec::eCPU_i386:
|
||||
case ArchSpec::eCPU_x86_64:
|
||||
switch (m_details.exception.data[0])
|
||||
{
|
||||
case 1: code_desc = "EXC_I386_DIV"; break;
|
||||
case 2: code_desc = "EXC_I386_INTO"; break;
|
||||
case 3: code_desc = "EXC_I386_NOEXT"; break;
|
||||
case 4: code_desc = "EXC_I386_EXTOVR"; break;
|
||||
case 5: code_desc = "EXC_I386_EXTERR"; break;
|
||||
case 6: code_desc = "EXC_I386_EMERR"; break;
|
||||
case 7: code_desc = "EXC_I386_BOUND"; break;
|
||||
case 8: code_desc = "EXC_I386_SSEEXTERR"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_ppc:
|
||||
case ArchSpec::eCPU_ppc64:
|
||||
switch (m_details.exception.data[0])
|
||||
{
|
||||
case 1: code_desc = "EXC_PPC_OVERFLOW"; break;
|
||||
case 2: code_desc = "EXC_PPC_ZERO_DIVIDE"; break;
|
||||
case 3: code_desc = "EXC_PPC_FLT_INEXACT"; break;
|
||||
case 4: code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; break;
|
||||
case 5: code_desc = "EXC_PPC_FLT_UNDERFLOW"; break;
|
||||
case 6: code_desc = "EXC_PPC_FLT_OVERFLOW"; break;
|
||||
case 7: code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // EXC_EMULATION
|
||||
exc_desc = "EXC_EMULATION";
|
||||
break;
|
||||
|
||||
|
||||
case 5: // EXC_SOFTWARE
|
||||
exc_desc = "EXC_SOFTWARE";
|
||||
if (m_details.exception.data[0] == EXC_SOFT_SIGNAL && m_details.exception.data_count == 2)
|
||||
{
|
||||
SetStopReasonWithSignal(m_details.exception.data[1]);
|
||||
exc_translated = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
{
|
||||
exc_desc = "EXC_SOFTWARE";
|
||||
bool is_software_breakpoint = false;
|
||||
switch (cpu)
|
||||
{
|
||||
case ArchSpec::eCPU_i386:
|
||||
case ArchSpec::eCPU_x86_64:
|
||||
if (m_details.exception.data[0] == 1) // EXC_I386_SGL
|
||||
{
|
||||
exc_translated = true;
|
||||
SetStopReasonToTrace ();
|
||||
}
|
||||
else if (m_details.exception.data[0] == 2) // EXC_I386_BPT
|
||||
{
|
||||
is_software_breakpoint = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_ppc:
|
||||
case ArchSpec::eCPU_ppc64:
|
||||
is_software_breakpoint = m_details.exception.data[0] == 1; // EXC_PPC_BREAKPOINT
|
||||
break;
|
||||
|
||||
case ArchSpec::eCPU_arm:
|
||||
is_software_breakpoint = m_details.exception.data[0] == 1; // EXC_ARM_BREAKPOINT
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_software_breakpoint)
|
||||
{
|
||||
addr_t pc = m_thread->GetRegisterContext()->GetPC();
|
||||
lldb::BreakpointSiteSP bp_site_sp = m_thread->GetProcess().GetBreakpointSiteList().FindByAddress(pc);
|
||||
if (bp_site_sp)
|
||||
{
|
||||
exc_translated = true;
|
||||
if (bp_site_sp->ValidForThisThread (m_thread))
|
||||
{
|
||||
Clear ();
|
||||
SetStopReasonWithBreakpointSiteID (bp_site_sp->GetID());
|
||||
}
|
||||
else
|
||||
{
|
||||
Clear ();
|
||||
SetStopReasonToNone();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
exc_desc = "EXC_SYSCALL";
|
||||
break;
|
||||
|
||||
case 8:
|
||||
exc_desc = "EXC_MACH_SYSCALL";
|
||||
break;
|
||||
|
||||
case 9:
|
||||
exc_desc = "EXC_RPC_ALERT";
|
||||
break;
|
||||
|
||||
case 10:
|
||||
exc_desc = "EXC_CRASH";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!exc_translated)
|
||||
{
|
||||
StreamString desc_strm;
|
||||
|
||||
if (exc_desc)
|
||||
desc_strm.PutCString(exc_desc);
|
||||
else
|
||||
desc_strm.Printf("EXC_??? (%u)", exc_type);
|
||||
|
||||
if (m_details.exception.data_count >= 1)
|
||||
{
|
||||
if (code_desc)
|
||||
desc_strm.Printf(" (%s=%s", code_label, code_desc);
|
||||
else
|
||||
desc_strm.Printf(" (%s=%llu", code_label, exc_data[0]);
|
||||
}
|
||||
|
||||
if (m_details.exception.data_count >= 2)
|
||||
{
|
||||
if (subcode_desc)
|
||||
desc_strm.Printf(", %s=%s", subcode_label, subcode_desc);
|
||||
else
|
||||
desc_strm.Printf(", %s=0x%llx", subcode_label, exc_data[1]);
|
||||
}
|
||||
|
||||
if (m_details.exception.data_count > 0)
|
||||
desc_strm.PutChar(')');
|
||||
|
||||
SetStopDescription(desc_strm.GetString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
void
|
||||
Thread::StopInfo::SetThread (Thread* thread)
|
||||
{
|
||||
|
@ -227,7 +476,7 @@ Thread::StopInfo::GetExceptionDataCount() const
|
|||
}
|
||||
|
||||
void
|
||||
Thread::StopInfo::SetStopReasonWithException (uint32_t exc_type, size_t exc_data_count)
|
||||
Thread::StopInfo::SetStopReasonWithGenericException (uint32_t exc_type, size_t exc_data_count)
|
||||
{
|
||||
m_reason = eStopReasonException;
|
||||
m_details.exception.type = exc_type;
|
||||
|
|
Loading…
Reference in New Issue