Index: gdb/windows-nat.c |
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c |
index f16588adfdac6e335d48895c8dc3d7935b5b51f2..f0545fcc967f94a1ddf90917a82bf842a836b3c1 100644 |
--- a/gdb/windows-nat.c |
+++ b/gdb/windows-nat.c |
@@ -1,6 +1,6 @@ |
/* Target-vector operations for controlling windows child processes, for GDB. |
- Copyright (C) 1995-2012 Free Software Foundation, Inc. |
+ Copyright (C) 1995-2013 Free Software Foundation, Inc. |
Contributed by Cygnus Solutions, A Red Hat Company. |
@@ -49,11 +49,11 @@ |
#include "filenames.h" |
#include "symfile.h" |
#include "objfiles.h" |
+#include "gdb_bfd.h" |
#include "gdb_obstack.h" |
-#include "gdb_string.h" |
+#include <string.h> |
#include "gdbthread.h" |
#include "gdbcmd.h" |
-#include <sys/param.h> |
#include <unistd.h> |
#include "exec.h" |
#include "solist.h" |
@@ -288,8 +288,8 @@ static void |
check (BOOL ok, const char *file, int line) |
{ |
if (!ok) |
- printf_filtered ("error return %s:%d was %lu\n", file, line, |
- GetLastError ()); |
+ printf_filtered ("error return %s:%d was %u\n", file, line, |
+ (unsigned) GetLastError ()); |
} |
/* Find a thread record given a thread id. If GET_CONTEXT is not 0, |
@@ -310,8 +310,10 @@ thread_rec (DWORD id, int get_context) |
if (SuspendThread (th->h) == (DWORD) -1) |
{ |
DWORD err = GetLastError (); |
- warning (_("SuspendThread failed. (winerr %d)"), |
- (int) err); |
+ |
+ warning (_("SuspendThread (tid=0x%x) failed." |
+ " (winerr %u)"), |
+ (unsigned) id, (unsigned) err); |
return NULL; |
} |
th->suspended = 1; |
@@ -385,7 +387,7 @@ windows_init_thread_list (void) |
/* Delete a thread from the list of threads. */ |
static void |
-windows_delete_thread (ptid_t ptid) |
+windows_delete_thread (ptid_t ptid, DWORD exit_code) |
{ |
thread_info *th; |
DWORD id; |
@@ -396,6 +398,9 @@ windows_delete_thread (ptid_t ptid) |
if (info_verbose) |
printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid)); |
+ else if (print_thread_events && id != main_thread_id) |
+ printf_unfiltered (_("[%s exited with code %u]\n"), |
+ target_pid_to_str (ptid), (unsigned) exit_code); |
delete_thread (ptid); |
for (th = &thread_head; |
@@ -575,7 +580,8 @@ get_module_name (LPVOID base_address, char *dll_name_ret) |
len = GetModuleFileNameEx (current_process_handle, |
DllHandle[i], pathbuf, __PMAX); |
if (len == 0) |
- error (_("Error getting dll name: %lu."), GetLastError ()); |
+ error (_("Error getting dll name: %u."), |
+ (unsigned) GetLastError ()); |
if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, dll_name_ret, |
__PMAX) < 0) |
error (_("Error converting dll name to POSIX: %d."), errno); |
@@ -752,7 +758,7 @@ windows_make_so (const char *name, LPVOID load_addr) |
asection *text = NULL; |
CORE_ADDR text_vma; |
- abfd = bfd_openr (so->so_name, "pei-i386"); |
+ abfd = gdb_bfd_open (so->so_name, "pei-i386", -1); |
if (!abfd) |
return so; |
@@ -762,7 +768,7 @@ windows_make_so (const char *name, LPVOID load_addr) |
if (!text) |
{ |
- bfd_close (abfd); |
+ gdb_bfd_unref (abfd); |
return so; |
} |
@@ -773,7 +779,7 @@ windows_make_so (const char *name, LPVOID load_addr) |
load_addr + 0x1000); |
cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text); |
- bfd_close (abfd); |
+ gdb_bfd_unref (abfd); |
} |
#endif |
@@ -841,11 +847,31 @@ handle_load_dll (void *dummy) |
dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; |
+ /* Try getting the DLL name by searching the list of known modules |
+ and matching their base address against this new DLL's base address. |
+ |
+ FIXME: brobecker/2013-12-10: |
+ It seems odd to be going through this search if the DLL name could |
+ simply be extracted via "event->lpImageName". Moreover, some |
+ experimentation with various versions of Windows seem to indicate |
+ that it might still be too early for this DLL to be listed when |
+ querying the system about the current list of modules, thus making |
+ this attempt pointless. |
+ |
+ This code can therefore probably be removed. But at the time of |
+ this writing, we are too close to creating the GDB 7.7 branch |
+ for us to make such a change. We are therefore defering it. */ |
+ |
if (!get_module_name (event->lpBaseOfDll, dll_buf)) |
dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; |
dll_name = dll_buf; |
+ /* Try getting the DLL name via the lpImageName field of the event. |
+ Note that Microsoft documents this fields as strictly optional, |
+ in the sense that it might be NULL. And the first DLL event in |
+ particular is explicitly documented as "likely not pass[ed]" |
+ (source: MSDN LOAD_DLL_DEBUG_INFO structure). */ |
if (*dll_name == '\0') |
dll_name = get_image_name (current_process_handle, |
event->lpImageName, event->fUnicode); |
@@ -879,13 +905,13 @@ handle_unload_dll (void *dummy) |
if (so->next->lm_info->load_addr == lpBaseOfDll) |
{ |
struct so_list *sodel = so->next; |
+ |
so->next = sodel->next; |
if (!so->next) |
solib_end = so; |
DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name)); |
windows_free_so (sodel); |
- solib_add (NULL, 0, NULL, auto_solib_add); |
return 1; |
} |
@@ -967,16 +993,18 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) |
char *p; |
int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0); |
int gotasig = gdb_signal_from_host (sig); |
+ |
ourstatus->value.sig = gotasig; |
if (gotasig) |
{ |
LPCVOID x; |
- DWORD n; |
+ SIZE_T n; |
+ |
ourstatus->kind = TARGET_WAITKIND_STOPPED; |
retval = strtoul (p, &p, 0); |
if (!retval) |
retval = main_thread_id; |
- else if ((x = (LPCVOID) strtoul (p, &p, 0)) |
+ else if ((x = (LPCVOID) (uintptr_t) strtoull (p, NULL, 0)) |
&& ReadProcessMemory (current_process_handle, x, |
&saved_context, |
__COPY_CONTEXT_SIZE, &n) |
@@ -999,7 +1027,7 @@ display_selector (HANDLE thread, DWORD sel) |
if (GetThreadSelectorEntry (thread, sel, &info)) |
{ |
int base, limit; |
- printf_filtered ("0x%03lx: ", sel); |
+ printf_filtered ("0x%03x: ", (unsigned) sel); |
if (!info.HighWord.Bits.Pres) |
{ |
puts_filtered ("Segment not present\n"); |
@@ -1063,7 +1091,7 @@ display_selector (HANDLE thread, DWORD sel) |
if (err == ERROR_NOT_SUPPORTED) |
printf_filtered ("Function not supported\n"); |
else |
- printf_filtered ("Invalid selector 0x%lx.\n",sel); |
+ printf_filtered ("Invalid selector 0x%x.\n", (unsigned) sel); |
return 0; |
} |
} |
@@ -1227,8 +1255,8 @@ handle_exception (struct target_waitstatus *ourstatus) |
/* Treat unhandled first chance exceptions specially. */ |
if (current_event.u.Exception.dwFirstChance) |
return -1; |
- printf_unfiltered ("gdb: unknown target exception 0x%08lx at %s\n", |
- current_event.u.Exception.ExceptionRecord.ExceptionCode, |
+ printf_unfiltered ("gdb: unknown target exception 0x%08x at %s\n", |
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode, |
host_address_to_string ( |
current_event.u.Exception.ExceptionRecord.ExceptionAddress)); |
ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; |
@@ -1248,8 +1276,9 @@ windows_continue (DWORD continue_status, int id) |
thread_info *th; |
BOOL res; |
- DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%lx, %s);\n", |
- current_event.dwProcessId, current_event.dwThreadId, |
+ DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n", |
+ (unsigned) current_event.dwProcessId, |
+ (unsigned) current_event.dwThreadId, |
continue_status == DBG_CONTINUE ? |
"DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED")); |
@@ -1296,8 +1325,8 @@ fake_create_process (void) |
open_process_used = 1; |
else |
{ |
- error (_("OpenProcess call failed, GetLastError = %lud"), |
- GetLastError ()); |
+ error (_("OpenProcess call failed, GetLastError = %u"), |
+ (unsigned) GetLastError ()); |
/* We can not debug anything in that case. */ |
} |
main_thread_id = current_event.dwThreadId; |
@@ -1456,7 +1485,7 @@ get_windows_debug_event (struct target_ops *ops, |
switch (event_code) |
{ |
case CREATE_THREAD_DEBUG_EVENT: |
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", |
+ DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", |
(unsigned) current_event.dwProcessId, |
(unsigned) current_event.dwThreadId, |
"CREATE_THREAD_DEBUG_EVENT")); |
@@ -1485,7 +1514,7 @@ get_windows_debug_event (struct target_ops *ops, |
break; |
case EXIT_THREAD_DEBUG_EVENT: |
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", |
+ DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", |
(unsigned) current_event.dwProcessId, |
(unsigned) current_event.dwThreadId, |
"EXIT_THREAD_DEBUG_EVENT")); |
@@ -1493,13 +1522,14 @@ get_windows_debug_event (struct target_ops *ops, |
if (current_event.dwThreadId != main_thread_id) |
{ |
windows_delete_thread (ptid_build (current_event.dwProcessId, 0, |
- current_event.dwThreadId)); |
+ current_event.dwThreadId), |
+ current_event.u.ExitThread.dwExitCode); |
th = &dummy_thread_info; |
} |
break; |
case CREATE_PROCESS_DEBUG_EVENT: |
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", |
+ DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", |
(unsigned) current_event.dwProcessId, |
(unsigned) current_event.dwThreadId, |
"CREATE_PROCESS_DEBUG_EVENT")); |
@@ -1510,7 +1540,8 @@ get_windows_debug_event (struct target_ops *ops, |
current_process_handle = current_event.u.CreateProcessInfo.hProcess; |
if (main_thread_id) |
windows_delete_thread (ptid_build (current_event.dwProcessId, 0, |
- main_thread_id)); |
+ main_thread_id), |
+ 0); |
main_thread_id = current_event.dwThreadId; |
/* Add the main thread. */ |
th = windows_add_thread (ptid_build (current_event.dwProcessId, 0, |
@@ -1521,7 +1552,7 @@ get_windows_debug_event (struct target_ops *ops, |
break; |
case EXIT_PROCESS_DEBUG_EVENT: |
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", |
+ DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", |
(unsigned) current_event.dwProcessId, |
(unsigned) current_event.dwThreadId, |
"EXIT_PROCESS_DEBUG_EVENT")); |
@@ -1541,7 +1572,7 @@ get_windows_debug_event (struct target_ops *ops, |
break; |
case LOAD_DLL_DEBUG_EVENT: |
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", |
+ DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", |
(unsigned) current_event.dwProcessId, |
(unsigned) current_event.dwThreadId, |
"LOAD_DLL_DEBUG_EVENT")); |
@@ -1555,7 +1586,7 @@ get_windows_debug_event (struct target_ops *ops, |
break; |
case UNLOAD_DLL_DEBUG_EVENT: |
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", |
+ DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", |
(unsigned) current_event.dwProcessId, |
(unsigned) current_event.dwThreadId, |
"UNLOAD_DLL_DEBUG_EVENT")); |
@@ -1568,7 +1599,7 @@ get_windows_debug_event (struct target_ops *ops, |
break; |
case EXCEPTION_DEBUG_EVENT: |
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", |
+ DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", |
(unsigned) current_event.dwProcessId, |
(unsigned) current_event.dwThreadId, |
"EXCEPTION_DEBUG_EVENT")); |
@@ -1590,7 +1621,7 @@ get_windows_debug_event (struct target_ops *ops, |
break; |
case OUTPUT_DEBUG_STRING_EVENT: /* Message from the kernel. */ |
- DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n", |
+ DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", |
(unsigned) current_event.dwProcessId, |
(unsigned) current_event.dwThreadId, |
"OUTPUT_DEBUG_STRING_EVENT")); |
@@ -1602,11 +1633,11 @@ get_windows_debug_event (struct target_ops *ops, |
default: |
if (saw_create != 1) |
break; |
- printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n", |
- (DWORD) current_event.dwProcessId, |
- (DWORD) current_event.dwThreadId); |
- printf_unfiltered (" unknown event code %ld\n", |
- current_event.dwDebugEventCode); |
+ printf_unfiltered ("gdb: kernel event for pid=%u tid=0x%x\n", |
+ (unsigned) current_event.dwProcessId, |
+ (unsigned) current_event.dwThreadId); |
+ printf_unfiltered (" unknown event code %u\n", |
+ (unsigned) current_event.dwDebugEventCode); |
break; |
} |
@@ -1692,6 +1723,64 @@ windows_wait (struct target_ops *ops, |
} |
} |
+/* On certain versions of Windows, the information about ntdll.dll |
+ is not available yet at the time we get the LOAD_DLL_DEBUG_EVENT, |
+ thus preventing us from reporting this DLL as an SO. This has been |
+ witnessed on Windows 8.1, for instance. A possible explanation |
+ is that ntdll.dll might be mapped before the SO info gets created |
+ by the Windows system -- ntdll.dll is the first DLL to be reported |
+ via LOAD_DLL_DEBUG_EVENT and other DLLs do not seem to suffer from |
+ that problem. |
+ |
+ If we indeed are missing ntdll.dll, this function tries to recover |
+ from this issue, after the fact. Do nothing if we encounter any |
+ issue trying to locate that DLL. */ |
+ |
+static void |
+windows_ensure_ntdll_loaded (void) |
+{ |
+ struct so_list *so; |
+ HMODULE dummy_hmodule; |
+ DWORD cb_needed; |
+ HMODULE *hmodules; |
+ int i; |
+ |
+ for (so = solib_start.next; so != NULL; so = so->next) |
+ if (FILENAME_CMP (lbasename (so->so_name), "ntdll.dll") == 0) |
+ return; /* ntdll.dll already loaded, nothing to do. */ |
+ |
+ if (EnumProcessModules (current_process_handle, &dummy_hmodule, |
+ sizeof (HMODULE), &cb_needed) == 0) |
+ return; |
+ |
+ if (cb_needed < 1) |
+ return; |
+ |
+ hmodules = (HMODULE *) alloca (cb_needed); |
+ if (EnumProcessModules (current_process_handle, hmodules, |
+ cb_needed, &cb_needed) == 0) |
+ return; |
+ |
+ for (i = 0; i < (int) (cb_needed / sizeof (HMODULE)); i++) |
+ { |
+ MODULEINFO mi; |
+ char dll_name[__PMAX]; |
+ |
+ if (GetModuleInformation (current_process_handle, hmodules[i], |
+ &mi, sizeof (mi)) == 0) |
+ continue; |
+ if (GetModuleFileNameEx (current_process_handle, hmodules[i], |
+ dll_name, sizeof (dll_name)) == 0) |
+ continue; |
+ if (FILENAME_CMP (lbasename (dll_name), "ntdll.dll") == 0) |
+ { |
+ solib_end->next = windows_make_so (dll_name, mi.lpBaseOfDll); |
+ solib_end = solib_end->next; |
+ return; |
+ } |
+ } |
+} |
+ |
static void |
do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) |
{ |
@@ -1745,6 +1834,14 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) |
break; |
} |
+ /* FIXME: brobecker/2013-12-10: We should try another approach where |
+ we first ignore all DLL load/unload events up until this point, |
+ and then iterate over all modules to create the associated shared |
+ objects. This is a fairly significant change, however, and we are |
+ close to creating a release branch, so we are delaying it a bit, |
+ after the branch is created. */ |
+ windows_ensure_ntdll_loaded (); |
+ |
windows_initialization_done = 1; |
inf->control.stop_soon = NO_STOP_QUIETLY; |
stop_after_trap = 0; |
@@ -1855,7 +1952,7 @@ windows_attach (struct target_ops *ops, char *args, int from_tty) |
} |
static void |
-windows_detach (struct target_ops *ops, char *args, int from_tty) |
+windows_detach (struct target_ops *ops, const char *args, int from_tty) |
{ |
int detached = 1; |
@@ -1864,8 +1961,8 @@ windows_detach (struct target_ops *ops, char *args, int from_tty) |
if (!DebugActiveProcessStop (current_event.dwProcessId)) |
{ |
- error (_("Can't detach process %lu (error %lu)"), |
- current_event.dwProcessId, GetLastError ()); |
+ error (_("Can't detach process %u (error %u)"), |
+ (unsigned) current_event.dwProcessId, (unsigned) GetLastError ()); |
detached = 0; |
} |
DebugSetProcessKillOnExit (FALSE); |
@@ -1875,11 +1972,12 @@ windows_detach (struct target_ops *ops, char *args, int from_tty) |
char *exec_file = get_exec_file (0); |
if (exec_file == 0) |
exec_file = ""; |
- printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file, |
- current_event.dwProcessId); |
+ printf_unfiltered ("Detaching from program: %s, Pid %u\n", exec_file, |
+ (unsigned) current_event.dwProcessId); |
gdb_flush (gdb_stdout); |
} |
+ i386_cleanup_dregs (); |
inferior_ptid = null_ptid; |
detach_inferior (current_event.dwProcessId); |
@@ -1894,7 +1992,8 @@ windows_pid_to_exec_file (int pid) |
/* Try to find exe name as symlink target of /proc/<pid>/exe. */ |
int nchars; |
char procexe[sizeof ("/proc/4294967295/exe")]; |
- sprintf (procexe, "/proc/%u/exe", pid); |
+ |
+ xsnprintf (procexe, sizeof (procexe), "/proc/%u/exe", pid); |
nchars = readlink (procexe, path, sizeof(path)); |
if (nchars > 0 && nchars < sizeof (path)) |
{ |
@@ -2035,6 +2134,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, |
char shell[__PMAX]; /* Path to shell */ |
char *toexec; |
char *args; |
+ size_t args_len; |
HANDLE tty; |
char *w32env; |
char *temp; |
@@ -2091,10 +2191,10 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, |
cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t)); |
swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs); |
#else |
- cygallargs = (char *) |
- alloca (sizeof (" -c 'exec '") + strlen (exec_file) |
- + strlen (allargs) + 2); |
- sprintf (cygallargs, " -c 'exec %s %s'", exec_file, allargs); |
+ len = (sizeof (" -c 'exec '") + strlen (exec_file) |
+ + strlen (allargs) + 2); |
+ cygallargs = (char *) alloca (len); |
+ xsnprintf (cygallargs, len, " -c 'exec %s %s'", exec_file, allargs); |
#endif |
toexec = shell; |
flags |= DEBUG_PROCESS; |
@@ -2187,10 +2287,13 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, |
} |
#else |
toexec = exec_file; |
- args = alloca (strlen (toexec) + strlen (allargs) + 2); |
- strcpy (args, toexec); |
- strcat (args, " "); |
- strcat (args, allargs); |
+ /* Build the command line, a space-separated list of tokens where |
+ the first token is the name of the module to be executed. |
+ To avoid ambiguities introduced by spaces in the module name, |
+ we quote it. */ |
+ args_len = strlen (toexec) + 2 /* quotes */ + strlen (allargs) + 2; |
+ args = alloca (args_len); |
+ xsnprintf (args, args_len, "\"%s\" %s", toexec, allargs); |
flags |= DEBUG_ONLY_THIS_PROCESS; |
@@ -2257,7 +2360,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, |
#endif |
if (!ret) |
- error (_("Error creating process %s, (error %d)."), |
+ error (_("Error creating process %s, (error %u)."), |
exec_file, (unsigned) GetLastError ()); |
CloseHandle (pi.hThread); |
@@ -2298,33 +2401,43 @@ windows_stop (ptid_t ptid) |
registers_changed (); /* refresh register state */ |
} |
-static int |
-windows_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len, |
- int write, struct mem_attrib *mem, |
- struct target_ops *target) |
+/* Helper for windows_xfer_partial that handles memory transfers. |
+ Arguments are like target_xfer_partial. */ |
+ |
+static LONGEST |
+windows_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf, |
+ ULONGEST memaddr, LONGEST len) |
{ |
SIZE_T done = 0; |
- if (write) |
+ BOOL success; |
+ DWORD lasterror = 0; |
+ |
+ if (writebuf != NULL) |
{ |
- DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n", |
- len, (DWORD) (uintptr_t) memaddr)); |
- if (!WriteProcessMemory (current_process_handle, |
- (LPVOID) (uintptr_t) memaddr, our, |
- len, &done)) |
- done = 0; |
+ DEBUG_MEM (("gdb: write target memory, %s bytes at %s\n", |
+ plongest (len), core_addr_to_string (memaddr))); |
+ success = WriteProcessMemory (current_process_handle, |
+ (LPVOID) (uintptr_t) memaddr, writebuf, |
+ len, &done); |
+ if (!success) |
+ lasterror = GetLastError (); |
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, |
- (LPCVOID) (uintptr_t) memaddr, our, |
- len, &done)) |
- done = 0; |
+ DEBUG_MEM (("gdb: read target memory, %s bytes at %s\n", |
+ plongest (len), core_addr_to_string (memaddr))); |
+ success = ReadProcessMemory (current_process_handle, |
+ (LPCVOID) (uintptr_t) memaddr, readbuf, |
+ len, &done); |
+ if (!success) |
+ lasterror = GetLastError (); |
} |
- return done; |
+ if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0) |
+ return done; |
+ else |
+ return success ? done : TARGET_XFER_E_IO; |
} |
static void |
@@ -2358,10 +2471,10 @@ windows_can_run (void) |
} |
static void |
-windows_close (int x) |
+windows_close (void) |
{ |
DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n", |
- PIDGET (inferior_ptid))); |
+ ptid_get_pid (inferior_ptid))); |
} |
/* Convert pid to printable format. */ |
@@ -2399,17 +2512,19 @@ windows_xfer_shared_libraries (struct target_ops *ops, |
for (so = solib_start.next; so; so = so->next) |
windows_xfer_shared_library (so->so_name, (CORE_ADDR) |
(uintptr_t) so->lm_info->load_addr, |
- target_gdbarch, &obstack); |
+ target_gdbarch (), &obstack); |
obstack_grow_str0 (&obstack, "</library-list>\n"); |
buf = obstack_finish (&obstack); |
len_avail = strlen (buf); |
if (offset >= len_avail) |
- return 0; |
- |
- if (len > len_avail - offset) |
- len = len_avail - offset; |
- memcpy (readbuf, buf + offset, len); |
+ len= 0; |
+ else |
+ { |
+ if (len > len_avail - offset) |
+ len = len_avail - offset; |
+ memcpy (readbuf, buf + offset, len); |
+ } |
obstack_free (&obstack, NULL); |
return len; |
@@ -2423,13 +2538,7 @@ windows_xfer_partial (struct target_ops *ops, enum target_object object, |
switch (object) |
{ |
case TARGET_OBJECT_MEMORY: |
- if (readbuf) |
- return (*ops->deprecated_xfer_memory) (offset, readbuf, |
- len, 0/*read*/, NULL, ops); |
- if (writebuf) |
- return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf, |
- len, 1/*write*/, NULL, ops); |
- return -1; |
+ return windows_xfer_memory (readbuf, writebuf, offset, len); |
case TARGET_OBJECT_LIBRARIES: |
return windows_xfer_shared_libraries (ops, object, annex, readbuf, |
@@ -2483,7 +2592,6 @@ init_windows_ops (void) |
windows_ops.to_fetch_registers = windows_fetch_inferior_registers; |
windows_ops.to_store_registers = windows_store_inferior_registers; |
windows_ops.to_prepare_to_store = windows_prepare_to_store; |
- windows_ops.deprecated_xfer_memory = windows_xfer_memory; |
windows_ops.to_xfer_partial = windows_xfer_partial; |
windows_ops.to_files_info = windows_files_info; |
windows_ops.to_insert_breakpoint = memory_insert_breakpoint; |
@@ -2719,8 +2827,9 @@ _initialize_check_for_gdb_ini (void) |
{ |
int len = strlen (oldini); |
char *newini = alloca (len + 1); |
- sprintf (newini, "%.*s.gdbinit", |
- (int) (len - (sizeof ("gdb.ini") - 1)), oldini); |
+ |
+ xsnprintf (newini, len + 1, "%.*s.gdbinit", |
+ (int) (len - (sizeof ("gdb.ini") - 1)), oldini); |
warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini); |
} |
} |