From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Mike A. Harris" To: Andrew Cagney Cc: Subject: Re: Patching gdb 5.0 for XFree86 module support Date: Sun, 23 Sep 2001 22:20:00 -0000 Message-id: References: <3BAEBF5A.4090209@cygnus.com> X-SW-Source: 2001-09/msg00312.html On Mon, 24 Sep 2001, Andrew Cagney wrote: >> I've been working the last few days on porting an older gdb >> 4.18 patch that adds support to gdb for debugging XFree86 >> loadable modules in place without requiring a static server >> build. This has several advantages for an XFree86 developer, as >> well as for the more technical user out there who is capable of >> debugging a problem, but not necessarily willing or capable to >> rebuild XFree86 from source as a static server. > >Just FYI, shared library support in current GDB is very different to >that found in 5.0. It was overhalled and made far far more modular. Just to clarify, what do you mean by 'current GDB'? Do you mean current CVS of gdb, or current Rawhide GDB? My testing is with Rawhide GDB since I'm wanting to use the gdb supplied with the distro. >Looking at this patch and especially the comment: > [SNIP] >>> + * just tidy up after the last run, tell the inferior that we're >>> + * around and insert a breakpoint so we get chance to do something >>> + * when a module is loaded. >>> + * >>> + */ > >the basic idea is sound. Per Daniel J's comment several people have >proposed similar things while makig the observation that the current >shlib implementation should be generalized. Ok, sounds good. >Andrew > >PS: Since the patch is very old, I'll just add a heads up that I'll need >to run the usual checks. Ok, I have actually got it running now. I'm attaching the latest patch, which is partially functional anyway. The full src.rpm of gdb with loadable XFree86 module support is at: ftp://people.redhat.com/mharris/hacks/gdb-5.0rh-15.6xfree.src.rpm I can load symbols from .o modules manually, but aparently not from .a's. Ultimately, what I would like is for gdb to load the modules for the whole shebang all at once. Possible? Am I totally insane? 1Gb of RAM should suffice no? ;o) TIA ---------------------------------------------------------------------- Mike A. Harris Shipping/mailing address: OS Systems Engineer 190 Pittsburgh Ave., Sault Ste. Marie, XFree86 maintainer Ontario, Canada, P6C 5B3 Red Hat Inc. Phone: (705)949-2136 http://www.redhat.com ftp://people.redhat.com/mharris Red Hat XFree86 mailing list: xfree86-list@redhat.com IRC: #redhat-xfree86 on irc.openprojects.org ---------------------------------------------------------------------- root@dod.usarmy.gov:~# rm -f /bin/laden >From muller@cerbere.u-strasbg.fr Mon Sep 24 03:53:00 2001 From: Pierre Muller To: gdb-patches@sources.redhat.com Cc: Christopher Faylor Subject: [RFA] Handle win32 debugger file handles Date: Mon, 24 Sep 2001 03:53:00 -0000 Message-id: <4.2.0.58.20010924121227.01ecb100@ics.u-strasbg.fr> X-SW-Source: 2001-09/msg00313.html Content-length: 6914 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 * 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