This is the mail archive of the gdb-patches@sources.redhat.com 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]

[RFA] Handle win32 debugger file handles



   The following patch fixed a long stand problem with the win32 version of
GDB when used as part of an editor.
   This is the case for the FP IDE (a Free Pascal IDE
that integrates GDB for internal debugging).
See http://sources.redhat.com/ml/cygwin/2001-08/msg00147.html

   That patch is still incomplete, in the sense that
this does allow to change the executable after
running it under the debugger, but we still leave
open file handles for all used dlls.
   The problem here is that the corresponding struct object
are not freed when the program is exited or killed. As I am unsure how
to solve this secondary problem (less people use the IDE to debug DLLs)
I send this patch with that problem pending.


2001-09-22  Pierre Muller  <muller@ics.u-strasbg.fr>

	* win32-nat.c: Handle hFile fields given by WaitForDebugEvent
              when dwDebugEventCode is either CREATE_PROCESS_DEBUG_EVENT
              or LOAD_DLL_DEBUG_EVENT.
              (current_process_file_handle): New static variable.
              (struct so_stuff): Add new field hFile.
              (register_loaded_dll): Add new arg: hFile.
              (handle_load_dll): Adapt to new register_loaded_dll function.
              (handle_unload_dll): New function.
              (child_clear_solibs):  Close hFile handles if valid.
              (child_clear_solib_handles): New function that closes all 
open handles.
              (get_child_debug_event): set or close the different file handles.
	   (core_dll_symbols_add): adapt to modified register_loaded_dll function.

Index: win32-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/win32-nat.c,v
retrieving revision 1.27
diff -u -r1.27 win32-nat.c
--- win32-nat.c	2001/05/04 04:15:28	1.27
+++ win32-nat.c	2001/09/24 10:21:50
@@ -105,6 +105,7 @@
  static DEBUG_EVENT current_event;	/* The current debug event from
  					   WaitForDebugEvent */
  static HANDLE current_process_handle;	/* Currently executing process */
+static HANDLE current_process_file_handle;	/* Currently executing process 
file handle */
  static thread_info *current_thread;	/* Info on currently selected thread */
  static DWORD main_thread_id;	/* Thread ID of the main thread */

@@ -493,6 +494,7 @@
  {
    struct so_stuff *next, **last;
    DWORD load_addr;
+  HANDLE hFile;
    char name[0];
  }
  solib_start, *solib_end;
@@ -501,12 +503,17 @@
  int max_dll_name_len;

  static void
-register_loaded_dll (const char *name, DWORD load_addr)
+register_loaded_dll (const char *name, DWORD load_addr, HANDLE hFile)
  {
+  int len;
    struct so_stuff *so;
    so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen 
(name) + 8 + 2);
    so->load_addr = load_addr;
+  so->hFile = hFile;
    strcpy (so->name, name);
+  len = strlen (name);
+  if (len > max_dll_name_len)
+    max_dll_name_len = len;

    solib_end->next = so;
    solib_end = so;
@@ -597,14 +604,35 @@
    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;
+  register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000, 
event->hFile);

    return 1;
  }

+static int
+handle_unload_dll (void * lpBaseOfDll)
+{
+  struct so_stuff *so = &solib_start, *so1 = solib_start.next;
+
+  while (so1 != NULL)
+    {
+      if (so1->load_addr == ((DWORD) lpBaseOfDll) + 0x1000)
+        {
+
+          if (so1->hFile != INVALID_HANDLE_VALUE)
+            CloseHandle(so1->hFile);
+          /* FIXME: There is still no function to unload
+             the symbols loaded by this DLL */
+          so->next = so1->next;
+          xfree(so1);
+          return 1;
+        }
+      so = so1;
+      so1 = so->next;
+    }
+ return 0;
+}
+
  /* Return name of last loaded DLL. */
  char *
  child_solib_loaded_library_pathname (int pid ATTRIBUTE_UNUSED)
@@ -620,6 +648,8 @@

    while ((so = so1) != NULL)
      {
+      if (so1->hFile != INVALID_HANDLE_VALUE)
+        CloseHandle(so1->hFile);
        so1 = so->next;
        xfree (so);
      }
@@ -629,6 +659,21 @@
    max_dll_name_len = sizeof ("DLL Name") - 1;
  }

+/* Close handles of list of loaded DLLs. */
+void
+child_clear_solib_handles (void)
+{
+  struct so_stuff *so = solib_start.next;
+
+  while (so != NULL)
+    {
+      if (so->hFile != INVALID_HANDLE_VALUE)
+        CloseHandle(so->hFile);
+      so->hFile = INVALID_HANDLE_VALUE;
+      so = so->next;
+    }
+}
+
  /* Add DLL symbol information. */
  void
  solib_symbols_add (char *name, CORE_ADDR load_addr)
@@ -869,6 +914,7 @@
  		     (unsigned) current_event.dwThreadId,
  		     "CREATE_PROCESS_DEBUG_EVENT"));
        current_process_handle = current_event.u.CreateProcessInfo.hProcess;
+      current_process_file_handle = current_event.u.CreateProcessInfo.hFile;

        main_thread_id = current_event.dwThreadId;
        /* Add the main thread */
@@ -889,6 +935,8 @@
        ourstatus->kind = TARGET_WAITKIND_EXITED;
        ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
        CloseHandle (current_process_handle);
+      CloseHandle (current_process_file_handle);
+      child_clear_solib_handles ();
        retval = main_thread_id;
        break;

@@ -897,7 +945,7 @@
  		     (unsigned) current_event.dwProcessId,
  		     (unsigned) current_event.dwThreadId,
  		     "LOAD_DLL_DEBUG_EVENT"));
-      catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
+      catch_errors (handle_load_dll, NULL, (char *) "Error in 
handle_load_dll", RETURN_MASK_ALL);
        registers_changed ();	/* mark all regs invalid */
        ourstatus->kind = TARGET_WAITKIND_LOADED;
        ourstatus->value.integer = 0;
@@ -909,6 +957,7 @@
  		     (unsigned) current_event.dwProcessId,
  		     (unsigned) current_event.dwThreadId,
  		     "UNLOAD_DLL_DEBUG_EVENT"));
+      catch_errors (handle_unload_dll, (void *) 
current_event.u.UnloadDll.lpBaseOfDll, (char *) "Error in 
handle_unload_dll", RETURN_MASK_ALL);
        break;			/* FIXME: don't know what to do here */

      case EXCEPTION_DEBUG_EVENT:
@@ -1272,6 +1321,9 @@
      }

    CHECK (CloseHandle (current_process_handle));
+  /* Close all file handles given by the OS */
+  CHECK (CloseHandle (current_process_file_handle));
+  child_clear_solib_handles ();

    /* this may fail in an attached process so don't check. */
    (void) CloseHandle (current_thread->h);
@@ -1489,7 +1541,7 @@
        }
    }

-  register_loaded_dll (dll_name, base_addr + 0x1000);
+  register_loaded_dll (dll_name, base_addr + 0x1000, INVALID_HANDLE_VALUE);
    solib_symbols_add (dll_name, (CORE_ADDR) base_addr + 0x1000);

  out:




Pierre Muller
Institut Charles Sadron
6,rue Boussingault
F 67083 STRASBOURG CEDEX (France)
mailto:muller@ics.u-strasbg.fr
Phone : (33)-3-88-41-40-07  Fax : (33)-3-88-41-40-99


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