debugger: intercept calls to qFatal

On Windows that might kill the inferior even if we only want to
examine data.

Task-number: QTCREATORBUG-4145
This commit is contained in:
hjk
2011-03-21 15:04:31 +01:00
parent 5426c3ac2c
commit 634bcc88ad
4 changed files with 67 additions and 37 deletions

View File

@@ -215,6 +215,7 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
m_stackNeeded = false;
m_preparedForQmlBreak = false;
m_disassembleUsesComma = false;
m_qFatalBreakpointNumber = 0;
invalidateSourcesList();
@@ -1246,7 +1247,8 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
if (bkptno && frame.isValid()
&& !isQmlStepBreakpoint1(bkptno)
&& !isQmlStepBreakpoint2(bkptno)) {
&& !isQmlStepBreakpoint2(bkptno)
&& !isQFatalBreakpoint(bkptno)) {
// Use opportunity to update the breakpoint marker position.
BreakHandler *handler = breakHandler();
//qDebug() << " PROBLEM: " << m_qmlBreakpointNumbers << bkptno
@@ -1268,7 +1270,8 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
if (lineNumber && !debuggerCore()->boolSetting(OperateByInstruction)
&& QFileInfo(fullName).exists()
&& !isQmlStepBreakpoint1(bkptno)
&& !isQmlStepBreakpoint2(bkptno))
&& !isQmlStepBreakpoint2(bkptno)
&& !isQFatalBreakpoint(bkptno))
gotoLocation(Location(fullName, lineNumber));
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
@@ -2169,7 +2172,7 @@ void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkp
} else if (child.hasName("func")) {
response.functionName = _(child.data());
} else if (child.hasName("addr")) {
// <MULTIPLE> happens in constructors, inline functions, and
// <MULTIPLE> happens in constructors, inline functions, and
// at other places like 'foreach' lines. In this case there are
// fields named "addr" in the response and/or the address
// is called <MULTIPLE>.
@@ -2438,6 +2441,8 @@ void GdbEngine::handleBreakList(const GdbMi &table)
needle.number = bkpt.findChild("number").data().toInt();
if (isQmlStepBreakpoint2(needle.number))
continue;
if (isQFatalBreakpoint(needle.number))
continue;
BreakpointId id = breakHandler()->findSimilarBreakpoint(needle);
if (id != BreakpointId(-1)) {
updateBreakpointDataFromOutput(id, bkpt);
@@ -4622,8 +4627,10 @@ void GdbEngine::handleInferiorPrepared()
// Apply source path mappings from global options.
const SourcePathMap sourcePathMap =
DebuggerSourcePathMappingWidget::mergePlatformQtPath(startParameters().qtInstallPath,
debuggerCore()->globalDebuggerOptions()->sourcePathMap);
DebuggerSourcePathMappingWidget::mergePlatformQtPath(
startParameters().qtInstallPath,
debuggerCore()->globalDebuggerOptions()->sourcePathMap);
if (!sourcePathMap.isEmpty()) {
const SourcePathMapIterator cend = sourcePathMap.constEnd();
for (SourcePathMapIterator it = sourcePathMap.constBegin(); it != cend; ++it) {
@@ -4653,6 +4660,52 @@ void GdbEngine::handleInferiorPrepared()
void GdbEngine::finishInferiorSetup()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
// Extract Qt namespace.
QString fileName;
{
QTemporaryFile symbols(QDir::tempPath() + _("/gdb_ns_"));
symbols.open();
fileName = symbols.fileName();
}
postCommand("maint print msymbols " + fileName.toLocal8Bit(),
CB(handleNamespaceExtraction), fileName);
}
void GdbEngine::handleNamespaceExtraction(const GdbResponse &response)
{
QFile file(response.cookie.toString());
file.open(QIODevice::ReadOnly);
QByteArray ba = file.readAll();
//file.remove();
int pos = ba.indexOf("7QString9fromAscii");
int pos1 = pos - 1;
while (pos1 > 0 && ba.at(pos1) != 'N' && ba.at(pos1) > '@')
--pos1;
++pos1;
const QByteArray ns = ba.mid(pos1, pos - pos1);
if (ns.isEmpty()) {
showMessage(_("FOUND NON-NAMESPACED QT"));
} else {
showMessage(_("FOUND NAMESPACED QT: " + ns));
setQtNamespace(ns + "::");
}
postCommand("-break-insert -f '" + qtNamespace() + "qFatal'",
CB(handleBreakOnQFatal));
}
void GdbEngine::handleBreakOnQFatal(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
GdbMi bkpt = response.data.findChild("bkpt");
GdbMi number = bkpt.findChild("number");
int bpnr = number.data().toInt();
if (bpnr) {
m_qFatalBreakpointNumber = bpnr;
postCommand("-break-commands " + number.data() + " return");
}
}
// Continue setup.
notifyInferiorSetupOk();
}
@@ -4786,6 +4839,11 @@ bool GdbEngine::isQmlStepBreakpoint2(int bpnr) const
return bpnr && m_qmlBreakpointNumbers[2] == bpnr;
}
bool GdbEngine::isQFatalBreakpoint(int bpnr) const
{
return bpnr && m_qFatalBreakpointNumber == bpnr;
}
//
// Factory
//