Commit d5dc6d10 authored by hjk's avatar hjk
Browse files

Fixes: debugger: introduce early break after application

initialization
parent faacf69a
......@@ -543,12 +543,6 @@ void DebuggerManager::notifyStartupFinished()
{
setStatus(DebuggerProcessReady);
showStatusMessage(tr("Startup finished. Debugger ready."), -1);
if (m_startMode == attachExternal) {
// we continue the execution
engine()->continueInferior();
} else {
engine()->runInferior();
}
}
void DebuggerManager::notifyInferiorStopped()
......
......@@ -100,6 +100,9 @@ enum GdbCommandType
GdbQuerySources,
GdbAsyncOutput2,
GdbExecRun,
GdbExecStart1,
GdbExecStart2,
GdbExecStart3,
GdbExecRunToFunction,
GdbExecStep,
GdbExecNext,
......@@ -635,6 +638,7 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
}
if (pid == q->m_attachedPID)
return;
//qDebug() << "FOUND PID " << pid;
q->m_attachedPID = pid;
qq->notifyInferiorPidChanged(pid);
}
......@@ -686,8 +690,8 @@ void GdbEngine::sendCommand(const QString &command, int type,
//qDebug() << qPrintable(currentTime()) << "RUNNING" << cmd.command;
m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
//emit gdbInputAvailable(QString(), " " + currentTime());
emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
//emit gdbInputAvailable(QString(), cmd.command);
//emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
emit gdbInputAvailable(QString(), cmd.command);
}
if (temporarilyStopped)
......@@ -753,9 +757,18 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
case GdbExecContinue:
case GdbExecFinish:
// evil code sharing
case GdbExecRun:
handleExecRun(record);
break;
case GdbExecStart1:
handleExecStart1(record);
break;
case GdbExecStart2:
handleExecStart2(record);
break;
case GdbExecStart3:
handleExecStart3(record);
break;
case GdbInfoProc:
handleInfoProc(record);
break;
......@@ -1134,6 +1147,34 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
const QString reason = data.findChild("reason").data();
QString console = data.findChild("consolestreamoutput").data();
if (reason.isEmpty()) {
GdbMi frame = data.findChild("frame");
if (frame.findChild("func").data() == "_start") {
// that's the "early stop"
frame.findChild("func").data() + '%';
#if defined(Q_OS_WIN)
sendCommand("info proc", GdbInfoProc);
#endif
#if defined(Q_OS_LINUX)
sendCommand("info proc", GdbInfoProc);
#endif
#if defined(Q_OS_MAC)
sendCommand("info pid", GdbInfoProc, QVariant(), true);
#endif
sendCommand("-file-list-exec-source-files", GdbQuerySources);
sendCommand("set auto-solib-add on");
sendCommand("sharedlibrary libc"); // for malloc
sendCommand("sharedlibrary libdl"); // for dlopen
tryLoadCustomDumpers();
sendCommand("info shared", ModulesList, QVariant());
// this will "continue" if done
attemptBreakpointSynchronization();
return;
}
// fall through
}
#if 0
if (console.contains("Stopped due to shared library event") || reason.isEmpty()) {
++m_shared;
//if (m_shared == 2)
......@@ -1162,6 +1203,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
}
return;
}
#endif
if (isExitedReason(reason)) {
qq->notifyInferiorExited();
......@@ -1218,7 +1260,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
if (reason == "breakpoint-hit") {
q->showStatusMessage(tr("Stopped at breakpoint"));
GdbMi frame = data.findChild("frame");
//qDebug() << frame.toString();
qDebug() << "HIT BREAKPOINT: " << frame.toString();
m_currentFrame = frame.findChild("addr").data() + '%' +
frame.findChild("func").data() + '%';
......@@ -1604,16 +1646,27 @@ bool GdbEngine::startDebugger()
}
}
if (q->startMode() == q->startInternal) {
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
//sendCommand("file " + fileName, GdbFileExecAndSymbols);
#ifdef Q_OS_MAC
sendCommand("sharedlibrary apply-load-rules all");
#endif
//sendCommand("-gdb-set stop-on-solib-events 1");
runInferior();
}
if (q->startMode() == q->attachExternal) {
sendCommand("attach " + QString::number(q->m_attachedPID));
}
if (q->startMode() == q->startInternal || q->startMode() == q->startExternal) {
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
if (q->startMode() == q->startExternal) {
//sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
sendCommand("file " + fileName, GdbFileExecAndSymbols);
#ifdef Q_OS_MAC
sendCommand("sharedlibrary apply-load-rules all");
#endif
sendCommand("-file-list-exec-source-files", GdbQuerySources);
//sendCommand("-file-list-exec-source-files", GdbQuerySources);
//sendCommand("-gdb-set stop-on-solib-events 1");
}
......@@ -1625,7 +1678,7 @@ bool GdbEngine::startDebugger()
else
qq->breakHandler()->setAllPending();
QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
//QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
return true;
}
......@@ -1648,7 +1701,33 @@ void GdbEngine::runInferior()
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
qq->notifyInferiorRunningRequested();
emit gdbInputAvailable(QString(), QString());
sendCommand("-exec-run", GdbExecRun);
sendCommand("set auto-solib-add off");
sendCommand("x/2i _start", GdbExecStart1);
}
void GdbEngine::handleExecStart1(const GdbResultRecord &response)
{
if (response.resultClass == GdbResultDone) {
// stdout:&"x/2i _start\n"
// stdout:~"0x404540 <_start>:\txor %ebp,%ebp\n"
// stdout:~"0x404542 <_start+2>:\tmov %rdx,%r9\n"
QString msg = response.data.findChild("consolestreamoutput").data();
QRegExp needle("0x([0-9a-f]+) <_start\\+.*>:");
if (needle.indexIn(msg) != -1) {
//qDebug() << "STREAM: " << msg << needle.cap(1);
sendCommand("tbreak *0x" + needle.cap(1)); // GdbExecStart3);
sendCommand("-exec-run"); // GdbExecStart3);
} else {
qDebug() << "PARSING START ADDRESS FAILED" << msg;
}
} else if (response.resultClass == GdbResultError) {
qDebug() << "PARSING START ADDRESS FAILED" << response.toString();
}
}
void GdbEngine::handleExecStart3(const GdbResultRecord &response)
{
#if defined(Q_OS_WIN)
sendCommand("info proc", GdbInfoProc);
#endif
......@@ -1658,6 +1737,7 @@ void GdbEngine::runInferior()
#if defined(Q_OS_MAC)
sendCommand("info pid", GdbInfoProc, QVariant(), true);
#endif
attemptBreakpointSynchronization();
}
void GdbEngine::stepExec()
......@@ -2183,8 +2263,10 @@ void GdbEngine::attemptBreakpointSynchronization()
//sendListBreakpoints();
}
if (!updateNeeded && q->status() == DebuggerProcessStartingUp)
qq->notifyStartupFinished();
if (!updateNeeded && q->status() == DebuggerProcessStartingUp) {
// we continue the execution
continueInferior();
}
}
......@@ -3603,7 +3685,7 @@ void GdbEngine::updateLocals()
// '2' is 'list with type and value'
sendSynchronizedCommand("-stack-list-locals 2", StackListLocals); // stage 2/2
tryLoadCustomDumpers();
//tryLoadCustomDumpers();
}
void GdbEngine::handleStackListArguments(const GdbResultRecord &record)
......
......@@ -185,6 +185,9 @@ private:
void handleResultRecord(const GdbResultRecord &response);
void handleFileExecAndSymbols(const GdbResultRecord &response);
void handleExecRun(const GdbResultRecord &response);
void handleExecStart1(const GdbResultRecord &response);
void handleExecStart2(const GdbResultRecord &response);
void handleExecStart3(const GdbResultRecord &response);
void handleExecJumpToLine(const GdbResultRecord &response);
void handleExecRunToFunction(const GdbResultRecord &response);
void handleInfoShared(const GdbResultRecord &response);
......
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