forked from qt-creator/qt-creator
Fixes: debugger: start symbol is WinMainCRTStartup, not _start
sometimes...
This commit is contained in:
@@ -230,6 +230,15 @@ static bool isLeavableFunction(const QString &funcName, const QString &fileName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString startSymbolName()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
return "WinMainCRTStartup";
|
||||||
|
#else
|
||||||
|
return "_start";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -251,6 +260,7 @@ GdbEngine::~GdbEngine()
|
|||||||
void GdbEngine::init()
|
void GdbEngine::init()
|
||||||
{
|
{
|
||||||
m_pendingRequests = 0;
|
m_pendingRequests = 0;
|
||||||
|
m_waitingForBreakpointSynchronizationToContinue = false;
|
||||||
m_gdbVersion = 100;
|
m_gdbVersion = 100;
|
||||||
m_outputCodec = QTextCodec::codecForLocale();
|
m_outputCodec = QTextCodec::codecForLocale();
|
||||||
m_dataDumperState = DataDumperUninitialized;
|
m_dataDumperState = DataDumperUninitialized;
|
||||||
@@ -650,7 +660,7 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
|
|||||||
}
|
}
|
||||||
if (pid == q->m_attachedPID)
|
if (pid == q->m_attachedPID)
|
||||||
return;
|
return;
|
||||||
//qDebug() << "FOUND PID " << pid;
|
qDebug() << "FOUND PID " << pid;
|
||||||
q->m_attachedPID = pid;
|
q->m_attachedPID = pid;
|
||||||
qq->notifyInferiorPidChanged(pid);
|
qq->notifyInferiorPidChanged(pid);
|
||||||
}
|
}
|
||||||
@@ -750,8 +760,10 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
|
|||||||
--m_pendingRequests;
|
--m_pendingRequests;
|
||||||
PENDING_DEBUG(" TYPE " << cmd.type << " DECREMENTS PENDING TO: "
|
PENDING_DEBUG(" TYPE " << cmd.type << " DECREMENTS PENDING TO: "
|
||||||
<< m_pendingRequests << cmd.command);
|
<< m_pendingRequests << cmd.command);
|
||||||
if (m_pendingRequests <= 0)
|
if (m_pendingRequests <= 0) {
|
||||||
|
PENDING_DEBUG(" .... AND TRIGGERS MODEL UPDATE");
|
||||||
updateWatchModel2();
|
updateWatchModel2();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
PENDING_DEBUG(" UNKNOWN TYPE " << cmd.type << " LEAVES PENDING AT: "
|
PENDING_DEBUG(" UNKNOWN TYPE " << cmd.type << " LEAVES PENDING AT: "
|
||||||
<< m_pendingRequests << cmd.command);
|
<< m_pendingRequests << cmd.command);
|
||||||
@@ -1065,8 +1077,10 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
|||||||
QString msg = data.findChild("consolestreamoutput").data();
|
QString msg = data.findChild("consolestreamoutput").data();
|
||||||
if (reason.isEmpty()) {
|
if (reason.isEmpty()) {
|
||||||
GdbMi frame = data.findChild("frame");
|
GdbMi frame = data.findChild("frame");
|
||||||
if (frame.findChild("func").data() == "_start") {
|
if (frame.findChild("func").data() == startSymbolName()) {
|
||||||
|
//
|
||||||
// that's the "early stop"
|
// that's the "early stop"
|
||||||
|
//
|
||||||
frame.findChild("func").data() + '%';
|
frame.findChild("func").data() + '%';
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
sendCommand("info proc", GdbInfoProc);
|
sendCommand("info proc", GdbInfoProc);
|
||||||
@@ -1078,9 +1092,6 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
|||||||
sendCommand("info pid", GdbInfoProc, QVariant(), true);
|
sendCommand("info pid", GdbInfoProc, QVariant(), true);
|
||||||
#endif
|
#endif
|
||||||
sendCommand("-file-list-exec-source-files", GdbQuerySources);
|
sendCommand("-file-list-exec-source-files", GdbQuerySources);
|
||||||
|
|
||||||
sendCommand("sharedlibrary libc"); // for malloc
|
|
||||||
sendCommand("sharedlibrary libdl"); // for dlopen
|
|
||||||
tryLoadCustomDumpers();
|
tryLoadCustomDumpers();
|
||||||
|
|
||||||
// intentionally after tryLoadCustomDumpers(),
|
// intentionally after tryLoadCustomDumpers(),
|
||||||
@@ -1098,11 +1109,12 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
|||||||
sendCommand("set auto-solib-add off");
|
sendCommand("set auto-solib-add off");
|
||||||
sendCommand("set stop-on-solib-events 0");
|
sendCommand("set stop-on-solib-events 0");
|
||||||
}
|
}
|
||||||
reloadModules();
|
|
||||||
// this will "continue" if done
|
// this will "continue" if done
|
||||||
attemptBreakpointSynchronization();
|
m_waitingForBreakpointSynchronizationToContinue = true;
|
||||||
|
QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
qDebug() << "EMPTY REASON FOR STOPPED";
|
||||||
// fall through
|
// fall through
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1231,7 +1243,7 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data)
|
|||||||
//
|
//
|
||||||
// Breakpoints
|
// Breakpoints
|
||||||
//
|
//
|
||||||
//qDebug() << "BREAK ASYNC: " << output.toString();
|
//qDebug() << "BREAK ASYNC: " << data.toString();
|
||||||
//sendListBreakpoints();
|
//sendListBreakpoints();
|
||||||
//attemptBreakpointSynchronization();
|
//attemptBreakpointSynchronization();
|
||||||
//if (m_breakListOnStopNeeded)
|
//if (m_breakListOnStopNeeded)
|
||||||
@@ -1572,7 +1584,7 @@ bool GdbEngine::startDebugger()
|
|||||||
if (!q->m_processArgs.isEmpty())
|
if (!q->m_processArgs.isEmpty())
|
||||||
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
||||||
sendCommand("set auto-solib-add off");
|
sendCommand("set auto-solib-add off");
|
||||||
sendCommand("x/2i _start", GdbStart);
|
sendCommand("x/2i " + startSymbolName(), GdbStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->startMode() == q->attachExternal) {
|
if (q->startMode() == q->attachExternal) {
|
||||||
@@ -1597,8 +1609,6 @@ bool GdbEngine::startDebugger()
|
|||||||
else
|
else
|
||||||
qq->breakHandler()->setAllPending();
|
qq->breakHandler()->setAllPending();
|
||||||
|
|
||||||
//QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1618,7 +1628,7 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
|
|||||||
// stdout:~"0x404540 <_start>:\txor %ebp,%ebp\n"
|
// stdout:~"0x404540 <_start>:\txor %ebp,%ebp\n"
|
||||||
// stdout:~"0x404542 <_start+2>:\tmov %rdx,%r9\n"
|
// stdout:~"0x404542 <_start+2>:\tmov %rdx,%r9\n"
|
||||||
QString msg = response.data.findChild("consolestreamoutput").data();
|
QString msg = response.data.findChild("consolestreamoutput").data();
|
||||||
QRegExp needle("0x([0-9a-f]+) <_start\\+.*>:");
|
QRegExp needle("0x([0-9a-f]+) <" + startSymbolName() + "\\+.*>:");
|
||||||
if (needle.indexIn(msg) != -1) {
|
if (needle.indexIn(msg) != -1) {
|
||||||
//qDebug() << "STREAM: " << msg << needle.cap(1);
|
//qDebug() << "STREAM: " << msg << needle.cap(1);
|
||||||
sendCommand("tbreak *0x" + needle.cap(1));
|
sendCommand("tbreak *0x" + needle.cap(1));
|
||||||
@@ -2080,11 +2090,14 @@ void GdbEngine::handleBreakInsert1(const GdbResultRecord &record, int index)
|
|||||||
|
|
||||||
void GdbEngine::attemptBreakpointSynchronization()
|
void GdbEngine::attemptBreakpointSynchronization()
|
||||||
{
|
{
|
||||||
|
// Non-lethal check for nested calls
|
||||||
|
static bool inBreakpointSychronization = false;
|
||||||
|
QTC_ASSERT(!inBreakpointSychronization, /**/);
|
||||||
|
inBreakpointSychronization = true;
|
||||||
|
|
||||||
BreakHandler *handler = qq->breakHandler();
|
BreakHandler *handler = qq->breakHandler();
|
||||||
//qDebug() << "BREAKPOINT SYNCHRONIZATION ";
|
|
||||||
|
|
||||||
foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) {
|
foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) {
|
||||||
//qDebug() << " SYNCHRONIZATION REMOVING" << data;
|
|
||||||
QString bpNumber = data->bpNumber;
|
QString bpNumber = data->bpNumber;
|
||||||
if (!bpNumber.trimmed().isEmpty())
|
if (!bpNumber.trimmed().isEmpty())
|
||||||
sendCommand("-break-delete " + bpNumber, BreakDelete, 0, true);
|
sendCommand("-break-delete " + bpNumber, BreakDelete, 0, true);
|
||||||
@@ -2150,10 +2163,13 @@ void GdbEngine::attemptBreakpointSynchronization()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!updateNeeded) {
|
if (!updateNeeded && m_waitingForBreakpointSynchronizationToContinue) {
|
||||||
|
m_waitingForBreakpointSynchronizationToContinue = false;
|
||||||
// we continue the execution
|
// we continue the execution
|
||||||
continueInferior();
|
continueInferior();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inBreakpointSychronization = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3931,12 +3947,14 @@ void GdbEngine::tryLoadCustomDumpers()
|
|||||||
if (QFileInfo(lib).isExecutable()) {
|
if (QFileInfo(lib).isExecutable()) {
|
||||||
//sendCommand("p dlopen");
|
//sendCommand("p dlopen");
|
||||||
QString flag = QString::number(RTLD_NOW);
|
QString flag = QString::number(RTLD_NOW);
|
||||||
sendSynchronizedCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
|
sendCommand("sharedlibrary libc"); // for malloc
|
||||||
|
sendCommand("sharedlibrary libdl"); // for dlopen
|
||||||
|
sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
|
||||||
WatchDumpCustomSetup);
|
WatchDumpCustomSetup);
|
||||||
// some older systems like CentOS 4.6 prefer this:
|
// some older systems like CentOS 4.6 prefer this:
|
||||||
sendSynchronizedCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")",
|
sendCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")",
|
||||||
WatchDumpCustomSetup);
|
WatchDumpCustomSetup);
|
||||||
sendSynchronizedCommand("sharedlibrary " + dotEscape(lib));
|
sendCommand("sharedlibrary " + dotEscape(lib));
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
|
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
|
||||||
<< lib << QFileInfo(lib).isExecutable();
|
<< lib << QFileInfo(lib).isExecutable();
|
||||||
@@ -3945,11 +3963,12 @@ void GdbEngine::tryLoadCustomDumpers()
|
|||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
QString lib = q->m_buildDir + "/qtc-gdbmacros/libgdbmacros.dylib";
|
QString lib = q->m_buildDir + "/qtc-gdbmacros/libgdbmacros.dylib";
|
||||||
if (QFileInfo(lib).isExecutable()) {
|
if (QFileInfo(lib).isExecutable()) {
|
||||||
//sendCommand("p dlopen"); // FIXME: remove me
|
sendCommand("sharedlibrary libc"); // for malloc
|
||||||
|
sendCommand("sharedlibrary libdl"); // for dlopen
|
||||||
QString flag = QString::number(RTLD_NOW);
|
QString flag = QString::number(RTLD_NOW);
|
||||||
sendSynchronizedCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
|
sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
|
||||||
WatchDumpCustomSetup);
|
WatchDumpCustomSetup);
|
||||||
sendSynchronizedCommand("sharedlibrary " + dotEscape(lib));
|
sendCommand("sharedlibrary " + dotEscape(lib));
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
|
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
|
||||||
<< lib << QFileInfo(lib).isExecutable();
|
<< lib << QFileInfo(lib).isExecutable();
|
||||||
@@ -3958,11 +3977,12 @@ void GdbEngine::tryLoadCustomDumpers()
|
|||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
QString lib = q->m_buildDir + "/qtc-gdbmacros/debug/gdbmacros.dll";
|
QString lib = q->m_buildDir + "/qtc-gdbmacros/debug/gdbmacros.dll";
|
||||||
if (QFileInfo(lib).exists()) {
|
if (QFileInfo(lib).exists()) {
|
||||||
|
sendCommand("sharedlibrary .*"); // for LoadLibraryA
|
||||||
//sendCommand("handle SIGSEGV pass stop print");
|
//sendCommand("handle SIGSEGV pass stop print");
|
||||||
//sendCommand("set unwindonsignal off");
|
//sendCommand("set unwindonsignal off");
|
||||||
sendSynchronizedCommand("call LoadLibraryA(\"" + lib + "\")",
|
sendCommand("call LoadLibraryA(\"" + lib + "\")",
|
||||||
WatchDumpCustomSetup);
|
WatchDumpCustomSetup);
|
||||||
sendSynchronizedCommand("sharedlibrary " + dotEscape(lib));
|
sendCommand("sharedlibrary " + dotEscape(lib));
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
|
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
|
||||||
<< lib << QFileInfo(lib).isExecutable();
|
<< lib << QFileInfo(lib).isExecutable();
|
||||||
@@ -3970,9 +3990,9 @@ void GdbEngine::tryLoadCustomDumpers()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// retreive list of dumpable classes
|
// retreive list of dumpable classes
|
||||||
sendSynchronizedCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)",
|
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)",
|
||||||
GdbQueryDataDumper1);
|
GdbQueryDataDumper1);
|
||||||
sendSynchronizedCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper2);
|
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -328,6 +328,8 @@ private:
|
|||||||
QString m_currentFrame;
|
QString m_currentFrame;
|
||||||
QMap<QString, QString> m_varToType;
|
QMap<QString, QString> m_varToType;
|
||||||
|
|
||||||
|
bool m_waitingForBreakpointSynchronizationToContinue;
|
||||||
|
|
||||||
DebuggerManager *q;
|
DebuggerManager *q;
|
||||||
IDebuggerManagerAccessForEngines *qq;
|
IDebuggerManagerAccessForEngines *qq;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user