forked from qt-creator/qt-creator
CDB refactoring, introduce typedefs to remove version numbers.
Log exceptions with stacktrace.
This commit is contained in:
@@ -32,8 +32,12 @@
|
||||
#include "cdbdebugengine_p.h"
|
||||
#include "debuggermanager.h"
|
||||
#include "breakhandler.h"
|
||||
#include "cdbstacktracecontext.h"
|
||||
|
||||
enum { cppExceptionCode = 0xe06d7363 };
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
@@ -198,7 +202,7 @@ STDMETHODIMP CdbDebugEventCallbackBase::ChangeSymbolState(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IDebugEventCallbacksWide *CdbDebugEventCallbackBase::getEventCallback(IDebugClient5 *clnt)
|
||||
IDebugEventCallbacksWide *CdbDebugEventCallbackBase::getEventCallback(CIDebugClient *clnt)
|
||||
{
|
||||
IDebugEventCallbacksWide *rc = 0;
|
||||
if (SUCCEEDED(clnt->GetEventCallbacksWide(&rc)))
|
||||
@@ -231,26 +235,116 @@ STDMETHODIMP CdbDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT2 Bp)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static inline QString msgException(const EXCEPTION_RECORD64 *Exception, ULONG FirstChance)
|
||||
// Simple exception formatting
|
||||
void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str)
|
||||
{
|
||||
return QString::fromLatin1("An exception occurred: Code=0x%1 FirstChance=%2").
|
||||
arg(QString::number(Exception->ExceptionCode, 16)).
|
||||
arg(FirstChance);
|
||||
str.setIntegerBase(16);
|
||||
str << "\nException at 0x" << e->ExceptionAddress
|
||||
<< ", code: 0x" << e->ExceptionCode << ": ";
|
||||
switch (e->ExceptionCode) {
|
||||
case cppExceptionCode:
|
||||
str << "C++ exception";
|
||||
break;
|
||||
case EXCEPTION_ACCESS_VIOLATION: {
|
||||
const bool writeOperation = e->ExceptionInformation[0];
|
||||
str << (writeOperation ? "write access violation" : "read access violation");
|
||||
}
|
||||
break;
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
str << "arrary bounds exceeded";
|
||||
break;
|
||||
case EXCEPTION_BREAKPOINT:
|
||||
str << "breakpoint";
|
||||
break;
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
str << "datatype misalignment";
|
||||
break;
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
str << "floating point exception";
|
||||
break;
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
str << "division by zero";
|
||||
break;
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
str << " floating-point operation cannot be represented exactly as a decimal fraction";
|
||||
break;
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
str << "invalid floating-point operation";
|
||||
break;
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
str << "floating-point overflow";
|
||||
break;
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
str << "floating-point operation stack over/underflow";
|
||||
break;
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
str << "floating-point UNDERFLOW";
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
str << "invalid instruction";
|
||||
break;
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
str << "page in error";
|
||||
break;
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
str << "integer division by zero";
|
||||
break;
|
||||
case EXCEPTION_INT_OVERFLOW:
|
||||
str << "integer overflow";
|
||||
break;
|
||||
case EXCEPTION_INVALID_DISPOSITION:
|
||||
str << "invalid disposition to exception dispatcher";
|
||||
break;
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||
str << "attempt to continue execution after noncontinuable exception";
|
||||
break;
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
str << "priviledged instruction";
|
||||
break;
|
||||
case EXCEPTION_SINGLE_STEP:
|
||||
str << "single step";
|
||||
break;
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
str << "stack_overflow";
|
||||
break;
|
||||
}
|
||||
str << ", flags=0x" << e->ExceptionFlags;
|
||||
if (e->ExceptionFlags == EXCEPTION_NONCONTINUABLE) {
|
||||
str << " (execution cannot be continued)";
|
||||
}
|
||||
str << "\n\n";
|
||||
str.setIntegerBase(10);
|
||||
}
|
||||
|
||||
// Format exception with stacktrace in case of C++ exception
|
||||
void formatException(const EXCEPTION_RECORD64 *e, CdbComInterfaces &cif, QTextStream &str)
|
||||
{
|
||||
formatException(e, str);
|
||||
if (e->ExceptionCode == cppExceptionCode) {
|
||||
QString errorMessage;
|
||||
ULONG currentThreadId = 0;
|
||||
cif.debugSystemObjects->GetCurrentThreadId(¤tThreadId);
|
||||
if (CdbStackTraceContext *stc = CdbStackTraceContext::create(&cif, currentThreadId, &errorMessage)) {
|
||||
str << "at:\n";
|
||||
stc->format(str);
|
||||
str <<'\n';
|
||||
delete stc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugEventCallback::Exception(
|
||||
THIS_
|
||||
__in PEXCEPTION_RECORD64 Exception,
|
||||
__in ULONG FirstChance
|
||||
__in ULONG /* FirstChance */
|
||||
)
|
||||
{
|
||||
Q_UNUSED(Exception)
|
||||
if (debugCDB)
|
||||
qDebug() << Q_FUNC_INFO << msgException(Exception, FirstChance);
|
||||
|
||||
// First chance are harmless
|
||||
if (!FirstChance)
|
||||
qWarning("%s", qPrintable(msgException(Exception, FirstChance)));
|
||||
QString msg;
|
||||
{
|
||||
QTextStream str(&msg);
|
||||
formatException(Exception, m_pEngine->m_d->m_cif, str);
|
||||
}
|
||||
m_pEngine->m_d->m_debuggerManagerAccess->showApplicationOutput(msg);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -395,7 +489,7 @@ STDMETHODIMP IgnoreDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
|
||||
}
|
||||
|
||||
// --------- EventCallbackRedirector
|
||||
EventCallbackRedirector::EventCallbackRedirector(IDebugClient5 *client, IDebugEventCallbacksWide *cb) :
|
||||
EventCallbackRedirector::EventCallbackRedirector(CIDebugClient *client, IDebugEventCallbacksWide *cb) :
|
||||
m_client(client),
|
||||
m_oldCb(CdbDebugEventCallbackBase::getEventCallback(client))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user