Approved by kev@cygnus.com
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
index 82d4c9466080b270116e803059912b6a9f65b923..ab5f3f32878dfafd92890e55ab75d83efce49df9 100644 (file)
@@ -440,9 +440,9 @@ struct so_stuff
 {
   struct so_stuff *next, **last;
   DWORD load_addr;
-  char name[0];
-}
-solib_start, *solib_end;
+  int loaded;
+  char name[1];
+solib_start, *solib_end;
 
 /* Call symbol_file_add with stderr redirected.  We don't care if there
    are errors. */
@@ -450,10 +450,10 @@ static int
 safe_symbol_file_add_stub (void *argv)
 {
 #define p ((struct safe_symbol_file_add_args *)argv)
-  struct so_stuff *so = solib_start.next;
+  struct so_stuff *so = &solib_start;
 
   while ((so = so->next))
-    if (strcasecmp (so->name, p->name) == 0)
+    if (so->loaded && strcasecmp (so->name, p->name) == 0)
       return 0;
   p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
   return !!p->ret;
@@ -509,13 +509,38 @@ static void
 register_loaded_dll (const char *name, DWORD load_addr)
 {
   struct so_stuff *so;
-  so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (name) + 8 + 2);
+  char ppath[MAX_PATH + 1];
+  char buf[MAX_PATH + 1];
+  char cwd[MAX_PATH + 1];
+  char *p;
+  WIN32_FIND_DATA w32_fd;
+  HANDLE h = FindFirstFile(name, &w32_fd);
+  size_t len;
+
+  FindClose (h);
+  strcpy (buf, name);
+  if (GetCurrentDirectory (MAX_PATH + 1, cwd))
+    {
+      p = strrchr (buf, '\\');
+      if (p)
+       p[1] = '\0';
+      SetCurrentDirectory (buf);
+      GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
+      SetCurrentDirectory (cwd);
+    }
+
+  cygwin_conv_to_posix_path (buf, ppath);
+  so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
+  so->loaded = 0;
   so->load_addr = load_addr;
-  strcpy (so->name, name);
+  strcpy (so->name, ppath);
 
   solib_end->next = so;
   solib_end = so;
   so->next = NULL;
+  len = strlen (ppath);
+  if (len > max_dll_name_len)
+    max_dll_name_len = len;
 }
 
 /* Wait for child to do something.  Return pid of child, or -1 in case
@@ -528,7 +553,6 @@ handle_load_dll (void *dummy ATTRIBUTE_UNUSED)
   DWORD done;
   char dll_buf[MAX_PATH + 1];
   char *dll_name = NULL;
-  int len;
   char *p;
 
   dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
@@ -597,15 +621,7 @@ handle_load_dll (void *dummy ATTRIBUTE_UNUSED)
   if (!dll_name)
     return 1;
 
-  (void) strlwr (dll_name);
-
-  while ((p = strchr (dll_name, '\\')))
-    *p = '/';
-
   register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
-  len = strlen (dll_name);
-  if (len > max_dll_name_len)
-    max_dll_name_len = len;
 
   return 1;
 }
@@ -650,14 +666,14 @@ solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
   memset (&section_addrs, 0, sizeof (section_addrs));
   section_addrs.other[0].name = ".text";
   section_addrs.other[0].addr = load_addr;
-  safe_symbol_file_add (name, from_tty, 0, 0, OBJF_SHARED);
+  safe_symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
 
   return;
 }
 
 /* Load DLL symbol info. */
 void
-dll_symbol_command (char *args, int from_tty ATTRIBUTE_UNUSED)
+dll_symbol_command (char *args, int from_tty)
 {
   int n;
   dont_repeat ();
@@ -674,7 +690,7 @@ dll_symbol_command (char *args, int from_tty ATTRIBUTE_UNUSED)
       args = newargs;
     }
 
-  safe_symbol_file_add (args, 0, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
+  safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
 }
 
 /* List currently loaded DLLs. */
@@ -1021,8 +1037,36 @@ do_initial_child_stuff (DWORD pid)
   return;
 }
 
-/* Attach to process PID, then initialize for debugging it.  */
+/* 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 (*DebugSetProcessKillOnExit)(BOOL);
+static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
+
+static int
+has_detach_ability ()
+{
+  static HMODULE kernel32 = NULL;
 
+  if (!kernel32)
+    kernel32 = LoadLibrary ("kernel32.dll");
+  if (kernel32)
+    {
+      if (!DebugSetProcessKillOnExit)
+       DebugSetProcessKillOnExit = GetProcAddress (kernel32,
+                                                "DebugSetProcessKillOnExit");
+      if (!DebugActiveProcessStop)
+       DebugActiveProcessStop = GetProcAddress (kernel32,
+                                                "DebugActiveProcessStop");
+      if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
+       return 1;
+    }
+  return 0;
+}
+
+/* Attach to process PID, then initialize for debugging it.  */
 static void
 child_attach (char *args, int from_tty)
 {
@@ -1038,6 +1082,12 @@ child_attach (char *args, int from_tty)
   if (!ok)
     error ("Can't attach to process.");
 
+  if (has_detach_ability ())
+    {
+      attach_flag = 1;
+      DebugSetProcessKillOnExit (FALSE);
+    }
+
   if (from_tty)
     {
       char *exec_file = (char *) get_exec_file (0);
@@ -1059,13 +1109,27 @@ child_attach (char *args, int from_tty)
 static void
 child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
 {
-  if (from_tty)
+  int detached = 1;
+
+  if (has_detach_ability ())
+    {
+      delete_command (NULL, 0);
+      child_continue (DBG_CONTINUE, -1);
+      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);
       if (exec_file == 0)
        exec_file = "";
-      printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
-                        target_pid_to_str (inferior_ptid));
+      printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
+                        current_event.dwProcessId);
       gdb_flush (gdb_stdout);
     }
   inferior_ptid = null_ptid;
@@ -1404,7 +1468,6 @@ _initialize_inftarg (void)
               "Load dll library symbols from FILE.");
   c->completer = filename_completer;
 
-  auto_solib_add = 1;
   add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
 
   add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
@@ -1644,8 +1707,10 @@ out:
 }
 
 void
-child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty, struct target_ops *target)
+child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty, struct target_ops *target, int readsyms)
 {
+  if (!readsyms)
+    return;
   if (core_bfd)
     {
       child_clear_solibs ();
This page took 0.026068 seconds and 4 git commands to generate.