This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] change method for dynamically loading "new" windows functions


2009-03-22  Christopher Faylor  <me+cygwin@cgf.cx>

	* windows-nat.c (DebugActiveProcessStop): Implement macro wraparound
	for dynamically loaded function.
	(DebugBreakProcess): Ditto.
	(DebugSetProcessKillOnExit): Ditto.
	(EnumProcessModules): Ditto.
	(GetModuleFileNameExA): Ditto.
	(GetModuleInformation): Ditto.
	(DebugActiveProcessStop): Rename and define placeholder for address of
	dynamically loaded function.  for dynamically loaded function.
	(DebugBreakProcess): Ditto.
	(DebugSetProcessKillOnExit): Ditto.
	(EnumProcessModules): Ditto.
	(GetModuleFileNameExA): Ditto.
	(GetModuleInformation): Ditto.
	(psapi_loaded): Delete.
	(get_module_name): Don't check psapi_loaded, just rely on the fact that
	dynamically loaded functions will return failure if they weren't
	previously found.
	(has_detach_ability): Delete.
	(windows_attach): Remove call to has_detach_ability ().  Just rely on
	functions being callable.
	(bad_DebugActiveProcessStop): Define.
	(bad_DebugBreakProcess): Ditto.
	(bad_DebugSetProcessKillOnExit): Ditto.
	(bad_EnumProcessModules): Ditto.
	(bad_GetModuleFileNameExA): Ditto.
	(bad_GetModuleInformation): Ditto.
	(_initialize_loadable): Rename from _initialize_psapi.  Initialize all
	dynamic storage here, setting nonexistent functions to dummy static
	functions which always return error.

Index: windows-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/windows-nat.c,v
retrieving revision 1.184
retrieving revision 1.185
diff -u -p -w -r1.184 -r1.185
--- windows-nat.c	17 Mar 2009 19:28:09 -0000	1.184
+++ windows-nat.c	22 Mar 2009 21:27:30 -0000	1.185
@@ -38,6 +38,7 @@
 #include <stdlib.h>
 #include <windows.h>
 #include <imagehlp.h>
+#include <psapi.h>
 #ifdef __CYGWIN__
 #include <sys/cygwin.h>
 #endif
@@ -63,6 +64,28 @@
 #include "windows-tdep.h"
 #include "windows-nat.h"
 
+#define DebugActiveProcessStop		dyn_DebugActiveProcessStop
+#define DebugBreakProcess		dyn_DebugBreakProcess
+#define DebugSetProcessKillOnExit	dyn_DebugSetProcessKillOnExit
+#define EnumProcessModules		dyn_EnumProcessModules
+#define GetModuleFileNameExA		dyn_GetModuleFileNameExA
+#define GetModuleInformation		dyn_GetModuleInformation
+
+/* Since Windows XP, detaching from a process is supported by Windows.
+   The following code tries loading the appropriate functions dynamically.
+   If loading these functions succeeds use them to actually detach from
+   the inferior process, otherwise behave as usual, pretending that
+   detach has worked. */
+static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
+static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
+static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
+static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
+					  LPDWORD);
+static DWORD WINAPI (*GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR,
+					    DWORD);
+static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
+					    DWORD);
+
 static struct target_ops windows_ops;
 
 #ifdef __CYGWIN__
@@ -84,7 +107,6 @@ enum
     CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
   };
 #endif
-#include <psapi.h>
 
 #ifndef CONTEXT_EXTENDED_REGISTERS
 /* This macro is only defined on ia32.  It only makes sense on this target,
@@ -438,14 +460,6 @@ windows_store_inferior_registers (struct
     do_windows_store_inferior_registers (regcache, r);
 }
 
-static int psapi_loaded = 0;
-static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD,
-						LPDWORD);
-static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
-						  DWORD);
-static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR,
-						   DWORD);
-
 /* Get the name of a given module at at given base address.  If base_address
    is zero return the first loaded module (which is always the name of the
    executable).  */
