Debugger[gdb/MS Windows/console]: Fix attaching

Resume thread after attaching and ignore the
signal-trap that follows it.

Reviewed-by: hjk
Task-number: QTCREATORBUG-1020
This commit is contained in:
Friedemann Kleint
2010-09-02 16:46:39 +02:00
parent ec64e1d7bd
commit 3a44135ed0
2 changed files with 63 additions and 10 deletions

View File

@@ -947,7 +947,8 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
if (!isExpectedResult) { if (!isExpectedResult) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Ignore spurious 'running' responses to 'attach' // Ignore spurious 'running' responses to 'attach'
const bool warning = !(startParameters().startMode == AttachExternal const bool warning = !((startParameters().startMode == AttachExternal
|| startParameters().useTerminal)
&& cmd.command.startsWith("attach")); && cmd.command.startsWith("attach"));
#else #else
const bool warning = true; const bool warning = true;
@@ -1368,14 +1369,15 @@ void GdbEngine::handleStop1(const GdbMi &data)
QByteArray reason = data.findChild("reason").data(); QByteArray reason = data.findChild("reason").data();
if (0 && m_gdbAdapter->isTrkAdapter() #ifdef Q_OS_WIN
&& reason == "signal-received" if (startParameters().useTerminal && reason == "signal-received"
&& data.findChild("signal-name").data() == "SIGTRAP") { && data.findChild("signal-name").data() == "SIGTRAP") {
// Caused by "library load" message. // Command line start up trap
showMessage(_("INTERNAL CONTINUE")); showMessage(_("INTERNAL CONTINUE"), LogMisc);
continueInferiorInternal(); continueInferiorInternal();
return; return;
} }
#endif
// This is for display only. // This is for display only.
if (m_modulesListOutdated) if (m_modulesListOutdated)

View File

@@ -38,6 +38,11 @@
#include <QtGui/QMessageBox> #include <QtGui/QMessageBox>
#ifdef Q_OS_WIN
# include <windows.h>
# include <utils/winutils.h>
#endif
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -119,23 +124,69 @@ void TermGdbAdapter::setupInferior()
{ {
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
const qint64 attachedPID = m_stubProc.applicationPID(); const qint64 attachedPID = m_stubProc.applicationPID();
#ifdef Q_OS_WIN
const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID();
showMessage(QString::fromLatin1("Attaching to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID), LogMisc);
#else
showMessage(QString::fromLatin1("Attaching to %1").arg(attachedPID), LogMisc);
#endif
m_engine->notifyInferiorPid(attachedPID); m_engine->notifyInferiorPid(attachedPID);
m_engine->postCommand("attach " + QByteArray::number(attachedPID), m_engine->postCommand("attach " + QByteArray::number(attachedPID),
CB(handleStubAttached)); CB(handleStubAttached));
} }
#ifdef Q_OS_WIN
static bool resumeThread(DWORD dwThreadId)
{
bool ok = false;
HANDLE handle = NULL;
do {
if (!dwThreadId)
break;
handle = OpenThread(SYNCHRONIZE |THREAD_QUERY_INFORMATION |THREAD_SUSPEND_RESUME,
FALSE, dwThreadId);
if (handle==NULL)
break;
ok = ResumeThread(handle) != DWORD(-1);
} while (false);
if (handle != NULL)
CloseHandle(handle);
return ok;
}
#endif // Q_OS_WIN
void TermGdbAdapter::handleStubAttached(const GdbResponse &response) void TermGdbAdapter::handleStubAttached(const GdbResponse &response)
{ {
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) { switch (response.resultClass) {
case GdbResultDone:
case GdbResultRunning:
#ifdef Q_OS_WIN
// Resume thread that was suspended by console stub process (see stub code).
if (resumeThread(m_stubProc.applicationMainThreadID())) {
showMessage(QString::fromLatin1("Inferior attached, thread %1 resumed").
arg(m_stubProc.applicationMainThreadID()), LogMisc);
} else {
showMessage(QString::fromLatin1("Inferior attached, unable to resume thread %1: %2").
arg(m_stubProc.applicationMainThreadID()).arg(Utils::winErrorMessage(GetLastError())),
LogWarning);
}
#else
showMessage(_("INFERIOR ATTACHED")); showMessage(_("INFERIOR ATTACHED"));
#endif // Q_OS_WIN
m_engine->handleInferiorPrepared(); m_engine->handleInferiorPrepared();
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
m_engine->postCommand("-stack-list-frames 0 0", CB(handleEntryPoint)); m_engine->postCommand("-stack-list-frames 0 0", CB(handleEntryPoint));
#endif #endif
} else if (response.resultClass == GdbResultError) { break;
QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data()); case GdbResultError:
m_engine->notifyInferiorSetupFailed(msg); m_engine->notifyInferiorSetupFailed(QString::fromLocal8Bit(response.data.findChild("msg").data()));
break;
default:
m_engine->notifyInferiorSetupFailed(QString::fromLatin1("Invalid response %1").arg(response.resultClass));
break;
} }
} }