From 2eb392bd77de1535823daeae04c83fae0e331ee8 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 15 Jul 2000 02:48:11 +0000 Subject: * hinfo.cc (hinfo::linearize_fd_array): Make max_used_fd an int so that we can detect when there are no fds to pass. * dcrt0.cc (host_dependent_constants::init): Revert Sat Mar 18 01:32:04 2000 change. (dll_crt0_1): Set "cygwin_finished_initializing" flag. (dll_crt0): Don't perform memcpy if uptr is already set to internal structure. (_dll_crt0): Remember location of programs envptr. * dll_init.h (per_module, dll, dll_list): Revamp. * dll_init.cc: Revamp. Use new classes. * fork.cc (fork): Use new revamped dll, dll_list, and per_module stuff. * environ.cc: Use __cygwin_environ throughout rather than the user_data->envptr. * exec.cc: Ditto. * spawn.cc: Ditto. * winsup.h: Declare update_envptrs, cygwin_finished_initializing. * lib/_cygwin_crt0_common.cc (_cygwin_crt0_common): Revert previous change. * lib/cygwin_attach_dll.cc (cygwin_attach_dll): Always pass in own per_process structure or we end up overwriting information from the main program. --- winsup/cygwin/fork.cc | 81 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 33 deletions(-) (limited to 'winsup/cygwin/fork.cc') diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 54c668137..fdd63c6e3 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -280,6 +280,13 @@ fork () return -1; } + /* Remember the address of the first loaded dll and decide + if we need to load dlls. We do this here so that this + information will be available in the parent and, when + the stack is copied, in the child. */ + dll *first_dll = dlls.start.next; + int load_dlls = dlls.reload_on_fork && dlls.loaded_dlls; + static child_info_fork ch; x = setjmp (ch.jmp); @@ -457,43 +464,41 @@ fork () if (!rc) goto cleanup; - /* Now fill data/bss of linked dll */ - DO_LINKED_DLL (p) - { - debug_printf ("copying data/bss of a linked dll"); - if (!fork_copy (pi, "linked dll data/bss", p->data_start, p->data_end, - p->bss_start, p->bss_end, - NULL)) - goto cleanup; - } - DLL_DONE; + /* Now fill data/bss of any DLLs that were linked into the program. */ + for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ()) + { + debug_printf ("copying data/bss of a linked dll"); + if (!fork_copy (pi, "linked dll data/bss", d->p.data_start, d->p.data_end, + d->p.bss_start, d->p.bss_end, + NULL)) + goto cleanup; + } proc_register (child); - int load_dll = DllList::the().forkeeMustReloadDlls() && - DllList::the().numberOfOpenedDlls(); /* Start thread, and wait for it to reload dlls. */ if (!resume_child (pi, forker_finished) || - !sync_with_child (pi, subproc_ready, load_dll, "child loading dlls")) + !sync_with_child (pi, subproc_ready, load_dlls, "child loading dlls")) goto cleanup; - /* child reload dlls & then write their data and bss */ - if (load_dll) - { - /* CHILD IS STOPPED */ - /* write memory of reloaded dlls */ - DO_LOADED_DLL (p) + /* If DLLs were loaded in the parent, then the child has reloaded all + of them and is now waiting to have all of the individual data and + bss sections filled in. */ + if (load_dlls) { - debug_printf ("copying data/bss for a loaded dll"); - if (!fork_copy (pi, "loaded dll data/bss", p->data_start, p->data_end, - p->bss_start, p->bss_end, - NULL)) - goto cleanup; + /* CHILD IS STOPPED */ + /* write memory of reloaded dlls */ + for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ()) + { + debug_printf ("copying data/bss for a loaded dll"); + if (!fork_copy (pi, "loaded dll data/bss", d->p.data_start, d->p.data_end, + d->p.bss_start, d->p.bss_end, + NULL)) + goto cleanup; + } + /* Start the child up again. */ + (void) resume_child (pi, forker_finished); } - DLL_DONE; - /* Start the child up again. */ - (void) resume_child (pi, forker_finished); - } ForceCloseHandle (subproc_ready); ForceCloseHandle (pi.hThread); @@ -532,6 +537,14 @@ fork () char c; if (GetEnvironmentVariable ("FORKDEBUG", &c, 1)) try_to_debug (); + char buf[80]; + /* This is useful for debugging fork problems. Use gdb to attach to + the pid reported here. */ + if (GetEnvironmentVariable ("CYGWIN_FORK_SLEEP", buf, sizeof (buf))) + { + small_printf ("Sleeping %d after fork, pid %u\n", atoi (buf), GetCurrentProcessId ()); + Sleep (atoi(buf)); + } #endif /* If we've played with the stack, stacksize != 0. That means that @@ -548,20 +561,22 @@ fork () dtable.fixup_after_fork (hParent); signal_fixup_after_fork (); - ForceCloseHandle (hParent); MALLOC_CHECK; - /* reload dlls if necessary */ - if (!DllList::the().forkeeMustReloadDlls() || - !DllList::the().numberOfOpenedDlls()) + /* If we haven't dynamically loaded any dlls, just signal + the parent. Otherwise, load all the dlls, tell the parent + that we're done, and wait for the parent to fill in the. + loaded dlls' data/bss. */ + if (!load_dlls) sync_with_parent ("performed fork fixup.", FALSE); else { - DllList::the().forkeeLoadDlls(); + dlls.load_after_fork (hParent, first_dll); sync_with_parent ("loaded dlls", TRUE); } + ForceCloseHandle (hParent); (void) ForceCloseHandle (child_proc_info->subproc_ready); (void) ForceCloseHandle (child_proc_info->forker_finished); -- cgit v1.2.3