@@ -465,14 +479,9 @@ get_module_name (LPVOID base_address, ch
   char *pathbuf = dll_name_ret;	/* Just copy directly to passed-in arg */
 #endif
 
-  /* If psapi_loaded < 0 either psapi.dll is not available or it does not contain
-     the needed functions. */
-  if (psapi_loaded <= 0)
-    goto failed;
-
   cbNeeded = 0;
   /* Find size of buffer needed to handle list of modules loaded in inferior */
-  if (!psapi_EnumProcessModules (current_process_handle, DllHandle,
+  if (!EnumProcessModules (current_process_handle, DllHandle,
 				 sizeof (HMODULE), &cbNeeded) || !cbNeeded)
     goto failed;
 
@@ -482,21 +491,21 @@ get_module_name (LPVOID base_address, ch
     goto failed;
 
   /* Get the list of modules */
-  if (!psapi_EnumProcessModules (current_process_handle, DllHandle, cbNeeded,
+  if (!EnumProcessModules (current_process_handle, DllHandle, cbNeeded,
 				 &cbNeeded))
     goto failed;
 
   for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
     {
       /* Get information on this module */
-      if (!psapi_GetModuleInformation (current_process_handle, DllHandle[i],
+      if (!GetModuleInformation (current_process_handle, DllHandle[i],
 				       &mi, sizeof (mi)))
 	error (_("Can't get module info"));
 
       if (!base_address || mi.lpBaseOfDll == base_address)
 	{
 	  /* Try to find the name of the given module */
-	  len = psapi_GetModuleFileNameExA (current_process_handle,
+	  len = GetModuleFileNameExA (current_process_handle,
 					    DllHandle[i], pathbuf, MAX_PATH);
 	  if (len == 0)
 	    error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
@@ -1554,36 +1563,6 @@ do_initial_windows_stuff (struct target_
   return;
 }
 
-/* Since Windows XP, detaching from a process is supported by Windows.
-   The following code tries loading the appropriate functions dynamically.
-   If loading these functions succeeds use them to actually detach from
-   the inferior process, otherwise behave as usual, pretending that
-   detach has worked. */
-static BOOL WINAPI (*kernel32_DebugSetProcessKillOnExit)(BOOL);
-static BOOL WINAPI (*kernel32_DebugActiveProcessStop)(DWORD);
-
-static int
-has_detach_ability (void)
-{
-  static HMODULE kernel32 = NULL;
-
-  if (!kernel32)
-    kernel32 = LoadLibrary ("kernel32.dll");
-  if (kernel32)
-    {
-      if (!kernel32_DebugSetProcessKillOnExit)
-	kernel32_DebugSetProcessKillOnExit =
-	  (void *) GetProcAddress (kernel32, "DebugSetProcessKillOnExit");
-      if (!kernel32_DebugActiveProcessStop)
-	kernel32_DebugActiveProcessStop =
-	  (void *) GetProcAddress (kernel32, "DebugActiveProcessStop");
-      if (kernel32_DebugSetProcessKillOnExit
-	  && kernel32_DebugActiveProcessStop)
-	return 1;
-    }
-  return 0;
-}
-
 /* Try to set or remove a user privilege to the current process.  Return -1
    if that fails, the previous setting of that privilege otherwise.
 
@@ -1698,8 +1677,7 @@ windows_attach (struct target_ops *ops, 
   if (!ok)
     error (_("Can't attach to process."));
 
-  if (has_detach_ability ())
-    kernel32_DebugSetProcessKillOnExit (FALSE);
+  DebugSetProcessKillOnExit (FALSE);
 
   if (from_tty)
     {
@@ -1724,19 +1702,17 @@ windows_detach (struct target_ops *ops, 
 {
   int detached = 1;
 
-  if (has_detach_ability ())
-    {
       ptid_t ptid = {-1};
       windows_resume (ops, ptid, 0, TARGET_SIGNAL_0);
 
-      if (!kernel32_DebugActiveProcessStop (current_event.dwProcessId))
+  if (!DebugActiveProcessStop (current_event.dwProcessId))
 	{
 	  error (_("Can't detach process %lu (error %lu)"),
 		 current_event.dwProcessId, GetLastError ());
 	  detached = 0;
 	}
-      kernel32_DebugSetProcessKillOnExit (FALSE);
-    }
+  DebugSetProcessKillOnExit (FALSE);
+
   if (detached && from_tty)
     {
       char *exec_file = get_exec_file (0);
@@ -2343,33 +2319,89 @@ _initialize_check_for_gdb_ini (void)
     }
 }
 
-void
-_initialize_psapi (void)
+/* Define dummy functions which always return error for the rare cases where
+   these functions could not be found. */
+static BOOL WINAPI
+bad_DebugActiveProcessStop (DWORD w)
 {
-  /* Load optional functions used for retrieving filename information
-     associated with the currently debugged process or its dlls. */
-  if (!psapi_loaded)
+  return FALSE;
+}
+static BOOL WINAPI
+bad_DebugBreakProcess (HANDLE w)
     {
-      HMODULE psapi_module_handle;
-
-      psapi_loaded = -1;
+  return FALSE;
+}
+static BOOL WINAPI
+bad_DebugSetProcessKillOnExit (BOOL w)
+{
+  return FALSE;
+}
+static BOOL WINAPI
+bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
+{
+  return FALSE;
+}
+static DWORD WINAPI
+bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
+{
+  return 0;
+}
+static BOOL WINAPI
+bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
+{
+  return FALSE;
+}
 
-      psapi_module_handle = LoadLibrary ("psapi.dll");
-      if (psapi_module_handle)
+/* Load any functions which may not be available in ancient versions
+   of Windows. */
+void
+_initialize_loadable (void)
 	{
-	  psapi_EnumProcessModules = (void *) GetProcAddress (psapi_module_handle, "EnumProcessModules");
-	  psapi_GetModuleInformation = (void *) GetProcAddress (psapi_module_handle, "GetModuleInformation");
-	  psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle, "GetModuleFileNameExA");
+  HMODULE hm = NULL;
 
-	  if (psapi_EnumProcessModules != NULL
-	      && psapi_GetModuleInformation != NULL
-	      && psapi_GetModuleFileNameExA != NULL)
-	    psapi_loaded = 1;
+  hm = LoadLibrary ("kernel32.dll");
+  if (hm)
+    {
+      dyn_DebugActiveProcessStop = (void *)
+	GetProcAddress (hm, "DebugActiveProcessStop");
+      dyn_DebugBreakProcess = (void *)
+	GetProcAddress (hm, "DebugBreakProcess");
+      dyn_DebugSetProcessKillOnExit = (void *)
+	GetProcAddress (hm, "DebugSetProcessKillOnExit");
 	}
+
+  /* Set variables to dummy versions of these processes if the function
+     wasn't found in kernel32.dll. */
+  if (!dyn_DebugBreakProcess)
+    dyn_DebugBreakProcess = bad_DebugBreakProcess;
+  if (!dyn_DebugActiveProcessStop || !dyn_DebugSetProcessKillOnExit)
+    {
+      dyn_DebugActiveProcessStop = bad_DebugActiveProcessStop;
+      dyn_DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit;
     }
 
+  /* Load optional functions used for retrieving filename information
+     associated with the currently debugged process or its dlls. */
+  hm = LoadLibrary ("psapi.dll");
+  if (hm)
+    {
+      dyn_EnumProcessModules = (void *)
+	GetProcAddress (hm, "EnumProcessModules");
+      dyn_GetModuleInformation = (void *)
+	GetProcAddress (hm, "GetModuleInformation");
+      dyn_GetModuleFileNameExA = (void *)
+	GetProcAddress (hm, "GetModuleFileNameExA");
+    }
+
+  if (!dyn_EnumProcessModules || !dyn_GetModuleInformation || !dyn_GetModuleFileNameExA)
+    {
+      /* Set variables to dummy versions of these processes if the function
+	 wasn't found in psapi.dll. */
+      dyn_EnumProcessModules = bad_EnumProcessModules;
+      dyn_GetModuleInformation = bad_GetModuleInformation;
+      dyn_GetModuleFileNameExA = bad_GetModuleFileNameExA;
   /* This will probably fail on Windows 9x/Me.  Let the user know that we're
      missing some functionality. */
-  if (psapi_loaded < 0)
     warning(_("cannot automatically find executable file or library to read symbols.  Use \"file\" or \"dll\" command to load executable/libraries directly."));
 }
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]