From 5d97040501505d37b01268fdf335ef6ea2bafb44 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 29 Dec 2005 20:46:34 +0000 Subject: *** 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'. --- winsup/cygwin/strace.cc | 87 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 26 deletions(-) (limited to 'winsup/cygwin/strace.cc') diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc index 6634a68dd..9e5929632 100644 --- a/winsup/cygwin/strace.cc +++ b/winsup/cygwin/strace.cc @@ -25,6 +25,7 @@ details. */ #include "fhandler.h" #include "dtable.h" #include "cygheap.h" +#include "child_info.h" #define PROTECT(x) x[sizeof (x)-1] = 0 #define CHECK(x) if (x[sizeof (x)-1] != 0) { small_printf ("array bound exceeded %d\n", __LINE__); ExitProcess (1); } @@ -36,27 +37,25 @@ class strace NO_COPY strace; void strace::hello () { - char buf[30]; - - if (inited) - { - active ^= 1; - return; - } - - inited = 1; - if (!being_debugged ()) + if (_active || !being_debugged ()) return; - __small_sprintf (buf, "cYg%8x %x", _STRACE_INTERFACE_ACTIVATE_ADDR, &active); + char buf[30]; + __small_sprintf (buf, "cYg%8x %x", _STRACE_INTERFACE_ACTIVATE_ADDR, &_active); OutputDebugString (buf); - if (active) + if (active ()) { + char pidbuf[40]; + if (myself->progname[0]) + __small_sprintf (pidbuf, "(pid %d, ppid %d)", myself->pid, myself->ppid ?: 1); + else + { + GetModuleFileName (NULL, myself->progname, sizeof (myself->progname)); + __small_sprintf (pidbuf, "(windows pid %d)", GetCurrentProcessId ()); + } prntf (1, NULL, "**********************************************"); - prntf (1, NULL, "Program name: %s (pid %d, ppid %d)", myself->progname, - myself->pid ?: GetCurrentProcessId (), - myself->ppid ?: 1); + prntf (1, NULL, "Program name: %s %s", myself->progname, pidbuf); prntf (1, NULL, "App version: %d.%d, api: %d.%d", user_data->dll_major, user_data->dll_minor, user_data->api_major, user_data->api_minor); @@ -65,7 +64,8 @@ strace::hello () cygwin_version.api_major, cygwin_version.api_minor); prntf (1, NULL, "DLL build: %s", cygwin_version.dll_build_date); prntf (1, NULL, "OS version: Windows %s", wincap.osname ()); - prntf (1, NULL, "Heap size: %u", cygheap->user_heap.chunk); + if (cygheap) + prntf (1, NULL, "Heap size: %u", cygheap->user_heap.chunk); prntf (1, NULL, "**********************************************"); } } @@ -111,6 +111,16 @@ getfunc (char *in_dst, const char *func) return dst - in_dst; } +static char * +mypid (char *buf) +{ + if (myself && myself->pid) + __small_sprintf (buf, "%d", myself->pid); + else + __small_sprintf (buf, "(%d)", cygwin_pid (GetCurrentProcessId ())); + return buf; +} + extern "C" char *__progname; /* sprintf analog for use by output routines. */ @@ -122,12 +132,11 @@ strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap) static NO_COPY bool nonewline = false; DWORD err = GetLastError (); const char *tn = cygthread::name (); - char *pn = __progname ?: (myself ? myself->progname : NULL); int microsec = microseconds (); lmicrosec = microsec; - __small_sprintf (fmt, "%7d [%s] %s ", microsec, tn, "%s %d%s"); + __small_sprintf (fmt, "%7d [%s] %s ", microsec, tn, "%s %s%s"); SetLastError (err); @@ -135,21 +144,33 @@ strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap) count = 0; else { - char *p, progname[CYG_MAX_PATH]; + char *pn; + if (!cygwin_finished_initializing) + pn = myself ? myself->progname : NULL; + else if (__progname) + pn = __progname; + else + pn = NULL; + + char *p; + char progname[CYG_MAX_PATH]; if (!pn) - p = (char *) "*** unknown ***"; + GetModuleFileName (NULL, pn = progname, sizeof (progname)); + if (!pn) + /* hmm */; else if ((p = strrchr (pn, '\\')) != NULL) p++; else if ((p = strrchr (pn, '/')) != NULL) p++; else p = pn; - strcpy (progname, p); + if (p != progname) + strcpy (progname, p); if ((p = strrchr (progname, '.')) != NULL && strcasematch (p, ".exe")) *p = '\000'; p = progname; - count = __small_sprintf (buf, fmt, p && *p ? p : "?", - (myself && myself->pid) ? myself->pid : GetCurrentProcessId (), + char tmpbuf[20]; + count = __small_sprintf (buf, fmt, p && *p ? p : "?", mypid (tmpbuf), execing ? "!" : ""); if (func) count += getfunc (buf + count, func); @@ -195,6 +216,20 @@ strace::write (unsigned category, const char *buf, int count) #undef PREFIX } +void +strace::write_childpid (child_info& ch, DWORD pid) +{ + char buf[30]; + + if (!attached () || !being_debugged ()) + return; +int res = + WaitForSingleObject (ch.subproc_ready, 30000); +do { if ((0x00040 & 0x08000) || active ()) prntf (0x00040, __PRETTY_FUNCTION__, "res %d", res); } while (0); + __small_sprintf (buf, "cYg%8x %x", _STRACE_CHILD_PID, pid); + OutputDebugString (buf); +} + /* Printf function used when tracing system calls. Warning: DO NOT SET ERRNO HERE! */ @@ -229,7 +264,7 @@ strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap } #ifndef NOSTRACE - if (active) + if (active ()) write (category, buf, len); #endif SetLastError (err); @@ -249,7 +284,7 @@ strace_printf (unsigned category, const char *func, const char *fmt, ...) { va_list ap; - if ((category & _STRACE_SYSTEM) || strace.active) + if ((category & _STRACE_SYSTEM) || strace.active ()) { va_start (ap, fmt); strace.vprntf (category, func, fmt, ap); @@ -417,7 +452,7 @@ ta[] = void strace::wm (int message, int word, int lon) { - if (active) + if (active ()) { int i; -- cgit v1.2.3