forked from qt-creator/qt-creator
Fixes: debugger: introduce early break after application
initialization
This commit is contained in:
@@ -543,12 +543,6 @@ void DebuggerManager::notifyStartupFinished()
|
|||||||
{
|
{
|
||||||
setStatus(DebuggerProcessReady);
|
setStatus(DebuggerProcessReady);
|
||||||
showStatusMessage(tr("Startup finished. Debugger ready."), -1);
|
showStatusMessage(tr("Startup finished. Debugger ready."), -1);
|
||||||
if (m_startMode == attachExternal) {
|
|
||||||
// we continue the execution
|
|
||||||
engine()->continueInferior();
|
|
||||||
} else {
|
|
||||||
engine()->runInferior();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerManager::notifyInferiorStopped()
|
void DebuggerManager::notifyInferiorStopped()
|
||||||
|
@@ -100,6 +100,9 @@ enum GdbCommandType
|
|||||||
GdbQuerySources,
|
GdbQuerySources,
|
||||||
GdbAsyncOutput2,
|
GdbAsyncOutput2,
|
||||||
GdbExecRun,
|
GdbExecRun,
|
||||||
|
GdbExecStart1,
|
||||||
|
GdbExecStart2,
|
||||||
|
GdbExecStart3,
|
||||||
GdbExecRunToFunction,
|
GdbExecRunToFunction,
|
||||||
GdbExecStep,
|
GdbExecStep,
|
||||||
GdbExecNext,
|
GdbExecNext,
|
||||||
@@ -635,6 +638,7 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
|
|||||||
}
|
}
|
||||||
if (pid == q->m_attachedPID)
|
if (pid == q->m_attachedPID)
|
||||||
return;
|
return;
|
||||||
|
//qDebug() << "FOUND PID " << pid;
|
||||||
q->m_attachedPID = pid;
|
q->m_attachedPID = pid;
|
||||||
qq->notifyInferiorPidChanged(pid);
|
qq->notifyInferiorPidChanged(pid);
|
||||||
}
|
}
|
||||||
@@ -686,8 +690,8 @@ void GdbEngine::sendCommand(const QString &command, int type,
|
|||||||
//qDebug() << qPrintable(currentTime()) << "RUNNING" << cmd.command;
|
//qDebug() << qPrintable(currentTime()) << "RUNNING" << cmd.command;
|
||||||
m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
|
m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
|
||||||
//emit gdbInputAvailable(QString(), " " + currentTime());
|
//emit gdbInputAvailable(QString(), " " + currentTime());
|
||||||
emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
|
//emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
|
||||||
//emit gdbInputAvailable(QString(), cmd.command);
|
emit gdbInputAvailable(QString(), cmd.command);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temporarilyStopped)
|
if (temporarilyStopped)
|
||||||
@@ -753,9 +757,18 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
|||||||
case GdbExecContinue:
|
case GdbExecContinue:
|
||||||
case GdbExecFinish:
|
case GdbExecFinish:
|
||||||
// evil code sharing
|
// evil code sharing
|
||||||
case GdbExecRun:
|
|
||||||
handleExecRun(record);
|
handleExecRun(record);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GdbExecStart1:
|
||||||
|
handleExecStart1(record);
|
||||||
|
break;
|
||||||
|
case GdbExecStart2:
|
||||||
|
handleExecStart2(record);
|
||||||
|
break;
|
||||||
|
case GdbExecStart3:
|
||||||
|
handleExecStart3(record);
|
||||||
|
break;
|
||||||
case GdbInfoProc:
|
case GdbInfoProc:
|
||||||
handleInfoProc(record);
|
handleInfoProc(record);
|
||||||
break;
|
break;
|
||||||
@@ -1134,6 +1147,34 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
|||||||
const QString reason = data.findChild("reason").data();
|
const QString reason = data.findChild("reason").data();
|
||||||
|
|
||||||
QString console = data.findChild("consolestreamoutput").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()) {
|
if (console.contains("Stopped due to shared library event") || reason.isEmpty()) {
|
||||||
++m_shared;
|
++m_shared;
|
||||||
//if (m_shared == 2)
|
//if (m_shared == 2)
|
||||||
@@ -1162,6 +1203,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (isExitedReason(reason)) {
|
if (isExitedReason(reason)) {
|
||||||
qq->notifyInferiorExited();
|
qq->notifyInferiorExited();
|
||||||
@@ -1218,7 +1260,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
|||||||
if (reason == "breakpoint-hit") {
|
if (reason == "breakpoint-hit") {
|
||||||
q->showStatusMessage(tr("Stopped at breakpoint"));
|
q->showStatusMessage(tr("Stopped at breakpoint"));
|
||||||
GdbMi frame = data.findChild("frame");
|
GdbMi frame = data.findChild("frame");
|
||||||
//qDebug() << frame.toString();
|
qDebug() << "HIT BREAKPOINT: " << frame.toString();
|
||||||
m_currentFrame = frame.findChild("addr").data() + '%' +
|
m_currentFrame = frame.findChild("addr").data() + '%' +
|
||||||
frame.findChild("func").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) {
|
if (q->startMode() == q->attachExternal) {
|
||||||
sendCommand("attach " + QString::number(q->m_attachedPID));
|
sendCommand("attach " + QString::number(q->m_attachedPID));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->startMode() == q->startInternal || q->startMode() == q->startExternal) {
|
if (q->startMode() == q->startExternal) {
|
||||||
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
|
//sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
|
||||||
|
sendCommand("file " + fileName, GdbFileExecAndSymbols);
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
sendCommand("sharedlibrary apply-load-rules all");
|
sendCommand("sharedlibrary apply-load-rules all");
|
||||||
#endif
|
#endif
|
||||||
sendCommand("-file-list-exec-source-files", GdbQuerySources);
|
//sendCommand("-file-list-exec-source-files", GdbQuerySources);
|
||||||
//sendCommand("-gdb-set stop-on-solib-events 1");
|
//sendCommand("-gdb-set stop-on-solib-events 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1625,7 +1678,7 @@ bool GdbEngine::startDebugger()
|
|||||||
else
|
else
|
||||||
qq->breakHandler()->setAllPending();
|
qq->breakHandler()->setAllPending();
|
||||||
|
|
||||||
QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
|
//QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1648,7 +1701,33 @@ void GdbEngine::runInferior()
|
|||||||
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
||||||
qq->notifyInferiorRunningRequested();
|
qq->notifyInferiorRunningRequested();
|
||||||
emit gdbInputAvailable(QString(), QString());
|
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)
|
#if defined(Q_OS_WIN)
|
||||||
sendCommand("info proc", GdbInfoProc);
|
sendCommand("info proc", GdbInfoProc);
|
||||||
#endif
|
#endif
|
||||||
@@ -1658,6 +1737,7 @@ void GdbEngine::runInferior()
|
|||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
sendCommand("info pid", GdbInfoProc, QVariant(), true);
|
sendCommand("info pid", GdbInfoProc, QVariant(), true);
|
||||||
#endif
|
#endif
|
||||||
|
attemptBreakpointSynchronization();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::stepExec()
|
void GdbEngine::stepExec()
|
||||||
@@ -2183,8 +2263,10 @@ void GdbEngine::attemptBreakpointSynchronization()
|
|||||||
//sendListBreakpoints();
|
//sendListBreakpoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!updateNeeded && q->status() == DebuggerProcessStartingUp)
|
if (!updateNeeded && q->status() == DebuggerProcessStartingUp) {
|
||||||
qq->notifyStartupFinished();
|
// we continue the execution
|
||||||
|
continueInferior();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3603,7 +3685,7 @@ void GdbEngine::updateLocals()
|
|||||||
// '2' is 'list with type and value'
|
// '2' is 'list with type and value'
|
||||||
sendSynchronizedCommand("-stack-list-locals 2", StackListLocals); // stage 2/2
|
sendSynchronizedCommand("-stack-list-locals 2", StackListLocals); // stage 2/2
|
||||||
|
|
||||||
tryLoadCustomDumpers();
|
//tryLoadCustomDumpers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleStackListArguments(const GdbResultRecord &record)
|
void GdbEngine::handleStackListArguments(const GdbResultRecord &record)
|
||||||
|
@@ -185,6 +185,9 @@ private:
|
|||||||
void handleResultRecord(const GdbResultRecord &response);
|
void handleResultRecord(const GdbResultRecord &response);
|
||||||
void handleFileExecAndSymbols(const GdbResultRecord &response);
|
void handleFileExecAndSymbols(const GdbResultRecord &response);
|
||||||
void handleExecRun(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 handleExecJumpToLine(const GdbResultRecord &response);
|
||||||
void handleExecRunToFunction(const GdbResultRecord &response);
|
void handleExecRunToFunction(const GdbResultRecord &response);
|
||||||
void handleInfoShared(const GdbResultRecord &response);
|
void handleInfoShared(const GdbResultRecord &response);
|
||||||
|
Reference in New Issue
Block a user