[gimp/soc-2011-seamless-clone2] Bug 678925 - Debugging plugins with windows
- From: Clayton Walker <claytonw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/soc-2011-seamless-clone2] Bug 678925 - Debugging plugins with windows
- Date: Wed, 8 May 2013 15:01:44 +0000 (UTC)
commit d90ef094acdeb9ca3149a28a9ef797539adb3287
Author: Michael Natterer <mitch gimp org>
Date: Sat Feb 23 16:25:58 2013 +0100
Bug 678925 - Debugging plugins with windows
Apply patch from Hartmut Kuhse that enables plug-in debugging on
Windows by stopping the process using Windows API, and providing a
small executable "gimp-plugin-resume.exe" to resume the stopped
plug-in.
devel-docs/debug-plug-ins.txt | 9 +++-
libgimp/gimp.c | 43 ++++++++++++++++-
tools/Makefile.am | 12 +++++
tools/gimp-debug-resume.c | 110 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 172 insertions(+), 2 deletions(-)
---
diff --git a/devel-docs/debug-plug-ins.txt b/devel-docs/debug-plug-ins.txt
index f1c874b..3e8befa 100644
--- a/devel-docs/debug-plug-ins.txt
+++ b/devel-docs/debug-plug-ins.txt
@@ -46,7 +46,9 @@ The steps to debug a plug-in are as follows:
5. Set breakpoints where you want the plug-in to stop in the debugger
6. Send the CONT signal (kill -CONT <pid>) to the plug-in process
-
+ (When compiled with Windows, resume the plug-in process with
+ gimp-debug-resume.exe <pid>)
+
7. Enter "continue" in the debugger. The plug-in will then continue
and break at the breakpoints.
@@ -105,3 +107,8 @@ GIMP_PLUGIN_DEBUG_WRAPPER=debugger
debugger refers to the debugger program, such as valgrind. You can
put command line options here too, they will be parsed like they do
in the shell.
+
+When compiled with Windows, the plug-in process is halted by Windows functions.
+It must be resumed externally by invoking gimp-debug-resume.exe <pid>
+The plug-ins pid can be found out by invoking gimp-debug-resume.exe
+without parameters. It shows the pid of all running processes.
diff --git a/libgimp/gimp.c b/libgimp/gimp.c
index 0f6e386..5205780 100644
--- a/libgimp/gimp.c
+++ b/libgimp/gimp.c
@@ -90,6 +90,7 @@
# define STRICT
# define _WIN32_WINNT 0x0601
# include <windows.h>
+# include <tlhelp32.h>
# undef RGB
# define USE_WIN32_SHM 1
#endif
@@ -1649,10 +1650,50 @@ static void
gimp_debug_stop (void)
{
#ifndef G_OS_WIN32
+
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Waiting for debugger...");
raise (SIGSTOP);
+
#else
- g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Debugging not implemented on Win32");
+
+ HANDLE hThreadSnap = NULL;
+ THREADENTRY32 te32 = { 0 };
+ pid_t opid = getpid ();
+
+ g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Debugging (restart externally): %d",
+ opid);
+
+ hThreadSnap = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0);
+ if (hThreadSnap == INVALID_HANDLE_VALUE)
+ {
+ g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
+ "error getting threadsnap - debugging impossible");
+ return;
+ }
+
+ te32.dwSize = sizeof (THREADENTRY32);
+
+ if (Thread32First (hThreadSnap, &te32))
+ {
+ do
+ {
+ if (te32.th32OwnerProcessID == opid)
+ {
+ HANDLE hThread = OpenThread (THREAD_SUSPEND_RESUME, FALSE,
+ te32.th32ThreadID);
+ SuspendThread (hThread);
+ CloseHandle (hThread);
+ }
+ }
+ while (Thread32Next (hThreadSnap, &te32));
+ }
+ else
+ {
+ g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "error getting threads");
+ }
+
+ CloseHandle (hThreadSnap);
+
#endif
}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index e78621e..b2e595e 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -10,8 +10,20 @@ endif
SUBDIRS = $(D_pdbgen)
+if OS_WIN32
+
+bin_PROGRAMS = \
+ gimptool-2.0 \
+ gimp-debug-resume
+
+gimp_debug_resume_SOURCES = gimp-debug-resume.c
+
+else
+
bin_PROGRAMS = gimptool-2.0
+endif
+
noinst_PROGRAMS = test-clipboard
EXTRA_PROGRAMS = \
diff --git a/tools/gimp-debug-resume.c b/tools/gimp-debug-resume.c
new file mode 100644
index 0000000..57633bf
--- /dev/null
+++ b/tools/gimp-debug-resume.c
@@ -0,0 +1,110 @@
+/* based on pausep by Daniel Turini
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#define _WIN32_WINNT 0x0502
+#include <windows.h>
+#include <tchar.h>
+#include <tlhelp32.h>
+#include <stdio.h>
+
+static BOOL
+resume_process (DWORD dwOwnerPID)
+{
+ HANDLE hThreadSnap = NULL;
+ BOOL bRet = FALSE;
+ THREADENTRY32 te32 = { 0 };
+
+ hThreadSnap = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0);
+ if (hThreadSnap == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ te32.dwSize = sizeof (THREADENTRY32);
+
+ if (Thread32First (hThreadSnap, &te32))
+ {
+ do
+ {
+ if (te32.th32OwnerProcessID == dwOwnerPID)
+ {
+ HANDLE hThread = OpenThread (THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID);
+ printf ("Resuming Thread: %u\n",te32.th32ThreadID);
+ ResumeThread (hThread);
+ CloseHandle (hThread);
+ }
+ }
+ while (Thread32Next (hThreadSnap, &te32));
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ CloseHandle (hThreadSnap);
+
+ return bRet;
+}
+
+static BOOL
+process_list (void)
+{
+ HANDLE hProcessSnap = NULL;
+ BOOL bRet = FALSE;
+ PROCESSENTRY32 pe32 = {0};
+
+ hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
+
+ if (hProcessSnap == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ pe32.dwSize = sizeof (PROCESSENTRY32);
+
+ if (Process32First (hProcessSnap, &pe32))
+ {
+ do
+ {
+ printf ("PID:\t%u\t%s\n", pe32.th32ProcessID, pe32.szExeFile);
+ }
+ while (Process32Next (hProcessSnap, &pe32));
+ bRet = TRUE;
+ }
+ else
+ bRet = FALSE;
+
+ CloseHandle (hProcessSnap);
+
+ return bRet;
+}
+
+int
+main (int argc,
+ char* argv[])
+{
+ DWORD pid;
+
+ if (argc <= 1)
+ {
+ process_list ();
+ }
+ else if (argc == 2)
+ {
+ pid = atoi (argv[1]);
+ if (pid == 0)
+ {
+ printf ("invalid: %s\n", pid);
+ return 1;
+ }
+ else
+ {
+ printf ("process: %u\n", pid);
+ resume_process (pid);
+ }
+ }
+ else
+ {
+ printf ("Usage:\n"
+ "resume : show processlist\n"
+ "resume PID: resuming thread\n");
+ }
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]