From e7e74db758ee3964ad8898eb398652f5db00a181 Mon Sep 17 00:00:00 2001 From: David Schulz <david.schulz@nokia.com> Date: Mon, 16 Jan 2012 15:24:04 +0100 Subject: [PATCH] Edit debugger so win64interrupt is called when trying to debug a 64bit application under windows. Task-number: QTCREATORBUG-2521 Change-Id: I38922a6bed09640ce88184e6913a9fbb1d7433de Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com> Reviewed-by: hjk <qthjk@ovi.com> --- src/plugins/debugger/cdb/cdbengine.cpp | 2 +- src/plugins/debugger/procinterrupt.cpp | 32 +++++++++++++++++++++-- src/plugins/debugger/shared/hostutils.cpp | 18 +++++++++++-- src/plugins/debugger/shared/hostutils.h | 2 +- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 158ba8899ca..e624fe0ac04 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1182,7 +1182,7 @@ void CdbEngine::doInterruptInferior(SpecialStopMode sm) m_specialStopMode = sm; QString errorMessage; showMessage(QString::fromLatin1("Interrupting process %1...").arg(inferiorPid()), LogMisc); - if (!winDebugBreakProcess(inferiorPid(), &errorMessage)) { + if (!winDebugBreakProcess(inferiorPid(), &errorMessage, Utils::winIs64BitBinary(cdbBinary(startParameters())))) { m_specialStopMode = oldSpecialMode; showMessage(QString::fromLatin1("Cannot interrupt process %1: %2").arg(inferiorPid()).arg(errorMessage), LogError); } diff --git a/src/plugins/debugger/procinterrupt.cpp b/src/plugins/debugger/procinterrupt.cpp index 291d50d60da..cf5a49150db 100644 --- a/src/plugins/debugger/procinterrupt.cpp +++ b/src/plugins/debugger/procinterrupt.cpp @@ -33,6 +33,7 @@ #include "procinterrupt.h" #include <QtCore/QProcess> // makes kill visible on Windows. +#include <QtCore/QFile> using namespace Debugger::Internal; @@ -40,8 +41,27 @@ using namespace Debugger::Internal; #define _WIN32_WINNT 0x0501 /* WinXP, needed for DebugBreakProcess() */ +#include <utils/winutils.h> #include <windows.h> +static BOOL isWow64Process(HANDLE hproc) +{ + BOOL ret = false; + typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + LPFN_ISWOW64PROCESS fnIsWow64Process = NULL; + HMODULE hModule = GetModuleHandle(L"kernel32.dll"); + if (hModule == NULL) + return false; + + fnIsWow64Process = reinterpret_cast<LPFN_ISWOW64PROCESS>(GetProcAddress(hModule, "IsWow64Process")); + if (fnIsWow64Process == NULL) + return false; + + if (!fnIsWow64Process(hproc, &ret)) + return false; + return ret; +} + bool Debugger::Internal::interruptProcess(int pID) { if (pID <= 0) @@ -51,10 +71,18 @@ bool Debugger::Internal::interruptProcess(int pID) if (hproc == NULL) return false; - bool ok = DebugBreakProcess(hproc) != 0; + BOOL proc64bit = false; - CloseHandle(hproc); + if (Utils::winIs64BitSystem()) + proc64bit = !isWow64Process(hproc); + bool ok = false; + if (proc64bit) + ok = !QProcess::execute(QCoreApplication::applicationDirPath() + QString::fromLatin1("/win64interrupt.exe %1").arg(pID)); + else + ok = !DebugBreakProcess(hproc); + + CloseHandle(hproc); return ok; } diff --git a/src/plugins/debugger/shared/hostutils.cpp b/src/plugins/debugger/shared/hostutils.cpp index 671e94336da..7e67648eaba 100644 --- a/src/plugins/debugger/shared/hostutils.cpp +++ b/src/plugins/debugger/shared/hostutils.cpp @@ -146,7 +146,7 @@ bool winResumeThread(unsigned long dwThreadId, QString *errorMessage) } // Open the process and break into it -bool winDebugBreakProcess(unsigned long pid, QString *errorMessage) +bool winDebugBreakProcess(unsigned long pid, QString *errorMessage, bool isCdb64bit) { bool ok = false; HANDLE inferior = NULL; @@ -160,7 +160,21 @@ bool winDebugBreakProcess(unsigned long pid, QString *errorMessage) arg(pid).arg(Utils::winErrorMessage(GetLastError())); break; } - if (!DebugBreakProcess(inferior)) { + + if (isCdb64bit) { + switch (QProcess::execute(QCoreApplication::applicationDirPath() + QString::fromLatin1("/win64interrupt.exe %1").arg(pid))) { + case -2: + *errorMessage = QString::fromLatin1("Cannot start win64interrupt.exe. Check src/tools/win64interrupt/win64interrupt.c for more information."); + break; + case 0: + ok = true; + break; + default: + *errorMessage = QString::fromLatin1("win64interrupt.exe could not break the process with the pid %1.").arg(pid); + break; + } + break; + } else if (!DebugBreakProcess(inferior)) { *errorMessage = QString::fromLatin1("DebugBreakProcess failed: %1").arg(Utils::winErrorMessage(GetLastError())); break; } diff --git a/src/plugins/debugger/shared/hostutils.h b/src/plugins/debugger/shared/hostutils.h index 2e8e311feb9..4fa3036ea02 100644 --- a/src/plugins/debugger/shared/hostutils.h +++ b/src/plugins/debugger/shared/hostutils.h @@ -60,7 +60,7 @@ QList<ProcData> hostProcessList(); bool winResumeThread(unsigned long dwThreadId, QString *errorMessage); // Open a process by PID and break into it. -bool winDebugBreakProcess(unsigned long pid, QString *errorMessage); +bool winDebugBreakProcess(unsigned long pid, QString *errorMessage, bool isCdb64bit); unsigned long winGetCurrentProcessId(); -- GitLab