forked from qt-creator/qt-creator
Fixes: debugger: work on breakpoints in plugins
This commit is contained in:
@@ -561,7 +561,7 @@ void DebuggerManager::notifyInferiorUpdateFinished()
|
|||||||
void DebuggerManager::notifyInferiorRunningRequested()
|
void DebuggerManager::notifyInferiorRunningRequested()
|
||||||
{
|
{
|
||||||
setStatus(DebuggerInferiorRunningRequested);
|
setStatus(DebuggerInferiorRunningRequested);
|
||||||
showStatusMessage(tr("Running..."), 5000);
|
showStatusMessage(tr("Running requested..."), 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerManager::notifyInferiorRunning()
|
void DebuggerManager::notifyInferiorRunning()
|
||||||
@@ -579,7 +579,7 @@ void DebuggerManager::notifyInferiorExited()
|
|||||||
void DebuggerManager::notifyInferiorPidChanged(int pid)
|
void DebuggerManager::notifyInferiorPidChanged(int pid)
|
||||||
{
|
{
|
||||||
//QMessageBox::warning(0, "PID", "PID: " + QString::number(pid));
|
//QMessageBox::warning(0, "PID", "PID: " + QString::number(pid));
|
||||||
//qDebug() << "PID: " << pid;
|
qDebug() << "PID: " << pid;
|
||||||
emit inferiorPidChanged(pid);
|
emit inferiorPidChanged(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -337,7 +337,6 @@ void GdbOptionPage::apply()
|
|||||||
m_settings.m_pluginSelectedBreakpointsPattern =
|
m_settings.m_pluginSelectedBreakpointsPattern =
|
||||||
m_ui.lineEditSelectedPluginBreakpointsPattern->text();
|
m_ui.lineEditSelectedPluginBreakpointsPattern->text();
|
||||||
|
|
||||||
|
|
||||||
*m_plugin->m_manager->settings() = m_settings;
|
*m_plugin->m_manager->settings() = m_settings;
|
||||||
m_plugin->writeSettings();
|
m_plugin->writeSettings();
|
||||||
}
|
}
|
||||||
|
@@ -99,10 +99,8 @@ enum GdbCommandType
|
|||||||
GdbQueryPwd,
|
GdbQueryPwd,
|
||||||
GdbQuerySources,
|
GdbQuerySources,
|
||||||
GdbAsyncOutput2,
|
GdbAsyncOutput2,
|
||||||
|
GdbStart,
|
||||||
GdbExecRun,
|
GdbExecRun,
|
||||||
GdbExecStart1,
|
|
||||||
GdbExecStart2,
|
|
||||||
GdbExecStart3,
|
|
||||||
GdbExecRunToFunction,
|
GdbExecRunToFunction,
|
||||||
GdbExecStep,
|
GdbExecStep,
|
||||||
GdbExecNext,
|
GdbExecNext,
|
||||||
@@ -460,13 +458,28 @@ void GdbEngine::handleResponse()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '~':
|
case '~': {
|
||||||
case '@':
|
QString data = GdbMi::parseCString(from, to);
|
||||||
|
m_pendingConsoleStreamOutput += data;
|
||||||
|
m_inbuffer = QByteArray(from, to - from);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '@': {
|
||||||
|
QString data = GdbMi::parseCString(from, to);
|
||||||
|
m_pendingTargetStreamOutput += data;
|
||||||
|
m_inbuffer = QByteArray(from, to - from);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case '&': {
|
case '&': {
|
||||||
QString data = GdbMi::parseCString(from, to);
|
QString data = GdbMi::parseCString(from, to);
|
||||||
handleStreamOutput(data, c);
|
m_pendingLogStreamOutput += data;
|
||||||
//dump(oldfrom, from, record.toString());
|
|
||||||
m_inbuffer = QByteArray(from, to - from);
|
m_inbuffer = QByteArray(from, to - from);
|
||||||
|
// On Windows, the contents seem to depend on the debugger
|
||||||
|
// version and/or OS version used.
|
||||||
|
if (data.startsWith("warning:"))
|
||||||
|
qq->showApplicationOutput(data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -759,14 +772,8 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
|||||||
handleExecRun(record);
|
handleExecRun(record);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GdbExecStart1:
|
case GdbStart:
|
||||||
handleExecStart1(record);
|
handleStart(record);
|
||||||
break;
|
|
||||||
case GdbExecStart2:
|
|
||||||
//handleExecStart2(record);
|
|
||||||
break;
|
|
||||||
case GdbExecStart3:
|
|
||||||
handleExecStart3(record);
|
|
||||||
break;
|
break;
|
||||||
case GdbInfoProc:
|
case GdbInfoProc:
|
||||||
handleInfoProc(record);
|
handleInfoProc(record);
|
||||||
@@ -1028,84 +1035,6 @@ void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record)
|
|||||||
q->gotoLocation(file, line, true);
|
q->gotoLocation(file, line, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleStreamOutput(const QString &data, char code)
|
|
||||||
{
|
|
||||||
// Linux
|
|
||||||
if (data.contains("[New Thread")) {
|
|
||||||
QRegExp re("\\[New Thread 0x([0-9a-f]*) \\(LWP ([0-9]*)\\)\\]");
|
|
||||||
if (re.indexIn(data) != -1)
|
|
||||||
maybeHandleInferiorPidChanged(re.cap(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mac
|
|
||||||
if (data.contains("[Switching to process ")) {
|
|
||||||
QRegExp re("\\[Switching to process ([0-9]*) local thread 0x([0-9a-f]*)\\]");
|
|
||||||
if (re.indexIn(data) != -1)
|
|
||||||
maybeHandleInferiorPidChanged(re.cap(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// present it twice: now and together with the next 'real' result
|
|
||||||
switch (code) {
|
|
||||||
case '~':
|
|
||||||
m_pendingConsoleStreamOutput += data;
|
|
||||||
break;
|
|
||||||
case '@':
|
|
||||||
m_pendingTargetStreamOutput += data;
|
|
||||||
break;
|
|
||||||
case '&':
|
|
||||||
m_pendingLogStreamOutput += data;
|
|
||||||
// On Windows, the contents seem to depend on the debugger
|
|
||||||
// version and/or OS version used.
|
|
||||||
if (data.startsWith("warning:"))
|
|
||||||
qq->showApplicationOutput(data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
if (data.startsWith("Pending break") && data.contains("\" resolved")) {
|
|
||||||
qDebug() << "SCHEDULING -break-list";
|
|
||||||
//m_breakListOnStopNeeded = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (m_slurpingPTypeOutput)
|
|
||||||
qDebug() << "SLURP: " << output.data;
|
|
||||||
|
|
||||||
// "No symbol \"__dlopen\" in current context."
|
|
||||||
// "No symbol \"dlopen\" in current context."
|
|
||||||
if (output.data.startsWith("No symbol ")
|
|
||||||
&& output.data.contains("dlopen")) {
|
|
||||||
m_dlopened = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// output of 'ptype <foo>'
|
|
||||||
if (output.data.startsWith("type = ")) {
|
|
||||||
if (output.data.endsWith("{") || output.data.endsWith("{\\n")) {
|
|
||||||
// multi-line output started here...
|
|
||||||
m_slurpingPTypeOutput = true;
|
|
||||||
m_slurpedPTypeOutput = output.data;
|
|
||||||
} else {
|
|
||||||
// Happens for simple types. Process it immediately
|
|
||||||
m_watchHandler->handleTypeContents(output.data);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_slurpingPTypeOutput) {
|
|
||||||
m_slurpedPTypeOutput += '\n';
|
|
||||||
m_slurpedPTypeOutput += output.data;
|
|
||||||
if (output.data.startsWith("}")) {
|
|
||||||
// this is the last line...
|
|
||||||
m_slurpingPTypeOutput = false;
|
|
||||||
m_watchHandler->handleTypeContents(m_slurpedPTypeOutput);
|
|
||||||
m_slurpedPTypeOutput.clear();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isExitedReason(const QString &reason)
|
static bool isExitedReason(const QString &reason)
|
||||||
{
|
{
|
||||||
return reason == QLatin1String("exited-normally") // inferior exited normally
|
return reason == QLatin1String("exited-normally") // inferior exited normally
|
||||||
@@ -1633,13 +1562,17 @@ bool GdbEngine::startDebugger()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (q->startMode() == q->startInternal) {
|
if (q->startMode() == q->startInternal) {
|
||||||
|
emit gdbInputAvailable(QString(), QString());
|
||||||
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
|
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
|
||||||
//sendCommand("file " + 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("-gdb-set stop-on-solib-events 1");
|
setTokenBarrier();
|
||||||
runInferior();
|
if (!q->m_processArgs.isEmpty())
|
||||||
|
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
||||||
|
sendCommand("set auto-solib-add off");
|
||||||
|
sendCommand("x/2i _start", GdbStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->startMode() == q->attachExternal) {
|
if (q->startMode() == q->attachExternal) {
|
||||||
@@ -1678,21 +1611,7 @@ void GdbEngine::continueInferior()
|
|||||||
sendCommand("-exec-continue", GdbExecContinue);
|
sendCommand("-exec-continue", GdbExecContinue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::runInferior()
|
void GdbEngine::handleStart(const GdbResultRecord &response)
|
||||||
{
|
|
||||||
q->resetLocation();
|
|
||||||
// FIXME: this ignores important startup messages
|
|
||||||
setTokenBarrier();
|
|
||||||
if (!q->m_processArgs.isEmpty())
|
|
||||||
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
|
||||||
qq->notifyInferiorRunningRequested();
|
|
||||||
emit gdbInputAvailable(QString(), QString());
|
|
||||||
|
|
||||||
sendCommand("set auto-solib-add off");
|
|
||||||
sendCommand("x/2i _start", GdbExecStart1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GdbEngine::handleExecStart1(const GdbResultRecord &response)
|
|
||||||
{
|
{
|
||||||
if (response.resultClass == GdbResultDone) {
|
if (response.resultClass == GdbResultDone) {
|
||||||
// stdout:&"x/2i _start\n"
|
// stdout:&"x/2i _start\n"
|
||||||
@@ -1702,8 +1621,9 @@ void GdbEngine::handleExecStart1(const GdbResultRecord &response)
|
|||||||
QRegExp needle("0x([0-9a-f]+) <_start\\+.*>:");
|
QRegExp needle("0x([0-9a-f]+) <_start\\+.*>:");
|
||||||
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)); // GdbExecStart3);
|
sendCommand("tbreak *0x" + needle.cap(1));
|
||||||
sendCommand("-exec-run"); // GdbExecStart3);
|
sendCommand("-exec-run");
|
||||||
|
qq->notifyInferiorRunningRequested();
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "PARSING START ADDRESS FAILED" << msg;
|
qDebug() << "PARSING START ADDRESS FAILED" << msg;
|
||||||
}
|
}
|
||||||
@@ -1712,20 +1632,6 @@ void GdbEngine::handleExecStart1(const GdbResultRecord &response)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleExecStart3(const GdbResultRecord &)
|
|
||||||
{
|
|
||||||
#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
|
|
||||||
attemptBreakpointSynchronization();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GdbEngine::stepExec()
|
void GdbEngine::stepExec()
|
||||||
{
|
{
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
@@ -2244,12 +2150,7 @@ void GdbEngine::attemptBreakpointSynchronization()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateNeeded) {
|
if (!updateNeeded) {
|
||||||
//interruptAndContinue();
|
|
||||||
//sendListBreakpoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!updateNeeded && q->status() == DebuggerProcessStartingUp) {
|
|
||||||
// we continue the execution
|
// we continue the execution
|
||||||
continueInferior();
|
continueInferior();
|
||||||
}
|
}
|
||||||
@@ -4017,7 +3918,6 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString &
|
|||||||
sendCommand("-var-assign assign " + value, WatchVarAssign);
|
sendCommand("-var-assign assign " + value, WatchVarAssign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GdbEngine::tryLoadCustomDumpers()
|
void GdbEngine::tryLoadCustomDumpers()
|
||||||
{
|
{
|
||||||
if (m_dataDumperState != DataDumperUninitialized)
|
if (m_dataDumperState != DataDumperUninitialized)
|
||||||
|
@@ -113,7 +113,6 @@ private:
|
|||||||
void exitDebugger();
|
void exitDebugger();
|
||||||
|
|
||||||
void continueInferior();
|
void continueInferior();
|
||||||
void runInferior();
|
|
||||||
void interruptInferior();
|
void interruptInferior();
|
||||||
|
|
||||||
void runToLineExec(const QString &fileName, int lineNumber);
|
void runToLineExec(const QString &fileName, int lineNumber);
|
||||||
@@ -179,14 +178,12 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int terminationIndex(const QByteArray &buffer, int &length);
|
int terminationIndex(const QByteArray &buffer, int &length);
|
||||||
void handleStreamOutput(const QString &output, char code);
|
void handleStart(const GdbResultRecord &response);
|
||||||
void handleAsyncOutput2(const GdbMi &data);
|
void handleAsyncOutput2(const GdbMi &data);
|
||||||
void handleAsyncOutput(const GdbMi &data);
|
void handleAsyncOutput(const GdbMi &data);
|
||||||
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 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);
|
||||||
|
@@ -62,7 +62,6 @@ public:
|
|||||||
virtual void nextIExec() = 0;
|
virtual void nextIExec() = 0;
|
||||||
|
|
||||||
virtual void continueInferior() = 0;
|
virtual void continueInferior() = 0;
|
||||||
virtual void runInferior() = 0;
|
|
||||||
virtual void interruptInferior() = 0;
|
virtual void interruptInferior() = 0;
|
||||||
|
|
||||||
virtual void runToLineExec(const QString &fileName, int lineNumber) = 0;
|
virtual void runToLineExec(const QString &fileName, int lineNumber) = 0;
|
||||||
|
Reference in New Issue
Block a user