On 01/02/2010 19:28, Dave Korn wrote: > On 01/02/2010 17:51, Christopher Faylor wrote: >> On Mon, Feb 01, 2010 at 12:46:11PM -0500, Christopher Faylor wrote: > >>>> Cribbing from the gdb source code, it looks like they use BaseAddrees + >>>> 0x1000 for the start point and then call GetModuleInformation to workout >>>> the size of the module. >>> Yeah, duh. "they" == "me". I should have checked gdb for this since I've >>> already done this research once before. >>> >>> If you do find that this works, then I think this may fall into the >>> realm of a non-trivial patch so it may be best to just tell me what >>> you've found rather than provide a patch - unless you want to go through >>> the approval process with Red Hat. >>> >>> Or, you can just wait for me to adapt what's in gdb to cygwin. I can do >>> tonight when I get back to a windows system. >> Btw, it isn't entirely clear that GetModuleInformation will work with >> older versions of Windows NT so this may not be a complete solution. We >> do use GetModuleInformation in Cygwin but it is not in anything as >> crucial as this. > > Can't we use the info in the dll struct? It has pointers to the data and > bss section, we could take the max out of them and the data in the M_B_I > struct. (Tell you what, I'll try it.)
Yep, that makes the original testcase work for me. How about it? winsup/cygwin/ChangeLog: * dll_init.cc (remove_dll_atexit): Take pointer to dll and estimate end of dll more generously. (dll_list::detach): Update caller. (This is just the first patch on its way relating to this subject.) cheers, DaveK
Index: dll_init.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/dll_init.cc,v retrieving revision 1.68 diff -p -u -r1.68 dll_init.cc --- dll_init.cc 29 Jan 2010 18:34:09 -0000 1.68 +++ dll_init.cc 1 Feb 2010 19:55:10 -0000 @@ -153,11 +153,15 @@ dll_list::alloc (HINSTANCE h, per_proces register an atexit function outside of the DLL and that should be run when the DLL detachs. */ static void -remove_dll_atexit (MEMORY_BASIC_INFORMATION& m) +remove_dll_atexit (const MEMORY_BASIC_INFORMATION& m, const dll *d) { unsigned char *dll_beg = (unsigned char *) m.AllocationBase; unsigned char *dll_end = (unsigned char *) m.AllocationBase + m.RegionSize; struct _atexit *p = _GLOBAL_REENT->_atexit; + if (dll_end < d->p.data_end) + dll_end = (unsigned char *) d->p.data_end; + if (dll_end < d->p.bss_end) + dll_end = (unsigned char *) d->p.bss_end; for (int n = p->_ind - 1; n >= 0; n--) { void (*fn) (void) = p->_fns[n]; @@ -188,7 +192,7 @@ dll_list::detach (void *retaddr) system_printf ("WARNING: trying to detach an already detached dll ..."); else if (--d->count == 0) { - remove_dll_atexit (m); + remove_dll_atexit (m, d); d->run_dtors (); d->prev->next = d->next; if (d->next)