This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] change method for dynamically loading "new" windows functions
- From: Christopher Faylor <cgf-use-the-mailinglist-please at sourceware dot org>
- To: gdb-patches at sourceware dot org
- Date: Sun, 22 Mar 2009 17:53:22 -0400
- Subject: [patch] change method for dynamically loading "new" windows functions
- Index: ChangeLog
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."));
}
+}