OSDN Git Service

* dcrt0.cc (getstack): New function.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / fork.cc
1 /* fork.cc
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005
4    Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 #include "winsup.h"
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include <stdarg.h>
17 #include "cygerrno.h"
18 #include "security.h"
19 #include "path.h"
20 #include "fhandler.h"
21 #include "dtable.h"
22 #include "sigproc.h"
23 #include "pinfo.h"
24 #include "cygheap.h"
25 #include "child_info.h"
26 #include "cygtls.h"
27 #include "perprocess.h"
28 #include "dll_init.h"
29 #include "sync.h"
30 #include "shared_info.h"
31 #include "cygmalloc.h"
32 #include "cygthread.h"
33
34 #define NPIDS_HELD 4
35
36 /* Timeout to wait for child to start, parent to init child, etc.  */
37 /* FIXME: Once things stabilize, bump up to a few minutes.  */
38 #define FORK_WAIT_TIMEOUT (300 * 1000)     /* 300 seconds */
39
40 #define dll_data_start &_data_start__
41 #define dll_data_end &_data_end__
42 #define dll_bss_start &_bss_start__
43 #define dll_bss_end &_bss_end__
44
45 class frok
46 {
47   dll *first_dll;
48   bool load_dlls;
49   child_info_fork ch;
50   const char *error;
51   int child_pid;
52   int this_errno;
53   int __stdcall parent (void *esp);
54   int __stdcall child (void *esp);
55   friend int fork ();
56 };
57
58 static void
59 stack_base (child_info_fork *ch)
60 {
61   ch->stackbottom = _tlsbase;
62   ch->stacktop = &ch;
63   ch->stacksize = (char *) ch->stackbottom - (char *) &ch;
64   debug_printf ("bottom %p, top %p, stack %p, size %d, reserve %d",
65                 ch->stackbottom, ch->stacktop, &ch, ch->stacksize,
66                 (char *) ch->stackbottom - (char *) ch->stacktop);
67 }
68
69 /* Copy memory from parent to child.
70    The result is a boolean indicating success.  */
71
72 static int
73 fork_copy (PROCESS_INFORMATION& pi, const char *what, ...)
74 {
75   va_list args;
76   char *low;
77   int pass = 0;
78
79   va_start (args, what);
80
81   while ((low = va_arg (args, char *)))
82     {
83       char *high = va_arg (args, char *);
84       DWORD todo = wincap.chunksize () ?: high - low;
85       char *here;
86
87       for (here = low; here < high; here += todo)
88         {
89           DWORD done = 0;
90           if (here + todo > high)
91             todo = high - here;
92           int res;
93           if (pi.hThread)
94             res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
95           else
96             res = ReadProcessMemory (pi.hProcess, here, here, todo, &done);
97           debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
98                         low, high, res);
99           if (!res || todo != done)
100             {
101               if (!res)
102                 __seterrno ();
103               /* If this happens then there is a bug in our fork
104                  implementation somewhere. */
105               system_printf ("%s pass %d failed, %p..%p, done %d, windows pid %u, %E",
106                             what, pass, low, high, done, pi.dwProcessId);
107               goto err;
108             }
109         }
110
111       pass++;
112     }
113
114   debug_printf ("done");
115   return 1;
116
117  err:
118   TerminateProcess (pi.hProcess, 1);
119   set_errno (EAGAIN);
120   return 0;
121 }
122
123 static int
124 resume_child (HANDLE forker_finished)
125 {
126   SetEvent (forker_finished);
127   debug_printf ("signalled child");
128   return 1;
129 }
130
131 /* Notify parent that it is time for the next step. */
132 static void __stdcall
133 sync_with_parent (const char *s, bool hang_self)
134 {
135   debug_printf ("signalling parent: %s", s);
136   fork_info->ready (false);
137   if (hang_self)
138     {
139       HANDLE h = fork_info->forker_finished;
140       /* Wait for the parent to fill in our stack and heap.
141          Don't wait forever here.  If our parent dies we don't want to clog
142          the system.  If the wait fails, we really can't continue so exit.  */
143       DWORD psync_rc = WaitForSingleObject (h, FORK_WAIT_TIMEOUT);
144       debug_printf ("awake");
145       switch (psync_rc)
146         {
147         case WAIT_TIMEOUT:
148           api_fatal ("WFSO timed out %s", s);
149           break;
150         case WAIT_FAILED:
151           if (GetLastError () == ERROR_INVALID_HANDLE &&
152               WaitForSingleObject (fork_info->forker_finished, 1) != WAIT_FAILED)
153             break;
154           api_fatal ("WFSO failed %s, fork_finished %p, %E", s,
155                      fork_info->forker_finished);
156           break;
157         default:
158           debug_printf ("no problems");
159           break;
160         }
161     }
162 }
163
164 int __stdcall
165 frok::child (void *)
166 {
167   HANDLE& hParent = ch.parent;
168   extern void fixup_hooks_after_fork ();
169   extern void fixup_timers_after_fork ();
170   debug_printf ("child is running.  pid %d, ppid %d, stack here %p",
171                 myself->pid, myself->ppid, __builtin_frame_address (0));
172
173   sync_with_parent ("after longjmp", true);
174   sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent,
175                   first_dll, load_dlls);
176
177   /* If we've played with the stack, stacksize != 0.  That means that
178      fork() was invoked from other than the main thread.  Make sure that
179      the threadinfo information is properly set up.  */
180   if (fork_info->stacksize)
181     {
182       _main_tls = &_my_tls;
183       _main_tls->init_thread (NULL, NULL);
184       _main_tls->local_clib = *_impure_ptr;
185       _impure_ptr = &_main_tls->local_clib;
186     }
187
188   if (wincap.has_security ())
189     {
190       set_cygwin_privileges (hProcImpToken);
191       cygheap->user.reimpersonate ();
192     }
193
194 #ifdef DEBUGGING
195   char c;
196   if (GetEnvironmentVariable ("FORKDEBUG", &c, 1))
197     try_to_debug ();
198   char buf[80];
199   /* This is useful for debugging fork problems.  Use gdb to attach to
200      the pid reported here. */
201   if (GetEnvironmentVariable ("CYGWIN_FORK_SLEEP", buf, sizeof (buf)))
202     {
203       small_printf ("Sleeping %d after fork, pid %u\n", atoi (buf), GetCurrentProcessId ());
204       Sleep (atoi (buf));
205     }
206 #endif
207
208   set_file_api_mode (current_codepage);
209
210   MALLOC_CHECK;
211
212   if (fixup_mmaps_after_fork (hParent))
213     api_fatal ("recreate_mmaps_after_fork_failed");
214
215 #ifdef USE_SERVER
216   /* Incredible but true:  If we use sockets and SYSV IPC shared memory,
217      there's a good chance that a duplicated socket in the child occupies
218      memory which is needed to duplicate shared memory from the parent
219      process, if the shared memory hasn't been duplicated already.
220      The same goes very likely for "normal" mmap shared memory, too, but
221      with SYSV IPC it was the first time observed.  So, *never* fixup
222      fdtab before fixing up shared memory. */
223   if (fixup_shms_after_fork ())
224     api_fatal ("recreate_shm areas after fork failed");
225 #endif
226
227   MALLOC_CHECK;
228
229   /* If we haven't dynamically loaded any dlls, just signal
230      the parent.  Otherwise, load all the dlls, tell the parent
231       that we're done, and wait for the parent to fill in the.
232       loaded dlls' data/bss. */
233   if (!load_dlls)
234     {
235       cygheap->fdtab.fixup_after_fork (hParent);
236       sync_with_parent ("performed fork fixup", false);
237     }
238   else
239     {
240       dlls.load_after_fork (hParent, first_dll);
241       cygheap->fdtab.fixup_after_fork (hParent);
242       sync_with_parent ("loaded dlls", true);
243     }
244
245   ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
246
247   _my_tls.fixup_after_fork ();
248   sigproc_init ();
249
250   pthread::atforkchild ();
251   fixup_timers_after_fork ();
252   fixup_hooks_after_fork ();
253   cygbench ("fork-child");
254   ld_preload ();
255   cygwin_finished_initializing = true;
256   return 0;
257 }
258
259 #define NO_SLOW_PID_REUSE
260 #ifndef NO_SLOW_PID_REUSE
261 static void
262 slow_pid_reuse (HANDLE h)
263 {
264   static NO_COPY HANDLE last_fork_procs[NPIDS_HELD];
265   static NO_COPY unsigned nfork_procs;
266
267   if (nfork_procs >= (sizeof (last_fork_procs) / sizeof (last_fork_procs [0])))
268     nfork_procs = 0;
269   /* Keep a list of handles to child processes sitting around to prevent
270      Windows from reusing the same pid n times in a row.  Having the same pids
271      close in succesion confuses bash.  Keeping a handle open will stop
272      windows from reusing the same pid.  */
273   if (last_fork_procs[nfork_procs])
274     ForceCloseHandle1 (last_fork_procs[nfork_procs], fork_stupidity);
275   if (DuplicateHandle (hMainProc, h, hMainProc, &last_fork_procs[nfork_procs],
276                         0, FALSE, DUPLICATE_SAME_ACCESS))
277     ProtectHandle1 (last_fork_procs[nfork_procs], fork_stupidity);
278   else
279     {
280       last_fork_procs[nfork_procs] = NULL;
281       system_printf ("couldn't create last_fork_proc, %E");
282     }
283   nfork_procs++;
284 }
285 #endif
286
287 int __stdcall
288 frok::parent (void *stack_here)
289 {
290   HANDLE forker_finished;
291   DWORD rc;
292   PROCESS_INFORMATION pi = {0, NULL, 0, 0};
293   child_pid = -1;
294   error = NULL;
295   this_errno = 0;
296   bool fix_impersonation = false;
297   pinfo child;
298
299   pthread::atforkprepare ();
300
301   int c_flags = GetPriorityClass (hMainProc);
302   STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
303
304   /* If we don't have a console, then don't create a console for the
305      child either.  */
306   HANDLE console_handle = CreateFile ("CONOUT$", GENERIC_WRITE,
307                                       FILE_SHARE_WRITE, &sec_none_nih,
308                                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
309                                       NULL);
310
311   if (console_handle != INVALID_HANDLE_VALUE)
312     CloseHandle (console_handle);
313   else
314     c_flags |= DETACHED_PROCESS;
315
316   /* Some file types (currently only sockets) need extra effort in the
317      parent after CreateProcess and before copying the datastructures
318      to the child. So we have to start the child in suspend state,
319      unfortunately, to avoid a race condition. */
320   if (cygheap->fdtab.need_fixup_before ())
321     c_flags |= CREATE_SUSPENDED;
322
323   /* Remember the address of the first loaded dll and decide
324      if we need to load dlls.  We do this here so that this
325      information will be available in the parent and, when
326      the stack is copied, in the child. */
327   first_dll = dlls.start.next;
328   load_dlls = dlls.reload_on_fork && dlls.loaded_dlls;
329
330   /* This will help some of the confusion.  */
331   fflush (stdout);
332
333   forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
334   if (forker_finished == NULL)
335     {
336       this_errno = geterrno_from_win_error ();
337       error = "child %d - unable to allocate forker_finished event, %E";
338       return -1;
339     }
340
341   ProtectHandleINH (forker_finished);
342
343   ch.forker_finished = forker_finished;
344
345   stack_base (&ch);
346
347   si.cb = sizeof (STARTUPINFO);
348   si.lpReserved2 = (LPBYTE) &ch;
349   si.cbReserved2 = sizeof (ch);
350
351   /* Remove impersonation */
352   cygheap->user.deimpersonate ();
353   fix_impersonation = true;
354
355   syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %p, 0, 0, %p, %p)",
356                   myself->progname, myself->progname, c_flags, &si, &pi);
357   bool locked = __malloc_lock ();
358   rc = CreateProcess (myself->progname, /* image to run */
359                       myself->progname, /* what we send in arg0 */
360                       &sec_none_nih,
361                       &sec_none_nih,
362                       TRUE,       /* inherit handles from parent */
363                       c_flags,
364                       NULL,       /* environment filled in later */
365                       0,          /* use current drive/directory */
366                       &si,
367                       &pi);
368
369   if (!rc)
370     {
371       this_errno = geterrno_from_win_error ();
372       error = "child %d - CreateProcessA failed, %E";
373       goto cleanup;
374     }
375
376
377   /* Fixup the parent datastructure if needed and resume the child's
378      main thread. */
379   if (cygheap->fdtab.need_fixup_before ())
380     {
381       cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
382       ResumeThread (pi.hThread);
383     }
384
385   child_pid = cygwin_pid (pi.dwProcessId);
386   child.init (child_pid, 1, NULL);
387
388   if (!child)
389     {
390       this_errno = get_errno () == ENOMEM ? ENOMEM : EAGAIN;
391 #ifdef DEBUGGING
392       error = "child %d - pinfo failed";
393 #else
394       syscall_printf ("pinfo failed");
395 #endif
396       goto cleanup;
397     }
398
399   child->start_time = time (NULL); /* Register child's starting time. */
400   child->nice = myself->nice;
401
402   /* Initialize things that are done later in dll_crt0_1 that aren't done
403      for the forkee.  */
404   strcpy (child->progname, myself->progname);
405
406   /* Restore impersonation */
407   cygheap->user.reimpersonate ();
408   fix_impersonation = false;
409
410   ProtectHandle (pi.hThread);
411   /* Protect the handle but name it similarly to the way it will
412      be called in subproc handling. */
413   ProtectHandle1 (pi.hProcess, childhProc);
414
415   /* Fill in fields in the child's process table entry.  */
416   child->dwProcessId = pi.dwProcessId;
417   child.hProcess = pi.hProcess;
418
419   /* Hopefully, this will succeed.  The alternative to doing things this
420      way is to reserve space prior to calling CreateProcess and then fill
421      it in afterwards.  This requires more bookkeeping than I like, though,
422      so we'll just do it the easy way.  So, terminate any child process if
423      we can't actually record the pid in the internal table. */
424   if (!child.remember (false))
425     {
426       TerminateProcess (pi.hProcess, 1);
427       this_errno = EAGAIN;
428 #ifdef DEBUGGING
429       error = "child %d - child.remember failed";
430 #endif
431       goto cleanup;
432     }
433
434 #ifndef NO_SLOW_PID_REUSE
435   slow_pid_reuse (pi.hProcess);
436 #endif
437
438   /* Wait for subproc to initialize itself. */
439   if (!ch.sync (child->pid, pi.hProcess, FORK_WAIT_TIMEOUT))
440     {
441       this_errno = EAGAIN;
442       error = "child %d - died waiting for longjmp before initialization";
443       goto cleanup;
444     }
445
446   /* CHILD IS STOPPED */
447   debug_printf ("child is alive (but stopped)");
448
449   /* Initialize, in order: data, bss, heap, stack, dll data, dll bss
450      Note: variables marked as NO_COPY will not be copied
451      since they are placed in a protected segment. */
452
453
454   MALLOC_CHECK;
455   void *impure_beg;
456   void *impure_end;
457   if (&_my_tls == _main_tls)
458     impure_beg = impure_end = NULL;
459   else
460     {
461       impure_beg = _impure_ptr;
462       impure_end = _impure_ptr + 1;
463     }
464   rc = fork_copy (pi, "user/cygwin data",
465                   user_data->data_start, user_data->data_end,
466                   user_data->bss_start, user_data->bss_end,
467                   cygheap->user_heap.base, cygheap->user_heap.ptr,
468                   stack_here, ch.stackbottom,
469                   dll_data_start, dll_data_end,
470                   dll_bss_start, dll_bss_end, impure_beg, impure_end, NULL);
471
472   __malloc_unlock ();
473   locked = false;
474   MALLOC_CHECK;
475   if (!rc)
476     goto cleanup;
477
478   /* Now fill data/bss of any DLLs that were linked into the program. */
479   for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ())
480     {
481       debug_printf ("copying data/bss of a linked dll");
482       if (!fork_copy (pi, "linked dll data/bss", d->p.data_start, d->p.data_end,
483                                                  d->p.bss_start, d->p.bss_end,
484                                                  NULL))
485         {
486           this_errno = get_errno ();
487 #ifdef DEBUGGING
488           error = "child %d - fork_copy for linked dll data/bss failed";
489 #endif
490           goto cleanup;
491         }
492     }
493
494   /* Start thread, and wait for it to reload dlls.  */
495   if (!resume_child (forker_finished))
496     goto cleanup;
497   else if (!ch.sync (child->pid, pi.hProcess, FORK_WAIT_TIMEOUT))
498     {
499       this_errno = EAGAIN;
500       error = "child %d died waiting for dll loading";
501       goto cleanup;
502     }
503
504   /* If DLLs were loaded in the parent, then the child has reloaded all
505      of them and is now waiting to have all of the individual data and
506      bss sections filled in. */
507   if (load_dlls)
508     {
509       /* CHILD IS STOPPED */
510       /* write memory of reloaded dlls */
511       for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ())
512         {
513           debug_printf ("copying data/bss for a loaded dll");
514           if (!fork_copy (pi, "loaded dll data/bss", d->p.data_start, d->p.data_end,
515                                                      d->p.bss_start, d->p.bss_end,
516                                                      NULL))
517             {
518               this_errno = get_errno ();
519 #ifdef DEBUGGING
520               error = "child %d - copying data/bss for a loaded dll";
521 #endif
522               goto cleanup;
523             }
524         }
525       /* Start the child up again. */
526       resume_child (forker_finished);
527     }
528
529   ForceCloseHandle (pi.hThread);
530   ForceCloseHandle (forker_finished);
531   forker_finished = NULL;
532   pi.hThread = NULL;
533   pthread::atforkparent ();
534
535   return child_pid;
536
537 /* Common cleanup code for failure cases */
538 cleanup:
539   if (fix_impersonation)
540     cygheap->user.reimpersonate ();
541   if (locked)
542     __malloc_unlock ();
543
544   /* Remember to de-allocate the fd table. */
545   if (pi.hProcess && !child.hProcess)
546     ForceCloseHandle1 (pi.hProcess, childhProc);
547   if (pi.hThread)
548     ForceCloseHandle (pi.hThread);
549   if (forker_finished)
550     ForceCloseHandle (forker_finished);
551   debug_printf ("returning -1");
552   return -1;
553 }
554
555 extern "C" int
556 fork ()
557 {
558   frok grouped;
559   MALLOC_CHECK;
560
561   debug_printf ("entering");
562   grouped.first_dll = NULL;
563   grouped.load_dlls = 0;
564
565   void *esp;
566   __asm__ volatile ("movl %%esp,%0": "=r" (esp));
567
568   myself->set_has_pgid_children ();
569
570   if (grouped.ch.parent == NULL)
571     return -1;
572   if (grouped.ch.subproc_ready == NULL)
573     {
574       system_printf ("unable to allocate subproc_ready event, %E");
575       return -1;
576     }
577
578   sig_send (NULL, __SIGHOLD);
579   int res;
580   int ischild = setjmp (grouped.ch.jmp);
581   if (!ischild)
582     res = grouped.parent (esp);
583   else
584     res = grouped.child (esp);
585
586   MALLOC_CHECK;
587   if (ischild || res > 0)
588     /* everything is ok */;
589   else
590     {
591       if (!grouped.error)
592         syscall_printf ("fork failed - child pid %d", grouped.child_pid);
593       else
594         system_printf (grouped.error, grouped.child_pid);
595       set_errno (grouped.this_errno);
596     }
597   syscall_printf ("%d = fork()", res);
598   sig_send (NULL, __SIGNOHOLD);
599   return res;
600 }
601 #ifdef DEBUGGING
602 void
603 fork_init ()
604 {
605 }
606 #endif /*DEBUGGING*/
607
608 #ifdef NEWVFORK
609 /* Dummy function to force second assignment below to actually be
610    carried out */
611 static vfork_save *
612 get_vfork_val ()
613 {
614   return vfork_storage.val ();
615 }
616 #endif
617
618 extern "C" int
619 vfork ()
620 {
621 #ifndef NEWVFORK
622   debug_printf ("stub called");
623   return fork ();
624 #else
625   vfork_save *vf = get_vfork_val ();
626   char **esp, **pp;
627
628   if (vf == NULL)
629     vf = vfork_storage.create ();
630   else if (vf->pid)
631     return fork ();
632
633   // FIXME the tls stuff could introduce a signal race if a child process
634   // exits quickly.
635   if (!setjmp (vf->j))
636     {
637       vf->pid = -1;
638       __asm__ volatile ("movl %%esp,%0": "=r" (vf->vfork_esp):);
639       __asm__ volatile ("movl %%ebp,%0": "=r" (vf->vfork_ebp):);
640       for (pp = (char **) vf->frame, esp = vf->vfork_esp;
641            esp <= vf->vfork_ebp + 2; pp++, esp++)
642         *pp = *esp;
643       vf->ctty = myself->ctty;
644       vf->sid = myself->sid;
645       vf->pgid = myself->pgid;
646       cygheap->ctty_on_hold = cygheap->ctty;
647       vf->open_fhs = cygheap->open_fhs;
648       debug_printf ("cygheap->ctty_on_hold %p, cygheap->open_fhs %d", cygheap->ctty_on_hold, cygheap->open_fhs);
649       int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
650       debug_printf ("%d = vfork()", res);
651       _my_tls.call_signal_handler ();   // FIXME: racy
652       vf->tls = _my_tls;
653       return res;
654     }
655
656   vf = get_vfork_val ();
657
658   for (pp = (char **) vf->frame, esp = vf->vfork_esp;
659        esp <= vf->vfork_ebp + 2; pp++, esp++)
660     *esp = *pp;
661
662   cygheap->fdtab.vfork_parent_restore ();
663
664   myself->ctty = vf->ctty;
665   myself->sid = vf->sid;
666   myself->pgid = vf->pgid;
667   termios_printf ("cygheap->ctty %p, cygheap->ctty_on_hold %p", cygheap->ctty, cygheap->ctty_on_hold);
668   cygheap->open_fhs = vf->open_fhs;
669
670   if (vf->pid < 0)
671     {
672       int exitval = vf->exitval;
673       vf->pid = 0;
674       if ((vf->pid = fork ()) == 0)
675         exit (exitval);
676     }
677
678   int pid = vf->pid;
679   vf->pid = 0;
680   debug_printf ("exiting vfork, pid %d", pid);
681   sig_dispatch_pending ();
682
683   _my_tls.call_signal_handler ();       // FIXME: racy
684   _my_tls = vf->tls;
685   return pid;
686 #endif
687 }
688
689 int
690 child_copy (HANDLE h, DWORD pid, const char *what, void *child_start, void *child_end)
691 {
692   PROCESS_INFORMATION pi;
693   pi.hProcess = h;
694   pi.dwProcessId = pid;
695   pi.hThread = NULL;
696   debug_printf ("%s, start %p, end %p", what, child_start, child_end);
697   return fork_copy (pi, what, child_start, child_end, NULL);
698 }