summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/dcrt0.cc
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-12-29 20:46:34 +0000
committerChristopher Faylor <me@cgf.cx>2005-12-29 20:46:34 +0000
commit5d97040501505d37b01268fdf335ef6ea2bafb44 (patch)
tree2764464e535cc8ec94122a853743e5583f2b0c95 /winsup/cygwin/dcrt0.cc
parent10e4168d8441980eeec3a5d3ce7f5a6052c3ee27 (diff)
downloadcygnal-5d97040501505d37b01268fdf335ef6ea2bafb44.tar.gz
cygnal-5d97040501505d37b01268fdf335ef6ea2bafb44.tar.bz2
cygnal-5d97040501505d37b01268fdf335ef6ea2bafb44.zip
*** cygwin DLL Changes:
* child_info.h (CURR_CHILD_INFO_MAGIC): Reset. (child_info::dwProcessId): Delete. (child_info::straced): New variable. (child_info::handle_fork): New member function. * dcrt0.cc (in_forkee): New global variable. (__cygwin_user_data::forkee): Mark as obsolete. (do_global_ctors): Use in_forkee rather than user_data->forkee. (get_cygwin_startup_info): Ditto. Deal with new straced field to allow strace to deal with children of attached processes. (initial_env): Accommodate changes to strace::hello. (child_info_fork::handle_fork): Rename from plain old 'handle_fork'. Move alloc_stack() call elsewhere. (dll_crt0_0): Fill out more of user_data. Reference handle_fork via fork_info. Add some debugging output. (_dll_crt0): Don't wait for sync thread if sync_startup is invalid. Zero sync_startup here. Call alloc_stack() here, if appropriate. (dll_crt0_1): Use in_forkee rather than user_data->forkee. (dll_crt0): Ditto. * malloc_wrapper.cc (malloc_init): Ditto. * dll_init.cc (in_forkee): Remove local static version of this variable. (dll_list::load_after_fork): Don't set in_forkee here. * external.cc (cygwin_internal): Use strace method rather than accessing field directly. * fhandler.cc (fhandler_base::read): Ditto. * fhandler_tty.cc (fhandler_tty_common::__acquire_output_mutex): Ditto. * fork.cc (frok::parent): Invoke strace write_childpid to communicate with potential strace. (child_copy): Add more detail to debugging output. * init.cc (calibration_id): New static variable. (prime_threads): Set sync_startup to invalid handle if we already know about thread_func_ix. Use static calibration_id to hold calibration thread id. * munge_threadfunc (munge_threadfunc): Don't try to debug if we don't find threadfunc_ix. (dll_entry): Avoid calling munge_threadfunc and _cygtls::remove on non-cygwin threads invoked during process startup. * pinfo.cc (set_myself): Always call strace.hello here regardless of DEBUGGING. * sigproc.cc (child_info::child_info): Remove spurious handling of dwProcessId. Set straced as appropriate. * spawn.cc (spawn_guts): Rename ciresrv to ch. Invoke strace write_childpid to communicate with potential strace. * strace.cc: Include child_info.h. (strace::hello): Remove inited test. Use active() method to test if strace has been activated. Handle case where we are started before (mypid): New function. (strace::vsprntf): Try to deal more intelligently with case where progname may not be filled out. Put pid in parentheses if it is a windows pid rather than a cygwin pid. myself has been filled out. (strace::write_childpid): New function for notifying strace about the creation of children. (strace::vprntf): Use strace method rather than accessing field directly. (strace_printf): Ditto. (strace::wm): Ditto. * winsup.h (in_forkee): Declare. * include/sys/strace.h (strace::write_childpid): Declare new function. (strace::attached): Define new function. (strace::active): Ditto. (strace::active_val): Ditto. (_STRACE_ON): Delete. (_STRACE_OFF): Ditto. (define_strace0): Use strace method rather than accessing field directly. (strace_printf_wrap): Ditto. (strace_printf_wrap1): Ditto. *** cygwin utils changes: * strace.cc (nprocesses): Make static global. (quiet): New variable. (strace_active): Ditto. (add_child): Increment nprocesses here. Don't add a child if it is already added (windows bug?). Report on child if not quiet. (get_child): Just return NULL if child not found. (remove_child): Report on child if not quiet. (attach_process): Don't complain if given a windows process. Use windows pid in error. (handle_output_debug_string): Issue error if trying to manipulate a process that we don't know about. Handle _STRACE_CHILD_PID - attach to reported child when we get this. (proc_child): Move nprocesses to file scope. Report on exceptions. (longopts): Implement "--quiet". (opts): Implement "-q". (main): Manipulate quiet flag. * utils.sgml (strace): Add words describing '-q'.
Diffstat (limited to 'winsup/cygwin/dcrt0.cc')
-rw-r--r--winsup/cygwin/dcrt0.cc64
1 files changed, 37 insertions, 27 deletions
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 6e0b765b8..04bef6e56 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -53,6 +53,7 @@ muto NO_COPY lock_process::locker;
bool display_title;
bool strip_title_path;
bool allow_glob = true;
+bool NO_COPY in_forkee;
codepage_type current_codepage = ansi_cp;
int __argc_safe;
@@ -108,7 +109,7 @@ extern "C"
/* premain */ {NULL, NULL, NULL, NULL},
/* run_ctors_p */ 0,
/* unused */ {0, 0, 0, 0, 0, 0, 0},
- /* forkee */ 0,
+ /* UNUSED forkee */ 0,
/* hmodule */ NULL,
/* api_major */ CYGWIN_VERSION_API_MAJOR,
/* api_minor */ CYGWIN_VERSION_API_MINOR,
@@ -141,7 +142,7 @@ do_global_dtors ()
static void __stdcall
do_global_ctors (void (**in_pfunc)(), int force)
{
- if (!force && user_data->forkee)
+ if (!force && in_forkee)
return; // inherit constructed stuff from parent pid
/* Run ctors backwards, so skip the first entry and find how many
@@ -554,11 +555,8 @@ initial_env ()
len = GetModuleFileName (NULL, buf, CYG_MAX_PATH);
console_printf ("Sleeping %d, pid %u %s\n", ms, GetCurrentProcessId (), buf);
Sleep (ms);
- if (!strace.active && !dynamically_loaded)
- {
- strace.inited = 0;
- strace.hello ();
- }
+ if (!strace.active () && !dynamically_loaded)
+ strace.hello ();
}
if (GetEnvironmentVariable ("CYGWIN_DEBUG", buf, sizeof (buf) - 1))
{
@@ -611,7 +609,7 @@ get_cygwin_startup_info ()
switch (res->type)
{
case _PROC_FORK:
- user_data->forkee = true;
+ in_forkee = true;
should_be_cb = sizeof (child_info_fork);
/* fall through */;
case _PROC_SPAWN:
@@ -622,6 +620,20 @@ get_cygwin_startup_info ()
multiple_cygwin_problem ("proc size", res->cb, should_be_cb);
else if (sizeof (fhandler_union) != res->fhandler_union_cb)
multiple_cygwin_problem ("fhandler size", res->fhandler_union_cb, sizeof (fhandler_union));
+ if (res->straced)
+ {
+ res->ready (false);
+#if 0
+ DWORD prio = GetThreadPriority (GetCurrentThread ());
+ SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
+#endif
+ for (unsigned i = 0; !being_debugged () && i < 10000; i++)
+ low_priority_sleep (0);
+#if 0
+ SetThreadPriority (GetCurrentThread (), prio);
+#endif
+ strace.hello ();
+ }
break;
default:
system_printf ("unknown exec type %d", res->type);
@@ -641,26 +653,24 @@ get_cygwin_startup_info ()
#define dll_bss_end &_bss_end__
void
-handle_fork ()
+child_info_fork::handle_fork ()
{
- alloc_stack (fork_info);
cygheap_fixup_in_child (false);
memory_init ();
set_myself (NULL);
- HANDLE hp = fork_info->parent;
- child_copy (hp, false,
+ child_copy (parent, false,
"dll data", dll_data_start, dll_data_end,
"dll bss", dll_bss_start, dll_bss_end,
"user heap", cygheap->user_heap.base, cygheap->user_heap.ptr,
NULL);
/* step 2 now that the dll has its heap filled in, we can fill in the
user's data and bss since user_data is now filled out. */
- child_copy (hp, false,
+ child_copy (parent, false,
"data", user_data->data_start, user_data->data_end,
"bss", user_data->bss_start, user_data->bss_end,
NULL);
- if (fixup_mmaps_after_fork (hp))
+ if (fixup_mmaps_after_fork (parent))
api_fatal ("recreate_mmaps_after_fork_failed");
}
@@ -675,6 +685,8 @@ dll_crt0_0 ()
_impure_ptr->_stdout = &_impure_ptr->__sf[1];
_impure_ptr->_stderr = &_impure_ptr->__sf[2];
_impure_ptr->_current_locale = "C";
+ user_data->impure_ptr = _impure_ptr;
+ user_data->impure_ptr_ptr = &_impure_ptr;
wincap.init ();
initial_env ();
mmap_init ();
@@ -690,7 +702,6 @@ dll_crt0_0 ()
OpenProcessToken (hMainProc, MAXIMUM_ALLOWED, &hProcToken);
SetErrorMode (SEM_FAILCRITICALERRORS);
-
device::init ();
do_global_ctors (&__CTOR_LIST__, 1);
cygthread::init ();
@@ -704,7 +715,7 @@ dll_crt0_0 ()
switch (child_proc_info->type)
{
case _PROC_FORK:
- handle_fork ();
+ fork_info->handle_fork ();
break;
case _PROC_SPAWN:
case _PROC_EXEC:
@@ -747,6 +758,7 @@ dll_crt0_0 ()
DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenImpersonation,
&hProcImpToken);
+ debug_printf ("finished dll_crt0_0 initialization");
}
/* Take over from libc's crt0.o and start the application. Note the
@@ -772,7 +784,7 @@ dll_crt0_1 (char *)
/* Initialize pthread mainthread when not forked and it is safe to call new,
otherwise it is reinitalized in fixup_after_fork */
- if (!user_data->forkee)
+ if (!in_forkee)
pthread::init_mainthread ();
#ifdef DEBUGGING
@@ -791,7 +803,7 @@ dll_crt0_1 (char *)
#endif
cygbench ("pre-forkee");
- if (user_data->forkee)
+ if (in_forkee)
{
/* If we've played with the stack, stacksize != 0. That means that
fork() was invoked from other than the main thread. Make sure that
@@ -946,18 +958,15 @@ initialize_main_tls (char *padding)
extern "C" void __stdcall
_dll_crt0 ()
{
+ extern DWORD threadfunc_ix;
extern HANDLE sync_startup;
- extern unsigned threadfunc_ix;
- if (threadfunc_ix)
- /* nothing to do */;
- else if (!sync_startup)
- system_printf ("internal error: sync_startup not called at start. Expect signal problems.");
- else
+ if (sync_startup != INVALID_HANDLE_VALUE)
{
WaitForSingleObject (sync_startup, INFINITE);
CloseHandle (sync_startup);
}
+ sync_startup = NULL;
if (!threadfunc_ix)
system_printf ("internal error: couldn't determine location of thread function on stack. Expect signal problems.");
@@ -968,8 +977,9 @@ _dll_crt0 ()
char padding[CYGTLS_PADSIZE];
- if (child_proc_info && child_proc_info->type == _PROC_FORK)
- user_data->forkee = true;
+debug_printf ("in_forkee %d, fork_info %p", in_forkee, fork_info);
+ if (in_forkee)
+ alloc_stack (fork_info);
else
__sinit (_impure_ptr);
@@ -981,7 +991,7 @@ void
dll_crt0 (per_process *uptr)
{
/* Set the local copy of the pointer into the user space. */
- if (!user_data->forkee && uptr && uptr != user_data)
+ if (!in_forkee && uptr && uptr != user_data)
{
memcpy (user_data, uptr, per_process_overwrite);
*(user_data->impure_ptr_ptr) = _GLOBAL_REENT;