forked from qt-creator/qt-creator
Debugger: Move some Windows functionality around.
Preparing the introduction of the new CDB engine.
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
#include "cdbengine.h"
|
#include "cdbengine.h"
|
||||||
#include "cdbexceptionutils.h"
|
#include "cdbexceptionutils.h"
|
||||||
#include "cdbengine_p.h"
|
#include "cdbengine_p.h"
|
||||||
|
#include "dbgwinutils.h"
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
@@ -75,7 +76,7 @@ STDMETHODIMP CdbDebugEventCallback::Exception(
|
|||||||
QTextStream str(&msg);
|
QTextStream str(&msg);
|
||||||
formatException(Exception, &m_pEngine->m_d->interfaces(), str);
|
formatException(Exception, &m_pEngine->m_d->interfaces(), str);
|
||||||
}
|
}
|
||||||
const bool fatal = isFatalException(Exception->ExceptionCode);
|
const bool fatal = isFatalWinException(Exception->ExceptionCode);
|
||||||
if (debugCDB)
|
if (debugCDB)
|
||||||
qDebug() << Q_FUNC_INFO << "\nex=" << Exception->ExceptionCode << " fatal=" << fatal << msg;
|
qDebug() << Q_FUNC_INFO << "\nex=" << Exception->ExceptionCode << " fatal=" << fatal << msg;
|
||||||
m_pEngine->showMessage(msg, AppError);
|
m_pEngine->showMessage(msg, AppError);
|
||||||
@@ -226,7 +227,7 @@ STDMETHODIMP CdbExceptionLoggerEventCallback::Exception(
|
|||||||
__in ULONG /* FirstChance */
|
__in ULONG /* FirstChance */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const bool recordException = !m_skipNonFatalExceptions || isFatalException(Exception->ExceptionCode);
|
const bool recordException = !m_skipNonFatalExceptions || isFatalWinException(Exception->ExceptionCode);
|
||||||
QString msg;
|
QString msg;
|
||||||
formatException(Exception, QTextStream(&msg));
|
formatException(Exception, QTextStream(&msg));
|
||||||
if (recordException) {
|
if (recordException) {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#include "debuggeragents.h"
|
#include "debuggeragents.h"
|
||||||
#include "debuggeruiswitcher.h"
|
#include "debuggeruiswitcher.h"
|
||||||
#include "debuggercore.h"
|
#include "debuggercore.h"
|
||||||
|
#include "dbgwinutils.h"
|
||||||
|
|
||||||
#include "debuggeractions.h"
|
#include "debuggeractions.h"
|
||||||
#include "breakhandler.h"
|
#include "breakhandler.h"
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "cdbexceptionutils.h"
|
#include "cdbexceptionutils.h"
|
||||||
#include "cdbengine_p.h"
|
#include "cdbengine_p.h"
|
||||||
#include "stacktracecontext.h"
|
#include "stacktracecontext.h"
|
||||||
|
#include "dbgwinutils.h"
|
||||||
|
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
@@ -151,106 +152,15 @@ QString ExceptionBlocker::format(const DEBUG_EXCEPTION_FILTER_PARAMETERS &p)
|
|||||||
|
|
||||||
// ------------------ further exception utilities
|
// ------------------ further exception utilities
|
||||||
// Simple exception formatting
|
// Simple exception formatting
|
||||||
|
|
||||||
void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str)
|
void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str)
|
||||||
{
|
{
|
||||||
str.setIntegerBase(16);
|
formatWindowsException(e->ExceptionCode, e->ExceptionAddress,
|
||||||
str << "\nException at 0x" << e->ExceptionAddress
|
e->ExceptionFlags,
|
||||||
<< ", code: 0x" << e->ExceptionCode << ": ";
|
e->ExceptionInformation[0],
|
||||||
switch (e->ExceptionCode) {
|
e->ExceptionInformation[1],
|
||||||
case winExceptionCppException:
|
str);
|
||||||
str << "C++ exception";
|
|
||||||
break;
|
|
||||||
case winExceptionStartupCompleteTrap:
|
|
||||||
str << "Startup complete";
|
|
||||||
break;
|
|
||||||
case winExceptionDllNotFound:
|
|
||||||
str << "DLL not found";
|
|
||||||
break;
|
|
||||||
case winExceptionDllEntryPointNoFound:
|
|
||||||
str << "DLL entry point not found";
|
|
||||||
break;
|
|
||||||
case winExceptionDllInitFailed:
|
|
||||||
str << "DLL failed to initialize";
|
|
||||||
break;
|
|
||||||
case winExceptionMissingSystemFile:
|
|
||||||
str << "System file is missing";
|
|
||||||
break;
|
|
||||||
case winExceptionRpcServerUnavailable:
|
|
||||||
str << "RPC server unavailable";
|
|
||||||
break;
|
|
||||||
case winExceptionRpcServerInvalid:
|
|
||||||
str << "Invalid RPC server";
|
|
||||||
break;
|
|
||||||
case EXCEPTION_ACCESS_VIOLATION: {
|
|
||||||
const bool writeOperation = e->ExceptionInformation[0];
|
|
||||||
str << (writeOperation ? "write" : "read")
|
|
||||||
<< " access violation at: 0x" << e->ExceptionInformation[1];
|
|
||||||
}
|
|
||||||
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 << "privileged 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 << "\n\n";
|
||||||
str.setIntegerBase(10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format exception with stacktrace in case of C++ exception
|
// Format exception with stacktrace in case of C++ exception
|
||||||
@@ -270,23 +180,5 @@ void formatException(const EXCEPTION_RECORD64 *e,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFatalException(LONG code)
|
|
||||||
{
|
|
||||||
switch (code) {
|
|
||||||
case EXCEPTION_BREAKPOINT:
|
|
||||||
case EXCEPTION_SINGLE_STEP:
|
|
||||||
case winExceptionStartupCompleteTrap: // Mysterious exception at start of application
|
|
||||||
case winExceptionRpcServerUnavailable:
|
|
||||||
case winExceptionRpcServerInvalid:
|
|
||||||
case winExceptionDllNotFound:
|
|
||||||
case winExceptionDllEntryPointNoFound:
|
|
||||||
case winExceptionCppException:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -46,18 +46,6 @@ namespace CdbCore {
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
// Special exception codes.
|
|
||||||
enum { winExceptionCppException = 0xe06d7363,
|
|
||||||
winExceptionStartupCompleteTrap = 0x406d1388,
|
|
||||||
winExceptionRpcServerUnavailable = 0x6ba,
|
|
||||||
winExceptionRpcServerInvalid = 0x6a6,
|
|
||||||
winExceptionDllNotFound = 0xc0000135,
|
|
||||||
winExceptionDllEntryPointNoFound = 0xc0000139,
|
|
||||||
winExceptionDllInitFailed = 0xc0000142,
|
|
||||||
winExceptionMissingSystemFile = 0xc0000143,
|
|
||||||
winExceptionAppInitFailed = 0xc0000143
|
|
||||||
};
|
|
||||||
|
|
||||||
class CdbDumperHelper;
|
class CdbDumperHelper;
|
||||||
|
|
||||||
// Utility class that blocks out exception handling (breaking)
|
// Utility class that blocks out exception handling (breaking)
|
||||||
@@ -102,9 +90,6 @@ void formatException(const EXCEPTION_RECORD64 *e,
|
|||||||
const CdbCore::ComInterfaces *cif,
|
const CdbCore::ComInterfaces *cif,
|
||||||
QTextStream &str);
|
QTextStream &str);
|
||||||
|
|
||||||
// Is this a crash/recoverable?
|
|
||||||
bool isFatalException(LONG code);
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,12 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "winutils.h"
|
#include "winutils.h"
|
||||||
|
#include "dbgwinutils.h"
|
||||||
#include "debuggerdialogs.h"
|
#include "debuggerdialogs.h"
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
|
||||||
// Enable Win API of XP SP1 and later
|
// Enable Win API of XP SP1 and later
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
@@ -252,5 +254,132 @@ bool isWinProcessBeingDebugged(unsigned long pid)
|
|||||||
return debugged != FALSE;
|
return debugged != FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple exception formatting
|
||||||
|
void formatWindowsException(unsigned long code, quint64 address,
|
||||||
|
unsigned long flags, quint64 info1, quint64 info2,
|
||||||
|
QTextStream &str)
|
||||||
|
{
|
||||||
|
str.setIntegerBase(16);
|
||||||
|
str << "\nException at 0x" << address
|
||||||
|
<< ", code: 0x" << code << ": ";
|
||||||
|
switch (code) {
|
||||||
|
case winExceptionCppException:
|
||||||
|
str << "C++ exception";
|
||||||
|
break;
|
||||||
|
case winExceptionStartupCompleteTrap:
|
||||||
|
str << "Startup complete";
|
||||||
|
break;
|
||||||
|
case winExceptionDllNotFound:
|
||||||
|
str << "DLL not found";
|
||||||
|
break;
|
||||||
|
case winExceptionDllEntryPointNoFound:
|
||||||
|
str << "DLL entry point not found";
|
||||||
|
break;
|
||||||
|
case winExceptionDllInitFailed:
|
||||||
|
str << "DLL failed to initialize";
|
||||||
|
break;
|
||||||
|
case winExceptionMissingSystemFile:
|
||||||
|
str << "System file is missing";
|
||||||
|
break;
|
||||||
|
case winExceptionRpcServerUnavailable:
|
||||||
|
str << "RPC server unavailable";
|
||||||
|
break;
|
||||||
|
case winExceptionRpcServerInvalid:
|
||||||
|
str << "Invalid RPC server";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_ACCESS_VIOLATION: {
|
||||||
|
const bool writeOperation = info1;
|
||||||
|
str << (writeOperation ? "write" : "read")
|
||||||
|
<< " access violation at: 0x" << info2;
|
||||||
|
}
|
||||||
|
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 << "privileged instruction";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_SINGLE_STEP:
|
||||||
|
str << "single step";
|
||||||
|
break;
|
||||||
|
case EXCEPTION_STACK_OVERFLOW:
|
||||||
|
str << "stack_overflow";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str << ", flags=0x" << flags;
|
||||||
|
if (flags == EXCEPTION_NONCONTINUABLE) {
|
||||||
|
str << " (execution cannot be continued)";
|
||||||
|
}
|
||||||
|
str.setIntegerBase(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDebuggerWinException(long code)
|
||||||
|
{
|
||||||
|
return code ==EXCEPTION_BREAKPOINT || code == EXCEPTION_SINGLE_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFatalWinException(long code)
|
||||||
|
{
|
||||||
|
switch (code) {
|
||||||
|
case EXCEPTION_BREAKPOINT:
|
||||||
|
case EXCEPTION_SINGLE_STEP:
|
||||||
|
case winExceptionStartupCompleteTrap: // Mysterious exception at start of application
|
||||||
|
case winExceptionRpcServerUnavailable:
|
||||||
|
case winExceptionRpcServerInvalid:
|
||||||
|
case winExceptionDllNotFound:
|
||||||
|
case winExceptionDllEntryPointNoFound:
|
||||||
|
case winExceptionCppException:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QString)
|
QT_FORWARD_DECLARE_CLASS(QString)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QTextStream)
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -59,6 +60,29 @@ QString winNormalizeFileName(const QString &f);
|
|||||||
|
|
||||||
bool isWinProcessBeingDebugged(unsigned long pid);
|
bool isWinProcessBeingDebugged(unsigned long pid);
|
||||||
|
|
||||||
|
// Special exception codes.
|
||||||
|
enum { winExceptionCppException = 0xe06d7363,
|
||||||
|
winExceptionStartupCompleteTrap = 0x406d1388,
|
||||||
|
winExceptionRpcServerUnavailable = 0x6ba,
|
||||||
|
winExceptionRpcServerInvalid = 0x6a6,
|
||||||
|
winExceptionDllNotFound = 0xc0000135,
|
||||||
|
winExceptionDllEntryPointNoFound = 0xc0000139,
|
||||||
|
winExceptionDllInitFailed = 0xc0000142,
|
||||||
|
winExceptionMissingSystemFile = 0xc0000143,
|
||||||
|
winExceptionAppInitFailed = 0xc0000143
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format windows Exception
|
||||||
|
void formatWindowsException(unsigned long code, quint64 address,
|
||||||
|
unsigned long flags, quint64 info1, quint64 info2,
|
||||||
|
QTextStream &str);
|
||||||
|
// Check for access violation, etc.
|
||||||
|
bool isFatalWinException(long code);
|
||||||
|
|
||||||
|
// Check for EXCEPTION_BREAKPOINT, EXCEPTION_SINGLE_STEP
|
||||||
|
bool isDebuggerWinException(long code);
|
||||||
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user