aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me+cygwin@cgf.cx>2009-03-22 21:27:30 +0000
committerChristopher Faylor <me+cygwin@cgf.cx>2009-03-22 21:27:30 +0000
commit2b008701dc388692b80774c1913c55d54be5c320 (patch)
tree34af7c3b0a555946cbded759bce2bacba46c47f5
parentbcd5727bdddbf3063b7a8714708a95863d811a9d (diff)
downloadgdb-2b008701dc388692b80774c1913c55d54be5c320.zip
gdb-2b008701dc388692b80774c1913c55d54be5c320.tar.gz
gdb-2b008701dc388692b80774c1913c55d54be5c320.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog33
-rw-r--r--gdb/windows-nat.c248
2 files changed, 173 insertions, 108 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a323589..686a149 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,36 @@
+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.
+
2009-03-22 Pedro Alves <pedro@codesourcery.com>
* mi/mi-interp.c (mi_interpreter_init): Attach mi_about_to_proceed
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 2ab1709..e80c4c5 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -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,
@@ -366,7 +388,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
thread_info *th = current_thread;
th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
GetThreadContext (th->h, &th->context);
- /* Copy dr values from that thread.
+ /* Copy dr values from that thread.
But only if there were not modified since last stop. PR gdb/2388 */
if (!debug_registers_changed)
{
@@ -438,14 +460,6 @@ windows_store_inferior_registers (struct target_ops *ops,
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,15 +479,10 @@ get_module_name (LPVOID base_address, char *dll_name_ret)
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,
- sizeof (HMODULE), &cbNeeded) || !cbNeeded)
+ if (!EnumProcessModules (current_process_handle, DllHandle,
+ sizeof (HMODULE), &cbNeeded) || !cbNeeded)
goto failed;
/* Allocate correct amount of space for module list */
@@ -482,22 +491,22 @@ get_module_name (LPVOID base_address, char *dll_name_ret)
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],
- &mi, sizeof (mi)))
+ 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,
- DllHandle[i], pathbuf, MAX_PATH);
+ len = GetModuleFileNameExA (current_process_handle,
+ DllHandle[i], pathbuf, MAX_PATH);
if (len == 0)
error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
#ifdef __CYGWIN__
@@ -976,7 +985,7 @@ info_w32_command (char *args, int from_tty)
#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
printf_unfiltered ("gdb: Target exception %s at %p\n", x, \
- current_event.u.Exception.ExceptionRecord.ExceptionAddress)
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress)
static int
handle_exception (struct target_waitstatus *ourstatus)
@@ -1089,7 +1098,7 @@ handle_exception (struct target_waitstatus *ourstatus)
return -1;
printf_unfiltered ("gdb: unknown target exception 0x%08lx at %p\n",
current_event.u.Exception.ExceptionRecord.ExceptionCode,
- current_event.u.Exception.ExceptionRecord.ExceptionAddress);
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress);
ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
break;
}
@@ -1465,20 +1474,20 @@ windows_wait (struct target_ops *ops,
while (1)
{
int retval;
-
+
/* Ignore CTRL+C signals while waiting for a debug event.
- FIXME: brobecker/2008-05-20: When the user presses CTRL+C while
- the inferior is running, both the inferior and GDB receive the
- associated signal. If the inferior receives the signal first
- and the delay until GDB receives that signal is sufficiently long,
- GDB can sometimes receive the SIGINT after we have unblocked
- the CTRL+C handler. This would lead to the debugger to stop
- prematurely while handling the new-thread event that comes
- with the handling of the SIGINT inside the inferior, and then
- stop again immediately when the user tries to resume the execution
- in the inferior. This is a classic race, and it would be nice
- to find a better solution to that problem. But in the meantime,
- the current approach already greatly mitigate this issue. */
+ FIXME: brobecker/2008-05-20: When the user presses CTRL+C while
+ the inferior is running, both the inferior and GDB receive the
+ associated signal. If the inferior receives the signal first
+ and the delay until GDB receives that signal is sufficiently long,
+ GDB can sometimes receive the SIGINT after we have unblocked
+ the CTRL+C handler. This would lead to the debugger to stop
+ prematurely while handling the new-thread event that comes
+ with the handling of the SIGINT inside the inferior, and then
+ stop again immediately when the user tries to resume the execution
+ in the inferior. This is a classic race, and it would be nice
+ to find a better solution to that problem. But in the meantime,
+ the current approach already greatly mitigate this issue. */
SetConsoleCtrlHandler (NULL, TRUE);
retval = get_windows_debug_event (ops, pid, ourstatus);
SetConsoleCtrlHandler (NULL, FALSE);
@@ -1554,36 +1563,6 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
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.
@@ -1614,13 +1593,13 @@ set_process_privilege (const char *privilege, BOOL enable)
goto out;
if (!OpenProcessToken)
OpenProcessToken =
- (void *) GetProcAddress (advapi32, "OpenProcessToken");
+ (void *) GetProcAddress (advapi32, "OpenProcessToken");
if (!LookupPrivilegeValue)
LookupPrivilegeValue =
- (void *) GetProcAddress (advapi32, "LookupPrivilegeValueA");
+ (void *) GetProcAddress (advapi32, "LookupPrivilegeValueA");
if (!AdjustTokenPrivileges)
AdjustTokenPrivileges =
- (void *) GetProcAddress (advapi32, "AdjustTokenPrivileges");
+ (void *) GetProcAddress (advapi32, "AdjustTokenPrivileges");
if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
{
advapi32 = NULL;
@@ -1698,8 +1677,7 @@ windows_attach (struct target_ops *ops, char *args, int from_tty)
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, char *args, int from_tty)
{
int detached = 1;
- if (has_detach_ability ())
- {
- ptid_t ptid = {-1};
- windows_resume (ops, ptid, 0, TARGET_SIGNAL_0);
+ ptid_t ptid = {-1};
+ windows_resume (ops, ptid, 0, TARGET_SIGNAL_0);
- if (!kernel32_DebugActiveProcessStop (current_event.dwProcessId))
- {
- error (_("Can't detach process %lu (error %lu)"),
- current_event.dwProcessId, GetLastError ());
- detached = 0;
- }
- kernel32_DebugSetProcessKillOnExit (FALSE);
+ if (!DebugActiveProcessStop (current_event.dwProcessId))
+ {
+ error (_("Can't detach process %lu (error %lu)"),
+ current_event.dwProcessId, GetLastError ());
+ detached = 0;
}
+ DebugSetProcessKillOnExit (FALSE);
+
if (detached && from_tty)
{
char *exec_file = get_exec_file (0);
@@ -1994,18 +1970,18 @@ windows_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len,
{
DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
len, (DWORD) (uintptr_t) memaddr));
- if (!WriteProcessMemory (current_process_handle,
+ if (!WriteProcessMemory (current_process_handle,
(LPVOID) (uintptr_t) memaddr, our,
len, &done))
done = 0;
- FlushInstructionCache (current_process_handle,
+ FlushInstructionCache (current_process_handle,
(LPCVOID) (uintptr_t) memaddr, len);
}
else
{
DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
len, (DWORD) (uintptr_t) memaddr));
- if (!ReadProcessMemory (current_process_handle,
+ if (!ReadProcessMemory (current_process_handle,
(LPCVOID) (uintptr_t) memaddr, our,
len, &done))
done = 0;
@@ -2343,33 +2319,89 @@ _initialize_check_for_gdb_ini (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)
+{
+ return FALSE;
+}
+static BOOL WINAPI
+bad_DebugBreakProcess (HANDLE w)
+{
+ 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;
+}
+
+/* Load any functions which may not be available in ancient versions
+ of Windows. */
void
-_initialize_psapi (void)
+_initialize_loadable (void)
{
- /* Load optional functions used for retrieving filename information
- associated with the currently debugged process or its dlls. */
- if (!psapi_loaded)
+ HMODULE hm = NULL;
+
+ hm = LoadLibrary ("kernel32.dll");
+ if (hm)
{
- HMODULE psapi_module_handle;
+ dyn_DebugActiveProcessStop = (void *)
+ GetProcAddress (hm, "DebugActiveProcessStop");
+ dyn_DebugBreakProcess = (void *)
+ GetProcAddress (hm, "DebugBreakProcess");
+ dyn_DebugSetProcessKillOnExit = (void *)
+ GetProcAddress (hm, "DebugSetProcessKillOnExit");
+ }
- psapi_loaded = -1;
+ /* 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;
+ }
- psapi_module_handle = LoadLibrary ("psapi.dll");
- if (psapi_module_handle)
- {
- psapi_EnumProcessModules = (void *) GetProcAddress (psapi_module_handle, "EnumProcessModules");
- psapi_GetModuleInformation = (void *) GetProcAddress (psapi_module_handle, "GetModuleInformation");
- psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle, "GetModuleFileNameExA");
-
- if (psapi_EnumProcessModules != NULL
- && psapi_GetModuleInformation != NULL
- && psapi_GetModuleFileNameExA != NULL)
- psapi_loaded = 1;
- }
+ /* 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");
}
- /* 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."));
+ 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. */
+ warning(_("cannot automatically find executable file or library to read symbols. Use \"file\" or \"dll\" command to load executable/libraries directly."));
+ }
}