View Issue Details

IDProjectCategoryView StatusLast Update
0001965GNUnetWin32 port (deprecated)public2011-12-26 22:30
ReporterLRN Assigned ToLRN  
PriorityhighSeverityfeatureReproducibilityN/A
Status closedResolutionfixed 
Product VersionGit master 
Target Version0.9.1Fixed in Version0.9.1 
Summary0001965: Vectored exception handling for W32
Descriptionsubj is attached. Whenever an exception occurs, and the process is not being debugged, it will run a debugger specified by GNUNET_DEBUGGER environment variable, and wait for it to attach.
The net effect is the same as using JIT debugging (AeDebug), but without the stack being broken by SEH (because VEH has a priority over SEH), which allows for fuller backtraces for any exception, not just for GNUNET_abort() calls.

Run the testsuite with something like GNUNET_DEBUGGER="gdb-python27.exe --pid=%u --event=%u -ex \"c\"" - and see for yourself.
TagsNo tags attached.
Attached Files
0001-Add-W32-VEH-ifdef.patch (3,483 bytes)   
From 430dba3398d71027e9ba83faf3b7ce0ba70bda03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1?=
 =?UTF-8?q?=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= <lrn1986@gmail.com>
Date: Sat, 26 Nov 2011 14:15:01 +0400
Subject: [PATCH] Add W32 VEH

---
 src/util/winproc.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/src/util/winproc.c b/src/util/winproc.c
index b524531..52a4e24 100644
--- a/src/util/winproc.c
+++ b/src/util/winproc.c
@@ -32,6 +32,9 @@
 #ifdef MINGW
 
 static HINSTANCE hNTDLL, hIphlpapi, hAdvapi, hNetapi;
+#ifdef W32_VEH
+static void *GNWinVEH_handle = NULL;
+#endif
 
 TNtQuerySystemInformation GNNtQuerySystemInformation;
 TGetIfEntry GNGetIfEntry;
@@ -77,6 +80,60 @@ plibc_panic (int err, char *msg)
        "%s", msg);
 }
 
+#ifdef W32_VEH
+/**
+ * Handles exceptions (useful for debugging).
+ * Issues a DebugBreak() call if the process is being debugged (not really
+ * useful - if the process is being debugged, this handler won't be invoked
+ * anyway). If it is not, runs a debugger from GNUNET_DEBUGGER env var,
+ * substituting first %u in it for PID, and the second one for the event,
+ * that should be set once the debugger attaches itself (otherwise the
+ * only way out of WaitForSingleObject() is to time out after 1 minute).
+ */
+LONG __stdcall
+GNWinVEH (PEXCEPTION_POINTERS ExceptionInfo)
+{
+  char debugger[MAX_PATH + 1];
+  char *debugger_env = NULL;
+  if (IsDebuggerPresent ())
+  {
+    DebugBreak ();
+    return EXCEPTION_CONTINUE_EXECUTION;
+  }
+  debugger_env = getenv ("GNUNET_DEBUGGER");
+  if (debugger_env != NULL)
+  {
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    HANDLE event;
+    SECURITY_ATTRIBUTES sa;
+    memset (&si, 0, sizeof (si));
+    si.cb = sizeof (si);
+    memset (&pi, 0, sizeof (pi));
+    memset (&sa, 0, sizeof (sa));
+    sa.nLength = sizeof (sa);
+    sa.bInheritHandle = TRUE;
+    event = CreateEvent (&sa, FALSE, FALSE, NULL);
+    snprintf (debugger, MAX_PATH + 1, debugger_env, GetCurrentProcessId (), (uintptr_t) event);
+    debugger[MAX_PATH] = '\0';
+    if (0 != CreateProcessA (NULL, debugger, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
+    {
+      CloseHandle (pi.hProcess);
+      CloseHandle (pi.hThread);
+      WaitForSingleObject (event, 60000);
+      CloseHandle (event);
+      if (IsDebuggerPresent ())
+      {
+        return EXCEPTION_CONTINUE_EXECUTION;
+      }
+    }
+    else
+      CloseHandle (event);
+  }
+  return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
 /**
  * @brief Initialize PlibC and set up Windows environment
  * @param logging context, NULL means stderr
@@ -95,6 +152,18 @@ GNInitWinEnv ()
   if (hNTDLL)
     return ret;
 
+#ifdef W32_VEH
+  if (GNWinVEH_handle == NULL)
+  {
+    GNWinVEH_handle = AddVectoredExceptionHandler (1, &GNWinVEH);
+    if (GNWinVEH_handle == NULL)
+    {
+      /* This is bad, but what can we do? */
+      printf ("Failed to set up an exception handler!\n");
+    }
+  }
+#endif
+
   hNTDLL = LoadLibrary ("ntdll.dll");
 
   /* Function to get CPU usage under Win NT */
@@ -242,6 +311,14 @@ GNShutdownWinEnv ()
 {
   plibc_shutdown ();
 
+#ifdef W32_VEH
+  if (GNWinVEH_handle != NULL)
+  {
+    RemoveVectoredExceptionHandler (GNWinVEH_handle);
+    GNWinVEH_handle = NULL;
+  }
+#endif
+
   FreeLibrary (hNTDLL);
   FreeLibrary (hIphlpapi);
   FreeLibrary (hAdvapi);
-- 
1.7.4

0001-Add-W32-VEH-ifdef.patch (3,483 bytes)   

Activities

LRN

2011-12-01 08:28

developer   ~0005003

Replaced the patch with a version that uses #ifdef instead of #if
#if is very good for complex macro systems, where macros are initialized by configure, and you can rely on a macro to be 0 or non-0. For macros that are specified simply as -DBLAH=1 in CPPFLAGS, it's better to use #ifdef, because normally the macro in question is not defined at all.
That is, unless someone adds a configure option that adds either -DW32_VEH=0 or -DW32_VEH=1 . I don't see the need for that, personally.

Christian Grothoff

2011-12-01 10:18

manager   ~0005004

Patch applied as SVN 18412.

Issue History

Date Modified Username Field Change
2011-11-26 11:19 LRN New Issue
2011-11-26 11:19 LRN Status new => assigned
2011-11-26 11:19 LRN Assigned To => NDurner
2011-11-26 11:19 LRN File Added: 0001-Add-W32-VEH.patch
2011-11-26 11:52 NDurner Status assigned => acknowledged
2011-12-01 08:25 LRN File Added: 0001-Add-W32-VEH-ifdef.patch
2011-12-01 08:26 LRN File Deleted: 0001-Add-W32-VEH.patch
2011-12-01 08:28 LRN Note Added: 0005003
2011-12-01 10:15 Christian Grothoff Priority normal => high
2011-12-01 10:15 Christian Grothoff Target Version => 0.9.1
2011-12-01 10:18 Christian Grothoff Note Added: 0005004
2011-12-01 10:18 Christian Grothoff Status acknowledged => resolved
2011-12-01 10:18 Christian Grothoff Fixed in Version => 0.9.1
2011-12-01 10:18 Christian Grothoff Resolution open => fixed
2011-12-01 10:18 Christian Grothoff Assigned To NDurner => LRN
2011-12-26 22:30 Christian Grothoff Status resolved => closed
2024-01-12 14:28 schanzen Category Win32 port => Win32 port (deprecated)