summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@digia.com>2013-06-10 15:45:00 +0200
committerDavid Schulz <david.schulz@digia.com>2013-06-17 11:20:42 +0200
commit2bc24b7a25ba7faf523166bbb75e36a9e7528124 (patch)
treeb39a285d63b2e1cfd50230520b5da3a715a7f57e
parent94dd4e740a3b6acf28cd3df4015af6f612aae6d5 (diff)
downloadqt-creator-2bc24b7a25ba7faf523166bbb75e36a9e7528124.tar.gz
Debugger: Fix interrupting 32bit process from a 64bit creator...
... on windows. Change-Id: I93f5299ab7f90ed64a6369176107d7596f3b36e4 Reviewed-by: hjk <hjk121@nokiamail.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
-rw-r--r--src/plugins/debugger/procinterrupt.cpp93
-rw-r--r--src/tools/tools.pro11
-rw-r--r--src/tools/wininterrupt/wininterrupt.c (renamed from src/tools/win64interrupt/win64interrupt.c)0
-rw-r--r--src/tools/wininterrupt/wininterrupt.pro (renamed from src/tools/win64interrupt/win64interrupt.pro)12
4 files changed, 69 insertions, 47 deletions
diff --git a/src/plugins/debugger/procinterrupt.cpp b/src/plugins/debugger/procinterrupt.cpp
index 0ad32373af..178f6a823e 100644
--- a/src/plugins/debugger/procinterrupt.cpp
+++ b/src/plugins/debugger/procinterrupt.cpp
@@ -93,51 +93,70 @@ bool Debugger::Internal::interruptProcess(int pID, int engineType, QString *erro
arg(pID).arg(Utils::winErrorMessage(GetLastError()));
break;
}
- // Try DebugBreakProcess if either Qt Creator is compiled 64 bit or
- // both Qt Creator and application are 32 bit.
-#ifdef Q_OS_WIN64
- // Qt-Creator compiled 64 bit
- // Windows must be 64 bit
- // CDB 64 bit: use DebugBreakProcess for 32 an 64 bit processes.
- // TODO: CDB 32 bit: inferior 32 bit can not use DebugBreakProcess, we need a win32interrupt.exe
- // GDB: not supported
- const bool useDebugBreakApi= true;
- Q_UNUSED(engineExecutableIs64Bit)
- Q_UNUSED(engineType)
+ enum DebugBreakApi {
+ UseDebugBreakApi,
+ UseWin64Interrupt,
+ UseWin32Interrupt
+ };
+/*
+ Windows 64 bit has a 32 bit subsystem (WOW64) which makes it possible to run a
+ 32 bit application inside a 64 bit environment.
+ When GDB is used DebugBreakProcess must be called from the same system (32/64 bit) running
+ the inferior. If CDB is used we could in theory break wow64 processes,
+ but the break is actually a wow64 breakpoint. CDB is configured to ignore these
+ breakpoints, because they also appear on module loading.
+ Therefore we need helper executables (win(32/64)interrupt.exe) on Windows 64 bit calling
+ DebugBreakProcess from the correct system.
+
+ DebugBreak matrix for windows
+
+ Api = UseDebugBreakApi
+ Win64 = UseWin64Interrupt
+ Win32 = UseWin32Interrupt
+ N/A = This configuration is not possible
+
+ | Windows 32bit | Windows 64bit
+ | QtCreator 32bit | QtCreator 32bit | QtCreator 64bit
+ | Inferior 32bit | Inferior 32bit | Inferior 64bit | Inferior 32bit | Inferior 64bit |
+----------|-----------------|-----------------|-----------------|-----------------|----------------|
+CDB 32bit | Api | Api | NA | Win32 | NA |
+ 64bit | NA | Win64 | Win64 | Api | Api |
+----------|-----------------|-----------------|-----------------|-----------------|----------------|
+GDB 32bit | Api | Api | NA | Win32 | NA |
+ 64bit | NA | Api | Win64 | Win32 | Api |
+----------|-----------------|-----------------|-----------------|-----------------|----------------|
+
+*/
+
+ DebugBreakApi breakApi = UseDebugBreakApi;
+#ifdef Q_OS_WIN64
+ if ((engineType == GdbEngineType && isWow64Process(inferior))
+ || (engineType == CdbEngineType && !engineExecutableIs64Bit)) {
+ breakApi = UseWin32Interrupt;
+ }
#else
- // Qt-Creator compiled 32 bit:
-
- bool useDebugBreakApi;
- if (isWow64Process(GetCurrentProcess())) {
- // Windows is 64 bit
- if (engineType == CdbEngineType) {
- // CDB 64 bit: If Qt-Creator is a WOW64 process (meaning a 32bit process
- // running in emulation), always use win64interrupt.exe for native
- // 64 bit processes and WOW64 processes. While DebugBreakProcess()
- // works in theory for other WOW64 processes, the break appears
- // as a WOW64 breakpoint, which CDB is configured to ignore since
- // it also triggers on module loading.
- // CDB 32 bit: 32 bit applications can not be interrupted using the win64interrupt.exe
- // So we need to find out which bitness the currently used cdb has.
- useDebugBreakApi = !engineExecutableIs64Bit;
- } else {
- // GDB: Use win64interrupt for native 64bit processes only (it fails
- // for WOW64 processes.
- useDebugBreakApi = isWow64Process(inferior);
- }
- } else {
- // Windows is 32 bit
- // All processes are 32 bit, so DebugBreakProcess can be used in all cases.
- useDebugBreakApi = true;
+ if (isWow64Process(GetCurrentProcess())
+ && ((engineType == CdbEngineType && engineExecutableIs64Bit)
+ || (engineType == GdbEngineType && !isWow64Process(inferior)))) {
+ breakApi = UseWin64Interrupt;
}
#endif
- if (useDebugBreakApi) {
+ if (breakApi == UseDebugBreakApi) {
ok = DebugBreakProcess(inferior);
if (!ok)
*errorMessage = QLatin1String("DebugBreakProcess failed: ") + Utils::winErrorMessage(GetLastError());
} else {
- const QString executable = QCoreApplication::applicationDirPath() + QLatin1String("/win64interrupt.exe");
+ const QString executable = breakApi == UseWin32Interrupt
+ ? QCoreApplication::applicationDirPath() + QLatin1String("/win32interrupt.exe")
+ : QCoreApplication::applicationDirPath() + QLatin1String("/win64interrupt.exe");
+ if (!QFile::exists(executable)) {
+ *errorMessage = QString::fromLatin1("%1 does not exist. If you have built QtCreator "
+ "on your own ,checkout "
+ "http://qt.gitorious.org/qt-creator/binary-artifacts.").
+ arg(QDir::toNativeSeparators(executable));
+ break;
+ }
switch (QProcess::execute(executable, QStringList(QString::number(pID)))) {
case -2:
*errorMessage = QString::fromLatin1("Cannot start %1. Check src\\tools\\win64interrupt\\win64interrupt.c for more information.").
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
index 240a42ee3f..ce4530ca8c 100644
--- a/src/tools/tools.pro
+++ b/src/tools/tools.pro
@@ -7,14 +7,7 @@ SUBDIRS = qtpromaker \
win32 {
SUBDIRS += qtcdebugger
- # win64interrupt only make sense for 64bit builds
- ENV_CPU=$$(CPU)
- ENV_LIBPATH=$$(LIBPATH)
- contains(ENV_CPU, ^AMD64$) {
- SUBDIRS += win64interrupt
- } else:isEmpty(ENV_CPU):contains(ENV_LIBPATH, ^.*amd64.*$) {
- SUBDIRS += win64interrupt
- }
+ SUBDIRS += wininterrupt
} else {
SUBDIRS += valgrindfake
}
@@ -36,4 +29,4 @@ greaterThan(QT_MAJOR_VERSION, 4) {
} else {
SUBDIRS += qml2puppet
}
-} \ No newline at end of file
+}
diff --git a/src/tools/win64interrupt/win64interrupt.c b/src/tools/wininterrupt/wininterrupt.c
index f2327f8a1c..f2327f8a1c 100644
--- a/src/tools/win64interrupt/win64interrupt.c
+++ b/src/tools/wininterrupt/wininterrupt.c
diff --git a/src/tools/win64interrupt/win64interrupt.pro b/src/tools/wininterrupt/wininterrupt.pro
index 282514c54c..b306db179f 100644
--- a/src/tools/win64interrupt/win64interrupt.pro
+++ b/src/tools/wininterrupt/wininterrupt.pro
@@ -16,7 +16,7 @@ win32-msvc* {
QMAKE_CXXFLAGS += -static
}
-SOURCES = win64interrupt.c
+SOURCES = wininterrupt.c
TEMPLATE = app
DESTDIR = $$IDE_LIBEXEC_PATH
@@ -26,5 +26,15 @@ build_all:!build_pass {
CONFIG += release
}
+ENV_CPU=$$(CPU)
+ENV_LIBPATH=$$(LIBPATH)
+contains(ENV_CPU, ^AMD64$) {
+ TARGET = win64interrupt
+} else:isEmpty(ENV_CPU):contains(ENV_LIBPATH, ^.*amd64.*$) {
+ TARGET = win64interrupt
+} else {
+ TARGET = win32interrupt
+}
+
target.path = $$QTC_PREFIX/bin # FIXME: libexec, more or less
INSTALLS += target