Commit 6d0b571a authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger[CDB]: Implement of Break-On-Throw.

along with some output formatting to find out defaults.
parent 31542a62
......@@ -374,7 +374,10 @@ void CdbDebugEngine::startDebugger(const QSharedPointer<DebuggerStartParameters>
m_d->clearDisplay();
m_d->m_inferiorStartupComplete = false;
setState(AdapterStarted, Q_FUNC_INFO, __LINE__);
// Options
QString errorMessage;
if (!m_d->setBreakOnThrow(theDebuggerBoolSetting(BreakOnThrow), &errorMessage))
manager()->showDebuggerOutput(LogWarning, errorMessage);
m_d->setVerboseSymbolLoading(m_d->m_options->verboseSymbolLoading);
// Figure out dumper. @TODO: same in gdb...
const QString dumperLibName = QDir::toNativeSeparators(manager()->qtDumperLibraryName());
......@@ -396,7 +399,6 @@ void CdbDebugEngine::startDebugger(const QSharedPointer<DebuggerStartParameters>
setState(InferiorStarting, Q_FUNC_INFO, __LINE__);
manager()->showStatusMessage("Starting Debugger", messageTimeOut);
QString errorMessage;
bool rc = false;
bool needWatchTimer = false;
m_d->clearForRun();
......@@ -1563,7 +1565,8 @@ void CdbDebugEngine::syncDebuggerPaths()
unsigned CdbDebugEngine::debuggerCapabilities() const
{
return DisassemblerCapability | RegisterCapability | ShowMemoryCapability
|WatchpointCapability;
|WatchpointCapability
|BreakOnThrowAndCatchCapability; // Sort-of: Can break on throw().
}
// Accessed by DebuggerManager
......
......@@ -904,6 +904,127 @@ void CoreEngine::setModuleCount(unsigned m)
m_debugEventCallback->setModuleCount(m);
}
static inline const char *debugFilterDescription(ULONG in)
{
switch (in) {
case DEBUG_FILTER_BREAK:
return "break";
case DEBUG_FILTER_SECOND_CHANCE_BREAK:
return "2nd-chance-break";
case DEBUG_FILTER_OUTPUT:
return "output";
case DEBUG_FILTER_IGNORE:
return "ignore";
default:
break;
}
return "unknown";
}
static inline QString msgCannotChangeExceptionCommands(unsigned long code, const QString &why)
{
return QString::fromLatin1("Cannot change exception commands for 0x%1: %2").
arg(code, 0, 16).arg(why);
}
bool CoreEngine::setBreakOnThrow(bool b, QString *errorMessage)
{
// See eventFilterStatus() for defaults
const unsigned long code = 0xe06d7363;
const unsigned long executionCommand = b ? DEBUG_FILTER_BREAK : DEBUG_FILTER_SECOND_CHANCE_BREAK;
const unsigned long continueCommand = b ? DEBUG_FILTER_BREAK : DEBUG_FILTER_SECOND_CHANCE_BREAK;
return setExceptionCommands(code, executionCommand, continueCommand, errorMessage);
}
bool CoreEngine::setExceptionCommands(ULONG code,
ULONG executionCommand,
ULONG continueCommand,
QString *errorMessage)
{
DEBUG_EXCEPTION_FILTER_PARAMETERS exceptionParameters;
HRESULT hr = m_cif.debugControl->GetExceptionFilterParameters(1, &code, 0, &exceptionParameters);
if (FAILED(hr)) {
*errorMessage = msgCannotChangeExceptionCommands(code, msgComFailed("GetExceptionFilterParameters", hr));
return false;
}
if (exceptionParameters.ExecutionOption == executionCommand
&& exceptionParameters.ContinueOption == continueCommand)
return true;
if (debug)
qDebug("Changing exception commands of 0x%x from %s/%s to %s/%s",
code,
debugFilterDescription(exceptionParameters.ExecutionOption),
debugFilterDescription(exceptionParameters.ContinueOption),
debugFilterDescription(executionCommand),
debugFilterDescription(continueCommand));
exceptionParameters.ExecutionOption = executionCommand;
exceptionParameters.ContinueOption = continueCommand;
hr = m_cif.debugControl->SetExceptionFilterParameters(1, &exceptionParameters);
if (FAILED(hr)) {
*errorMessage = msgCannotChangeExceptionCommands(code, msgComFailed("SetExceptionFilterParameters", hr));
return false;
}
return true;
}
static void formatEventFilter(CIDebugControl *ctl, unsigned long start, unsigned long end,
bool isException,
QTextStream &str)
{
enum { bufSize =2048 };
WCHAR buffer[bufSize];
for (unsigned long i = start; i < end; i++) {
HRESULT hr = ctl->GetEventFilterTextWide(i, buffer, bufSize, 0);
if (SUCCEEDED(hr)) {
ULONG size;
str << "- #" << i << " \"" << QString::fromUtf16(buffer) << '"';
hr = ctl->GetEventFilterCommandWide(i, buffer, bufSize, &size);
if (SUCCEEDED(hr) && size > 1)
str << " command: '" << QString::fromUtf16(buffer) << '\'';
if (isException) {
DEBUG_EXCEPTION_FILTER_PARAMETERS exceptionParameters;
hr = ctl->GetExceptionFilterParameters(1, 0, i, &exceptionParameters);
if (SUCCEEDED(hr)) {
str.setIntegerBase(16);
str << " code: 0x" << exceptionParameters.ExceptionCode;
str.setIntegerBase(10);
str << " execute: '"
<< debugFilterDescription(exceptionParameters.ExecutionOption)
<< "' continue: '" << debugFilterDescription(exceptionParameters.ContinueOption)
<< '\'';
if (exceptionParameters.SecondCommandSize) {
hr = ctl->GetExceptionFilterSecondCommandWide(i, buffer, bufSize, 0);
if (SUCCEEDED(hr))
str << " 2nd-command '" << QString::fromUtf16(buffer) << '\'';
}
}
} // isException
str << '\n';
}
}
}
QString CoreEngine::eventFilterStatus() const
{
ULONG specificEvents, specificExceptions, arbitraryExceptions;
QString rc;
QTextStream str(&rc);
HRESULT hr = m_cif.debugControl->GetNumberEventFilters(&specificEvents, &specificExceptions, &arbitraryExceptions);
if (FAILED(hr))
return QString();
str << "Specific events\n";
formatEventFilter(m_cif.debugControl, 0, specificEvents, false, str);
const ULONG arbitraryExceptionsStart = specificEvents + specificExceptions;
str << "Specific exceptions\n";
formatEventFilter(m_cif.debugControl, specificEvents, arbitraryExceptionsStart, true, str);
str << "Arbitrary exceptions\n";
const ULONG arbitraryExceptionsEnd = arbitraryExceptionsStart + arbitraryExceptions;
formatEventFilter(m_cif.debugControl, arbitraryExceptionsStart, arbitraryExceptionsEnd, true, str);
return rc;
}
// ------------- DEBUG_VALUE formatting helpers
// format an array of integers as "0x323, 0x2322, ..."
......
......@@ -151,6 +151,14 @@ public:
unsigned moduleCount() const;
bool setBreakOnThrow(bool b, QString *errorMessage);
bool setExceptionCommands(ULONG code,
ULONG executionCommand,
ULONG continueCommand,
QString *errorMessage);
QString eventFilterStatus() const;
signals:
void watchTimerDebugEvent();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment