*** 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'.
This commit is contained in:
parent
10e4168d84
commit
5d97040501
|
@ -1,3 +1,73 @@
|
||||||
|
2005-12-29 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2005-12-28 Christopher Faylor <cgf@timesys.com>
|
2005-12-28 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* environ.cc (win_env::add_cache): Don't add variables to the
|
* environ.cc (win_env::add_cache): Don't add variables to the
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum child_info_types
|
||||||
|
|
||||||
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
||||||
|
|
||||||
#define CURR_CHILD_INFO_MAGIC 0xb530a54dU
|
#define CURR_CHILD_INFO_MAGIC 0xc87757a7U
|
||||||
|
|
||||||
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
||||||
below class. The layout is checksummed to determine compatibility between
|
below class. The layout is checksummed to determine compatibility between
|
||||||
|
@ -48,7 +48,7 @@ public:
|
||||||
init_cygheap *cygheap;
|
init_cygheap *cygheap;
|
||||||
void *cygheap_max;
|
void *cygheap_max;
|
||||||
DWORD cygheap_reserve_sz;
|
DWORD cygheap_reserve_sz;
|
||||||
DWORD dwProcessId;
|
unsigned char straced;
|
||||||
unsigned fhandler_union_cb;
|
unsigned fhandler_union_cb;
|
||||||
child_info (unsigned, child_info_types, bool);
|
child_info (unsigned, child_info_types, bool);
|
||||||
child_info (): subproc_ready (NULL), parent (NULL) {}
|
child_info (): subproc_ready (NULL), parent (NULL) {}
|
||||||
|
@ -69,6 +69,7 @@ public:
|
||||||
void *stacktop; // location of top of parent stack
|
void *stacktop; // location of top of parent stack
|
||||||
void *stackbottom; // location of bottom of parent stack
|
void *stackbottom; // location of bottom of parent stack
|
||||||
child_info_fork ();
|
child_info_fork ();
|
||||||
|
void handle_fork ();
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_base;
|
class fhandler_base;
|
||||||
|
|
|
@ -147,7 +147,7 @@ void
|
||||||
_cygtls::remove (DWORD wait)
|
_cygtls::remove (DWORD wait)
|
||||||
{
|
{
|
||||||
debug_printf ("wait %p", wait);
|
debug_printf ("wait %p", wait);
|
||||||
if (!locals.exitsock || exit_state >= ES_FINAL)
|
if (1 || !isinitialized () || !locals.exitsock || exit_state >= ES_FINAL)
|
||||||
return;
|
return;
|
||||||
if (wait)
|
if (wait)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,7 @@ muto NO_COPY lock_process::locker;
|
||||||
bool display_title;
|
bool display_title;
|
||||||
bool strip_title_path;
|
bool strip_title_path;
|
||||||
bool allow_glob = true;
|
bool allow_glob = true;
|
||||||
|
bool NO_COPY in_forkee;
|
||||||
codepage_type current_codepage = ansi_cp;
|
codepage_type current_codepage = ansi_cp;
|
||||||
|
|
||||||
int __argc_safe;
|
int __argc_safe;
|
||||||
|
@ -108,7 +109,7 @@ extern "C"
|
||||||
/* premain */ {NULL, NULL, NULL, NULL},
|
/* premain */ {NULL, NULL, NULL, NULL},
|
||||||
/* run_ctors_p */ 0,
|
/* run_ctors_p */ 0,
|
||||||
/* unused */ {0, 0, 0, 0, 0, 0, 0},
|
/* unused */ {0, 0, 0, 0, 0, 0, 0},
|
||||||
/* forkee */ 0,
|
/* UNUSED forkee */ 0,
|
||||||
/* hmodule */ NULL,
|
/* hmodule */ NULL,
|
||||||
/* api_major */ CYGWIN_VERSION_API_MAJOR,
|
/* api_major */ CYGWIN_VERSION_API_MAJOR,
|
||||||
/* api_minor */ CYGWIN_VERSION_API_MINOR,
|
/* api_minor */ CYGWIN_VERSION_API_MINOR,
|
||||||
|
@ -141,7 +142,7 @@ do_global_dtors ()
|
||||||
static void __stdcall
|
static void __stdcall
|
||||||
do_global_ctors (void (**in_pfunc)(), int force)
|
do_global_ctors (void (**in_pfunc)(), int force)
|
||||||
{
|
{
|
||||||
if (!force && user_data->forkee)
|
if (!force && in_forkee)
|
||||||
return; // inherit constructed stuff from parent pid
|
return; // inherit constructed stuff from parent pid
|
||||||
|
|
||||||
/* Run ctors backwards, so skip the first entry and find how many
|
/* 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);
|
len = GetModuleFileName (NULL, buf, CYG_MAX_PATH);
|
||||||
console_printf ("Sleeping %d, pid %u %s\n", ms, GetCurrentProcessId (), buf);
|
console_printf ("Sleeping %d, pid %u %s\n", ms, GetCurrentProcessId (), buf);
|
||||||
Sleep (ms);
|
Sleep (ms);
|
||||||
if (!strace.active && !dynamically_loaded)
|
if (!strace.active () && !dynamically_loaded)
|
||||||
{
|
strace.hello ();
|
||||||
strace.inited = 0;
|
|
||||||
strace.hello ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (GetEnvironmentVariable ("CYGWIN_DEBUG", buf, sizeof (buf) - 1))
|
if (GetEnvironmentVariable ("CYGWIN_DEBUG", buf, sizeof (buf) - 1))
|
||||||
{
|
{
|
||||||
|
@ -611,7 +609,7 @@ get_cygwin_startup_info ()
|
||||||
switch (res->type)
|
switch (res->type)
|
||||||
{
|
{
|
||||||
case _PROC_FORK:
|
case _PROC_FORK:
|
||||||
user_data->forkee = true;
|
in_forkee = true;
|
||||||
should_be_cb = sizeof (child_info_fork);
|
should_be_cb = sizeof (child_info_fork);
|
||||||
/* fall through */;
|
/* fall through */;
|
||||||
case _PROC_SPAWN:
|
case _PROC_SPAWN:
|
||||||
|
@ -622,6 +620,20 @@ get_cygwin_startup_info ()
|
||||||
multiple_cygwin_problem ("proc size", res->cb, should_be_cb);
|
multiple_cygwin_problem ("proc size", res->cb, should_be_cb);
|
||||||
else if (sizeof (fhandler_union) != res->fhandler_union_cb)
|
else if (sizeof (fhandler_union) != res->fhandler_union_cb)
|
||||||
multiple_cygwin_problem ("fhandler size", res->fhandler_union_cb, sizeof (fhandler_union));
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
system_printf ("unknown exec type %d", res->type);
|
system_printf ("unknown exec type %d", res->type);
|
||||||
|
@ -641,26 +653,24 @@ get_cygwin_startup_info ()
|
||||||
#define dll_bss_end &_bss_end__
|
#define dll_bss_end &_bss_end__
|
||||||
|
|
||||||
void
|
void
|
||||||
handle_fork ()
|
child_info_fork::handle_fork ()
|
||||||
{
|
{
|
||||||
alloc_stack (fork_info);
|
|
||||||
cygheap_fixup_in_child (false);
|
cygheap_fixup_in_child (false);
|
||||||
memory_init ();
|
memory_init ();
|
||||||
set_myself (NULL);
|
set_myself (NULL);
|
||||||
HANDLE hp = fork_info->parent;
|
child_copy (parent, false,
|
||||||
child_copy (hp, false,
|
|
||||||
"dll data", dll_data_start, dll_data_end,
|
"dll data", dll_data_start, dll_data_end,
|
||||||
"dll bss", dll_bss_start, dll_bss_end,
|
"dll bss", dll_bss_start, dll_bss_end,
|
||||||
"user heap", cygheap->user_heap.base, cygheap->user_heap.ptr,
|
"user heap", cygheap->user_heap.base, cygheap->user_heap.ptr,
|
||||||
NULL);
|
NULL);
|
||||||
/* step 2 now that the dll has its heap filled in, we can fill in the
|
/* 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. */
|
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,
|
"data", user_data->data_start, user_data->data_end,
|
||||||
"bss", user_data->bss_start, user_data->bss_end,
|
"bss", user_data->bss_start, user_data->bss_end,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (fixup_mmaps_after_fork (hp))
|
if (fixup_mmaps_after_fork (parent))
|
||||||
api_fatal ("recreate_mmaps_after_fork_failed");
|
api_fatal ("recreate_mmaps_after_fork_failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,6 +685,8 @@ dll_crt0_0 ()
|
||||||
_impure_ptr->_stdout = &_impure_ptr->__sf[1];
|
_impure_ptr->_stdout = &_impure_ptr->__sf[1];
|
||||||
_impure_ptr->_stderr = &_impure_ptr->__sf[2];
|
_impure_ptr->_stderr = &_impure_ptr->__sf[2];
|
||||||
_impure_ptr->_current_locale = "C";
|
_impure_ptr->_current_locale = "C";
|
||||||
|
user_data->impure_ptr = _impure_ptr;
|
||||||
|
user_data->impure_ptr_ptr = &_impure_ptr;
|
||||||
wincap.init ();
|
wincap.init ();
|
||||||
initial_env ();
|
initial_env ();
|
||||||
mmap_init ();
|
mmap_init ();
|
||||||
|
@ -690,7 +702,6 @@ dll_crt0_0 ()
|
||||||
OpenProcessToken (hMainProc, MAXIMUM_ALLOWED, &hProcToken);
|
OpenProcessToken (hMainProc, MAXIMUM_ALLOWED, &hProcToken);
|
||||||
|
|
||||||
SetErrorMode (SEM_FAILCRITICALERRORS);
|
SetErrorMode (SEM_FAILCRITICALERRORS);
|
||||||
|
|
||||||
device::init ();
|
device::init ();
|
||||||
do_global_ctors (&__CTOR_LIST__, 1);
|
do_global_ctors (&__CTOR_LIST__, 1);
|
||||||
cygthread::init ();
|
cygthread::init ();
|
||||||
|
@ -704,7 +715,7 @@ dll_crt0_0 ()
|
||||||
switch (child_proc_info->type)
|
switch (child_proc_info->type)
|
||||||
{
|
{
|
||||||
case _PROC_FORK:
|
case _PROC_FORK:
|
||||||
handle_fork ();
|
fork_info->handle_fork ();
|
||||||
break;
|
break;
|
||||||
case _PROC_SPAWN:
|
case _PROC_SPAWN:
|
||||||
case _PROC_EXEC:
|
case _PROC_EXEC:
|
||||||
|
@ -747,6 +758,7 @@ dll_crt0_0 ()
|
||||||
DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
|
DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
|
||||||
SecurityImpersonation, TokenImpersonation,
|
SecurityImpersonation, TokenImpersonation,
|
||||||
&hProcImpToken);
|
&hProcImpToken);
|
||||||
|
debug_printf ("finished dll_crt0_0 initialization");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take over from libc's crt0.o and start the application. Note the
|
/* 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,
|
/* Initialize pthread mainthread when not forked and it is safe to call new,
|
||||||
otherwise it is reinitalized in fixup_after_fork */
|
otherwise it is reinitalized in fixup_after_fork */
|
||||||
if (!user_data->forkee)
|
if (!in_forkee)
|
||||||
pthread::init_mainthread ();
|
pthread::init_mainthread ();
|
||||||
|
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
|
@ -791,7 +803,7 @@ dll_crt0_1 (char *)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cygbench ("pre-forkee");
|
cygbench ("pre-forkee");
|
||||||
if (user_data->forkee)
|
if (in_forkee)
|
||||||
{
|
{
|
||||||
/* If we've played with the stack, stacksize != 0. That means that
|
/* If we've played with the stack, stacksize != 0. That means that
|
||||||
fork() was invoked from other than the main thread. Make sure 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
|
extern "C" void __stdcall
|
||||||
_dll_crt0 ()
|
_dll_crt0 ()
|
||||||
{
|
{
|
||||||
|
extern DWORD threadfunc_ix;
|
||||||
extern HANDLE sync_startup;
|
extern HANDLE sync_startup;
|
||||||
extern unsigned threadfunc_ix;
|
if (sync_startup != INVALID_HANDLE_VALUE)
|
||||||
if (threadfunc_ix)
|
|
||||||
/* nothing to do */;
|
|
||||||
else if (!sync_startup)
|
|
||||||
system_printf ("internal error: sync_startup not called at start. Expect signal problems.");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
WaitForSingleObject (sync_startup, INFINITE);
|
WaitForSingleObject (sync_startup, INFINITE);
|
||||||
CloseHandle (sync_startup);
|
CloseHandle (sync_startup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sync_startup = NULL;
|
||||||
if (!threadfunc_ix)
|
if (!threadfunc_ix)
|
||||||
system_printf ("internal error: couldn't determine location of thread function on stack. Expect signal problems.");
|
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];
|
char padding[CYGTLS_PADSIZE];
|
||||||
|
|
||||||
if (child_proc_info && child_proc_info->type == _PROC_FORK)
|
debug_printf ("in_forkee %d, fork_info %p", in_forkee, fork_info);
|
||||||
user_data->forkee = true;
|
if (in_forkee)
|
||||||
|
alloc_stack (fork_info);
|
||||||
else
|
else
|
||||||
__sinit (_impure_ptr);
|
__sinit (_impure_ptr);
|
||||||
|
|
||||||
|
@ -981,7 +991,7 @@ void
|
||||||
dll_crt0 (per_process *uptr)
|
dll_crt0 (per_process *uptr)
|
||||||
{
|
{
|
||||||
/* Set the local copy of the pointer into the user space. */
|
/* 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);
|
memcpy (user_data, uptr, per_process_overwrite);
|
||||||
*(user_data->impure_ptr_ptr) = _GLOBAL_REENT;
|
*(user_data->impure_ptr_ptr) = _GLOBAL_REENT;
|
||||||
|
|
|
@ -23,7 +23,6 @@ extern void __stdcall check_sanity_and_sync (per_process *);
|
||||||
|
|
||||||
dll_list NO_COPY dlls;
|
dll_list NO_COPY dlls;
|
||||||
|
|
||||||
static int NO_COPY in_forkee;
|
|
||||||
static bool dll_global_dtors_recorded;
|
static bool dll_global_dtors_recorded;
|
||||||
|
|
||||||
/* Run destructors for all DLLs on exit. */
|
/* Run destructors for all DLLs on exit. */
|
||||||
|
@ -283,7 +282,6 @@ release_upto (const char *name, DWORD here)
|
||||||
void
|
void
|
||||||
dll_list::load_after_fork (HANDLE parent, dll *first)
|
dll_list::load_after_fork (HANDLE parent, dll *first)
|
||||||
{
|
{
|
||||||
in_forkee = 1;
|
|
||||||
int try2 = 0;
|
int try2 = 0;
|
||||||
dll d;
|
dll d;
|
||||||
|
|
||||||
|
@ -346,7 +344,7 @@ dll_list::load_after_fork (HANDLE parent, dll *first)
|
||||||
}
|
}
|
||||||
next = d.next; /* Get the address of the next DLL. */
|
next = d.next; /* Get the address of the next DLL. */
|
||||||
}
|
}
|
||||||
in_forkee = 0;
|
in_forkee = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
|
|
|
@ -218,7 +218,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
||||||
|
|
||||||
case CW_STRACE_ACTIVE:
|
case CW_STRACE_ACTIVE:
|
||||||
{
|
{
|
||||||
return strace.active;
|
return strace.active ();
|
||||||
}
|
}
|
||||||
|
|
||||||
case CW_CYGWIN_PID_TO_WINPID:
|
case CW_CYGWIN_PID_TO_WINPID:
|
||||||
|
|
|
@ -772,7 +772,7 @@ fhandler_base::read (void *in_ptr, size_t& len)
|
||||||
len = dst - (char *) ptr;
|
len = dst - (char *) ptr;
|
||||||
|
|
||||||
#ifndef NOSTRACE
|
#ifndef NOSTRACE
|
||||||
if (strace.active)
|
if (strace.active ())
|
||||||
{
|
{
|
||||||
char buf[16 * 6 + 1];
|
char buf[16 * 6 + 1];
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
|
|
|
@ -112,7 +112,7 @@ DWORD
|
||||||
fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln,
|
fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln,
|
||||||
DWORD ms)
|
DWORD ms)
|
||||||
{
|
{
|
||||||
if (strace.active)
|
if (strace.active ())
|
||||||
strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex: waiting %d ms", ln, ms);
|
strace.prntf (_STRACE_TERMIOS, fn, "(%d): tty output_mutex: waiting %d ms", ln, ms);
|
||||||
DWORD res = WaitForSingleObject (output_mutex, ms);
|
DWORD res = WaitForSingleObject (output_mutex, ms);
|
||||||
if (res == WAIT_OBJECT_0)
|
if (res == WAIT_OBJECT_0)
|
||||||
|
|
|
@ -307,12 +307,14 @@ frok::parent (void *stack_here)
|
||||||
|
|
||||||
/* Fixup the parent datastructure if needed and resume the child's
|
/* Fixup the parent datastructure if needed and resume the child's
|
||||||
main thread. */
|
main thread. */
|
||||||
if (cygheap->fdtab.need_fixup_before ())
|
if (c_flags & CREATE_SUSPENDED)
|
||||||
{
|
{
|
||||||
cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
|
cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
|
||||||
ResumeThread (pi.hThread);
|
ResumeThread (pi.hThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strace.write_childpid (ch, pi.dwProcessId);
|
||||||
|
|
||||||
child_pid = cygwin_pid (pi.dwProcessId);
|
child_pid = cygwin_pid (pi.dwProcessId);
|
||||||
child.init (child_pid, 1, NULL);
|
child.init (child_pid, 1, NULL);
|
||||||
|
|
||||||
|
@ -662,7 +664,7 @@ child_copy (HANDLE hp, bool write, ...)
|
||||||
res = WriteProcessMemory (hp, here, here, todo, &done);
|
res = WriteProcessMemory (hp, here, here, todo, &done);
|
||||||
else
|
else
|
||||||
res = ReadProcessMemory (hp, here, here, todo, &done);
|
res = ReadProcessMemory (hp, here, here, todo, &done);
|
||||||
debug_printf ("hp %p, low %p, high %p, res %d", hp, low, high, res);
|
debug_printf ("%s - hp %p low %p, high %p, res %d", what, hp, low, high, res);
|
||||||
if (!res || todo != done)
|
if (!res || todo != done)
|
||||||
{
|
{
|
||||||
if (!res)
|
if (!res)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* sys/strace.h
|
/* sys/strace.h
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
|
2005 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -8,8 +9,6 @@ This software is a copyrighted work licensed under the terms of the
|
||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
/* sys/strace.h */
|
|
||||||
|
|
||||||
/* This file contains routines for tracing system calls and other internal
|
/* This file contains routines for tracing system calls and other internal
|
||||||
phenomenon.
|
phenomenon.
|
||||||
|
|
||||||
|
@ -33,21 +32,25 @@ details. */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
class child_info;
|
||||||
class strace
|
class strace
|
||||||
{
|
{
|
||||||
int vsprntf (char *buf, const char *func, const char *infmt, va_list ap);
|
int vsprntf (char *buf, const char *func, const char *infmt, va_list ap);
|
||||||
void write (unsigned category, const char *buf, int count);
|
void write (unsigned category, const char *buf, int count);
|
||||||
|
unsigned char _active;
|
||||||
public:
|
public:
|
||||||
int microseconds ();
|
int microseconds ();
|
||||||
int version;
|
int version;
|
||||||
int active;
|
|
||||||
int lmicrosec;
|
int lmicrosec;
|
||||||
int execing;
|
bool execing;
|
||||||
int inited;
|
void hello () __attribute__ ((regparm (1)));
|
||||||
void hello ();
|
|
||||||
void prntf (unsigned, const char *func, const char *, ...) /*__attribute__ ((regparm(3)))*/;
|
void prntf (unsigned, const char *func, const char *, ...) /*__attribute__ ((regparm(3)))*/;
|
||||||
void vprntf (unsigned, const char *func, const char *, va_list ap) /*__attribute__ ((regparm(3)))*/;
|
void vprntf (unsigned, const char *func, const char *, va_list ap) /*__attribute__ ((regparm(3)))*/;
|
||||||
void wm (int message, int word, int lon) __attribute__ ((regparm(3)));
|
void wm (int message, int word, int lon) __attribute__ ((regparm(3)));
|
||||||
|
void write_childpid (child_info&, unsigned long) __attribute__ ((regparm (2)));
|
||||||
|
bool attached () const {return _active == 3;}
|
||||||
|
bool active () const {return _active & 1;}
|
||||||
|
unsigned char& active_val () {return _active;}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern strace strace;
|
extern strace strace;
|
||||||
|
@ -56,6 +59,7 @@ extern strace strace;
|
||||||
|
|
||||||
#define _STRACE_INTERFACE_ACTIVATE_ADDR -1
|
#define _STRACE_INTERFACE_ACTIVATE_ADDR -1
|
||||||
#define _STRACE_INTERFACE_ACTIVATE_ADDR1 -2
|
#define _STRACE_INTERFACE_ACTIVATE_ADDR1 -2
|
||||||
|
#define _STRACE_CHILD_PID -3
|
||||||
|
|
||||||
/* Bitmasks of tracing messages to print. */
|
/* Bitmasks of tracing messages to print. */
|
||||||
|
|
||||||
|
@ -78,13 +82,6 @@ extern strace strace;
|
||||||
#define _STRACE_MALLOC 0x20000 // trace malloc calls
|
#define _STRACE_MALLOC 0x20000 // trace malloc calls
|
||||||
#define _STRACE_THREAD 0x40000 // thread-locking calls
|
#define _STRACE_THREAD 0x40000 // thread-locking calls
|
||||||
#define _STRACE_NOTALL 0x80000 // don't include if _STRACE_ALL
|
#define _STRACE_NOTALL 0x80000 // don't include if _STRACE_ALL
|
||||||
#if defined (DEBUGGING)
|
|
||||||
# define _STRACE_ON strace.active = 1
|
|
||||||
# define _STRACE_OFF strace.active = 0
|
|
||||||
#else
|
|
||||||
# define _STRACE_ON
|
|
||||||
# define _STRACE_OFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -108,7 +105,7 @@ void strace_printf (unsigned, const char *func, const char *, ...);
|
||||||
|
|
||||||
#define define_strace0(c,...) \
|
#define define_strace0(c,...) \
|
||||||
do { \
|
do { \
|
||||||
if ((c & _STRACE_SYSTEM) || strace.active) \
|
if ((c & _STRACE_SYSTEM) || strace.active ()) \
|
||||||
strace.prntf (c, __PRETTY_FUNCTION__, __VA_ARGS__); \
|
strace.prntf (c, __PRETTY_FUNCTION__, __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
@ -130,13 +127,13 @@ void strace_printf (unsigned, const char *func, const char *, ...);
|
||||||
#else
|
#else
|
||||||
#define strace_printf_wrap(what, fmt, args...) \
|
#define strace_printf_wrap(what, fmt, args...) \
|
||||||
((void) ({\
|
((void) ({\
|
||||||
if ((_STRACE_ ## what & _STRACE_SYSTEM) || strace.active) \
|
if ((_STRACE_ ## what & _STRACE_SYSTEM) || strace.active ()) \
|
||||||
strace.prntf(_STRACE_ ## what, __PRETTY_FUNCTION__, fmt, ## args); \
|
strace.prntf(_STRACE_ ## what, __PRETTY_FUNCTION__, fmt, ## args); \
|
||||||
0; \
|
0; \
|
||||||
}))
|
}))
|
||||||
#define strace_printf_wrap1(what, fmt, args...) \
|
#define strace_printf_wrap1(what, fmt, args...) \
|
||||||
((void) ({\
|
((void) ({\
|
||||||
if ((_STRACE_ ## what & _STRACE_SYSTEM) || strace.active) \
|
if ((_STRACE_ ## what & _STRACE_SYSTEM) || strace.active ()) \
|
||||||
strace.prntf((_STRACE_ ## what) | _STRACE_NOTALL, __PRETTY_FUNCTION__, fmt, ## args); \
|
strace.prntf((_STRACE_ ## what) | _STRACE_NOTALL, __PRETTY_FUNCTION__, fmt, ## args); \
|
||||||
0; \
|
0; \
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -41,6 +41,8 @@ calibration_thread (VOID *arg)
|
||||||
ExitThread (0);
|
ExitThread (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD calibration_id;
|
||||||
|
|
||||||
/* We need to know where the OS stores the address of the thread function
|
/* We need to know where the OS stores the address of the thread function
|
||||||
on the stack so that we can intercept the call and insert some tls
|
on the stack so that we can intercept the call and insert some tls
|
||||||
stuff on the stack. This function starts a known calibration thread.
|
stuff on the stack. This function starts a known calibration thread.
|
||||||
|
@ -50,11 +52,12 @@ calibration_thread (VOID *arg)
|
||||||
static void
|
static void
|
||||||
prime_threads ()
|
prime_threads ()
|
||||||
{
|
{
|
||||||
if (!threadfunc_ix[0])
|
if (threadfunc_ix[0])
|
||||||
|
sync_startup = INVALID_HANDLE_VALUE;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
DWORD id;
|
|
||||||
search_for = (char *) calibration_thread;
|
search_for = (char *) calibration_thread;
|
||||||
sync_startup = CreateThread (NULL, 0, calibration_thread, 0, 0, &id);
|
sync_startup = CreateThread (NULL, 0, calibration_thread, 0, 0, &calibration_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +75,7 @@ munge_threadfunc ()
|
||||||
for (peb = ebp, i = 0; peb < top && i < 7; peb++)
|
for (peb = ebp, i = 0; peb < top && i < 7; peb++)
|
||||||
if (*peb == search_for)
|
if (*peb == search_for)
|
||||||
threadfunc_ix[i++] = peb - ebp;
|
threadfunc_ix[i++] = peb - ebp;
|
||||||
if (!threadfunc_ix[0])
|
if (0 && !threadfunc_ix[0])
|
||||||
{
|
{
|
||||||
try_to_debug ();
|
try_to_debug ();
|
||||||
return;
|
return;
|
||||||
|
@ -82,7 +85,7 @@ munge_threadfunc ()
|
||||||
char *threadfunc = ebp[threadfunc_ix[0]];
|
char *threadfunc = ebp[threadfunc_ix[0]];
|
||||||
if (threadfunc == (char *) calibration_thread)
|
if (threadfunc == (char *) calibration_thread)
|
||||||
/* no need for the overhead */;
|
/* no need for the overhead */;
|
||||||
else
|
else if (threadfunc_ix[0])
|
||||||
{
|
{
|
||||||
for (i = 0; threadfunc_ix[i]; i++)
|
for (i = 0; threadfunc_ix[i]; i++)
|
||||||
ebp[threadfunc_ix[i]] = (char *) threadfunc_fe;
|
ebp[threadfunc_ix[i]] = (char *) threadfunc_fe;
|
||||||
|
@ -166,10 +169,12 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
munge_threadfunc ();
|
if (!sync_startup || GetCurrentThreadId () == calibration_id)
|
||||||
|
munge_threadfunc ();
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
_my_tls.remove (0);
|
if (!sync_startup)
|
||||||
|
_my_tls.remove (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ malloc_init ()
|
||||||
calls to malloc/free/realloc to application provided. This may
|
calls to malloc/free/realloc to application provided. This may
|
||||||
happen if some other dll calls cygwin's malloc, but main code provides
|
happen if some other dll calls cygwin's malloc, but main code provides
|
||||||
its own malloc */
|
its own malloc */
|
||||||
if (!user_data->forkee)
|
if (!in_forkee)
|
||||||
{
|
{
|
||||||
user_data->free (user_data->malloc (16));
|
user_data->free (user_data->malloc (16));
|
||||||
if (export_malloc_called)
|
if (export_malloc_called)
|
||||||
|
|
|
@ -54,10 +54,7 @@ set_myself (HANDLE h)
|
||||||
myself->dwProcessId = GetCurrentProcessId ();
|
myself->dwProcessId = GetCurrentProcessId ();
|
||||||
|
|
||||||
GetModuleFileName (NULL, myself->progname, sizeof (myself->progname));
|
GetModuleFileName (NULL, myself->progname, sizeof (myself->progname));
|
||||||
#ifndef DEBUGGING
|
strace.hello ();
|
||||||
if (!strace.active)
|
|
||||||
#endif
|
|
||||||
strace.hello ();
|
|
||||||
debug_printf ("myself->dwProcessId %u", myself->dwProcessId);
|
debug_printf ("myself->dwProcessId %u", myself->dwProcessId);
|
||||||
if (h)
|
if (h)
|
||||||
{
|
{
|
||||||
|
|
|
@ -768,7 +768,7 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, bool need_subpr
|
||||||
sigproc_printf ("subproc_ready %p", subproc_ready);
|
sigproc_printf ("subproc_ready %p", subproc_ready);
|
||||||
cygheap = ::cygheap;
|
cygheap = ::cygheap;
|
||||||
cygheap_max = ::cygheap_max;
|
cygheap_max = ::cygheap_max;
|
||||||
dwProcessId = myself->dwProcessId;
|
straced = strace.attached ();
|
||||||
/* Create an inheritable handle to pass to the child process. This will
|
/* Create an inheritable handle to pass to the child process. This will
|
||||||
allow the child to duplicate handles from the parent to itself. */
|
allow the child to duplicate handles from the parent to itself. */
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
|
|
|
@ -424,7 +424,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
pthread_cleanup_push (do_cleanup, (void *) &cleanup);
|
pthread_cleanup_push (do_cleanup, (void *) &cleanup);
|
||||||
av newargv;
|
av newargv;
|
||||||
linebuf one_line;
|
linebuf one_line;
|
||||||
child_info_spawn ciresrv;
|
child_info_spawn ch;
|
||||||
|
|
||||||
path_conv real_path;
|
path_conv real_path;
|
||||||
bool reset_sendsig = false;
|
bool reset_sendsig = false;
|
||||||
|
@ -643,11 +643,11 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
res = -1;
|
res = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ciresrv.set (chtype, real_path.iscygexec ());
|
ch.set (chtype, real_path.iscygexec ());
|
||||||
ciresrv.moreinfo = moreinfo;
|
ch.moreinfo = moreinfo;
|
||||||
|
|
||||||
si.lpReserved2 = (LPBYTE) &ciresrv;
|
si.lpReserved2 = (LPBYTE) &ch;
|
||||||
si.cbReserved2 = sizeof (ciresrv);
|
si.cbReserved2 = sizeof (ch);
|
||||||
|
|
||||||
/* When ruid != euid we create the new process under the current original
|
/* When ruid != euid we create the new process under the current original
|
||||||
account and impersonate in child, this way maintaining the different
|
account and impersonate in child, this way maintaining the different
|
||||||
|
@ -731,6 +731,9 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(flags & CREATE_SUSPENDED))
|
||||||
|
strace.write_childpid (ch, pi.dwProcessId);
|
||||||
|
|
||||||
/* Fixup the parent data structures if needed and resume the child's
|
/* Fixup the parent data structures if needed and resume the child's
|
||||||
main thread. */
|
main thread. */
|
||||||
if (cygheap->fdtab.need_fixup_before ())
|
if (cygheap->fdtab.need_fixup_before ())
|
||||||
|
@ -818,12 +821,15 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
|
|
||||||
/* Start the child running */
|
/* Start the child running */
|
||||||
if (flags & CREATE_SUSPENDED)
|
if (flags & CREATE_SUSPENDED)
|
||||||
ResumeThread (pi.hThread);
|
{
|
||||||
|
ResumeThread (pi.hThread);
|
||||||
|
strace.write_childpid (ch, pi.dwProcessId);
|
||||||
|
}
|
||||||
ForceCloseHandle (pi.hThread);
|
ForceCloseHandle (pi.hThread);
|
||||||
|
|
||||||
sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
|
sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
|
||||||
|
|
||||||
synced = ciresrv.sync (pid, pi.hProcess, INFINITE);
|
synced = ch.sync (pid, pi.hProcess, INFINITE);
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@ details. */
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
|
#include "child_info.h"
|
||||||
|
|
||||||
#define PROTECT(x) x[sizeof (x)-1] = 0
|
#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); }
|
#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
|
void
|
||||||
strace::hello ()
|
strace::hello ()
|
||||||
{
|
{
|
||||||
char buf[30];
|
if (_active || !being_debugged ())
|
||||||
|
|
||||||
if (inited)
|
|
||||||
{
|
|
||||||
active ^= 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
inited = 1;
|
|
||||||
if (!being_debugged ())
|
|
||||||
return;
|
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);
|
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, "**********************************************");
|
||||||
prntf (1, NULL, "Program name: %s (pid %d, ppid %d)", myself->progname,
|
prntf (1, NULL, "Program name: %s %s", myself->progname, pidbuf);
|
||||||
myself->pid ?: GetCurrentProcessId (),
|
|
||||||
myself->ppid ?: 1);
|
|
||||||
prntf (1, NULL, "App version: %d.%d, api: %d.%d",
|
prntf (1, NULL, "App version: %d.%d, api: %d.%d",
|
||||||
user_data->dll_major, user_data->dll_minor,
|
user_data->dll_major, user_data->dll_minor,
|
||||||
user_data->api_major, user_data->api_minor);
|
user_data->api_major, user_data->api_minor);
|
||||||
|
@ -65,7 +64,8 @@ strace::hello ()
|
||||||
cygwin_version.api_major, cygwin_version.api_minor);
|
cygwin_version.api_major, cygwin_version.api_minor);
|
||||||
prntf (1, NULL, "DLL build: %s", cygwin_version.dll_build_date);
|
prntf (1, NULL, "DLL build: %s", cygwin_version.dll_build_date);
|
||||||
prntf (1, NULL, "OS version: Windows %s", wincap.osname ());
|
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, "**********************************************");
|
prntf (1, NULL, "**********************************************");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,16 @@ getfunc (char *in_dst, const char *func)
|
||||||
return dst - in_dst;
|
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;
|
extern "C" char *__progname;
|
||||||
|
|
||||||
/* sprintf analog for use by output routines. */
|
/* 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;
|
static NO_COPY bool nonewline = false;
|
||||||
DWORD err = GetLastError ();
|
DWORD err = GetLastError ();
|
||||||
const char *tn = cygthread::name ();
|
const char *tn = cygthread::name ();
|
||||||
char *pn = __progname ?: (myself ? myself->progname : NULL);
|
|
||||||
|
|
||||||
int microsec = microseconds ();
|
int microsec = microseconds ();
|
||||||
lmicrosec = microsec;
|
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);
|
SetLastError (err);
|
||||||
|
|
||||||
|
@ -135,21 +144,33 @@ strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap)
|
||||||
count = 0;
|
count = 0;
|
||||||
else
|
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)
|
if (!pn)
|
||||||
p = (char *) "*** unknown ***";
|
GetModuleFileName (NULL, pn = progname, sizeof (progname));
|
||||||
|
if (!pn)
|
||||||
|
/* hmm */;
|
||||||
else if ((p = strrchr (pn, '\\')) != NULL)
|
else if ((p = strrchr (pn, '\\')) != NULL)
|
||||||
p++;
|
p++;
|
||||||
else if ((p = strrchr (pn, '/')) != NULL)
|
else if ((p = strrchr (pn, '/')) != NULL)
|
||||||
p++;
|
p++;
|
||||||
else
|
else
|
||||||
p = pn;
|
p = pn;
|
||||||
strcpy (progname, p);
|
if (p != progname)
|
||||||
|
strcpy (progname, p);
|
||||||
if ((p = strrchr (progname, '.')) != NULL && strcasematch (p, ".exe"))
|
if ((p = strrchr (progname, '.')) != NULL && strcasematch (p, ".exe"))
|
||||||
*p = '\000';
|
*p = '\000';
|
||||||
p = progname;
|
p = progname;
|
||||||
count = __small_sprintf (buf, fmt, p && *p ? p : "?",
|
char tmpbuf[20];
|
||||||
(myself && myself->pid) ? myself->pid : GetCurrentProcessId (),
|
count = __small_sprintf (buf, fmt, p && *p ? p : "?", mypid (tmpbuf),
|
||||||
execing ? "!" : "");
|
execing ? "!" : "");
|
||||||
if (func)
|
if (func)
|
||||||
count += getfunc (buf + count, func);
|
count += getfunc (buf + count, func);
|
||||||
|
@ -195,6 +216,20 @@ strace::write (unsigned category, const char *buf, int count)
|
||||||
#undef PREFIX
|
#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.
|
/* Printf function used when tracing system calls.
|
||||||
Warning: DO NOT SET ERRNO HERE! */
|
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
|
#ifndef NOSTRACE
|
||||||
if (active)
|
if (active ())
|
||||||
write (category, buf, len);
|
write (category, buf, len);
|
||||||
#endif
|
#endif
|
||||||
SetLastError (err);
|
SetLastError (err);
|
||||||
|
@ -249,7 +284,7 @@ strace_printf (unsigned category, const char *func, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
if ((category & _STRACE_SYSTEM) || strace.active)
|
if ((category & _STRACE_SYSTEM) || strace.active ())
|
||||||
{
|
{
|
||||||
va_start (ap, fmt);
|
va_start (ap, fmt);
|
||||||
strace.vprntf (category, func, fmt, ap);
|
strace.vprntf (category, func, fmt, ap);
|
||||||
|
@ -417,7 +452,7 @@ ta[] =
|
||||||
void
|
void
|
||||||
strace::wm (int message, int word, int lon)
|
strace::wm (int message, int word, int lon)
|
||||||
{
|
{
|
||||||
if (active)
|
if (active ())
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,7 @@ extern SYSTEM_INFO system_info;
|
||||||
/* The title on program start. */
|
/* The title on program start. */
|
||||||
extern char *old_title;
|
extern char *old_title;
|
||||||
extern bool display_title;
|
extern bool display_title;
|
||||||
|
extern bool in_forkee;
|
||||||
|
|
||||||
extern HANDLE hMainThread;
|
extern HANDLE hMainThread;
|
||||||
extern HANDLE hMainProc;
|
extern HANDLE hMainProc;
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
2005-12-29 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
* 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'.
|
||||||
|
|
||||||
2005-12-29 Christopher Faylor <cgf@timesys.com>
|
2005-12-29 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* cygcheck.cc (common_apps): Add crontab, vi, vim.
|
* cygcheck.cc (common_apps): Add crontab, vi, vim.
|
||||||
|
|
|
@ -37,11 +37,15 @@ static int forkdebug = 1;
|
||||||
static int numerror = 1;
|
static int numerror = 1;
|
||||||
static int show_usecs = 1;
|
static int show_usecs = 1;
|
||||||
static int delta = 1;
|
static int delta = 1;
|
||||||
static int hhmmss = 0;
|
static int hhmmss;
|
||||||
static int bufsize = 0;
|
static int bufsize;
|
||||||
static int new_window = 0;
|
static int new_window;
|
||||||
static long flush_period = 0;
|
static long flush_period;
|
||||||
static int include_hex = 0;
|
static int include_hex;
|
||||||
|
static int quiet = -1;
|
||||||
|
|
||||||
|
static unsigned char strace_active = 1;
|
||||||
|
static int processes;
|
||||||
|
|
||||||
static BOOL close_handle (HANDLE h, DWORD ok);
|
static BOOL close_handle (HANDLE h, DWORD ok);
|
||||||
|
|
||||||
|
@ -104,18 +108,6 @@ error (int geterrno, const char *fmt, ...)
|
||||||
DWORD lastid = 0;
|
DWORD lastid = 0;
|
||||||
HANDLE lasth;
|
HANDLE lasth;
|
||||||
|
|
||||||
#define PROCFLAGS \
|
|
||||||
PROCESS_ALL_ACCESS /*(PROCESS_DUP_HANDLE | PROCESS_TERMINATE | PROCESS_VM_READ | PROCESS_VM_WRITE) */
|
|
||||||
static void
|
|
||||||
add_child (DWORD id, HANDLE hproc)
|
|
||||||
{
|
|
||||||
child_list *c = children.next;
|
|
||||||
children.next = (child_list *) calloc (1, sizeof (child_list));
|
|
||||||
children.next->next = c;
|
|
||||||
lastid = children.next->id = id;
|
|
||||||
lasth = children.next->hproc = hproc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static child_list *
|
static child_list *
|
||||||
get_child (DWORD id)
|
get_child (DWORD id)
|
||||||
{
|
{
|
||||||
|
@ -124,7 +116,23 @@ get_child (DWORD id)
|
||||||
if (c->id == id)
|
if (c->id == id)
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
error (0, "no process id %d found", id);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_child (DWORD id, HANDLE hproc)
|
||||||
|
{
|
||||||
|
if (!get_child (id))
|
||||||
|
{
|
||||||
|
child_list *c = children.next;
|
||||||
|
children.next = (child_list *) calloc (1, sizeof (child_list));
|
||||||
|
children.next->next = c;
|
||||||
|
lastid = children.next->id = id;
|
||||||
|
lasth = children.next->hproc = hproc;
|
||||||
|
processes++;
|
||||||
|
if (!quiet)
|
||||||
|
fprintf (stderr, "Windows process %d attached\n", id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -139,6 +147,9 @@ remove_child (DWORD id)
|
||||||
child_list *c1 = c->next;
|
child_list *c1 = c->next;
|
||||||
c->next = c1->next;
|
c->next = c1->next;
|
||||||
free (c1);
|
free (c1);
|
||||||
|
if (!quiet)
|
||||||
|
fprintf (stderr, "Windows process %d detached\n", id);
|
||||||
|
processes--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,15 +294,11 @@ attach_process (pid_t pid)
|
||||||
{
|
{
|
||||||
child_pid = (DWORD) cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
|
child_pid = (DWORD) cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
|
||||||
if (!child_pid)
|
if (!child_pid)
|
||||||
{
|
child_pid = pid;
|
||||||
warn (0, "no such cygwin pid - %d", pid);
|
|
||||||
child_pid = pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DebugActiveProcess (child_pid))
|
if (!DebugActiveProcess (child_pid))
|
||||||
error (0, "couldn't attach to pid %d<%d> for debugging", pid, child_pid);
|
error (0, "couldn't attach to pid %d for debugging", child_pid);
|
||||||
|
|
||||||
printf ("Attached to pid %d (windows pid %u)\n", pid, (unsigned) child_pid);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,6 +403,8 @@ handle_output_debug_string (DWORD id, LPVOID p, unsigned mask, FILE *ofile)
|
||||||
char alen[3 + 8 + 1];
|
char alen[3 + 8 + 1];
|
||||||
DWORD nbytes;
|
DWORD nbytes;
|
||||||
child_list *child = get_child (id);
|
child_list *child = get_child (id);
|
||||||
|
if (!child)
|
||||||
|
error (0, "no process id %d found", id);
|
||||||
HANDLE hchild = child->hproc;
|
HANDLE hchild = child->hproc;
|
||||||
#define INTROLEN (sizeof (alen) - 1)
|
#define INTROLEN (sizeof (alen) - 1)
|
||||||
|
|
||||||
|
@ -423,7 +432,7 @@ handle_output_debug_string (DWORD id, LPVOID p, unsigned mask, FILE *ofile)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
special = len;
|
special = len;
|
||||||
if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
|
if (special == _STRACE_INTERFACE_ACTIVATE_ADDR || special == _STRACE_CHILD_PID)
|
||||||
len = 17;
|
len = 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,14 +450,20 @@ handle_output_debug_string (DWORD id, LPVOID p, unsigned mask, FILE *ofile)
|
||||||
|
|
||||||
s = strchr (s, '\0') + 1;
|
s = strchr (s, '\0') + 1;
|
||||||
|
|
||||||
|
if (special == _STRACE_CHILD_PID)
|
||||||
|
{
|
||||||
|
if (!DebugActiveProcess (n))
|
||||||
|
error (0, "couldn't attach to subprocess %d for debugging, "
|
||||||
|
"windows error %d", n, GetLastError ());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
|
if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
|
||||||
{
|
{
|
||||||
DWORD new_flag = 1;
|
if (!WriteProcessMemory (hchild, (LPVOID) n, &strace_active,
|
||||||
if (!WriteProcessMemory (hchild, (LPVOID) n, &new_flag,
|
sizeof (strace_active), &nbytes))
|
||||||
sizeof (new_flag), &nbytes))
|
error (0, "couldn't write strace flag to subprocess at %p, "
|
||||||
error (0,
|
"windows error %d", n, GetLastError ());
|
||||||
"couldn't write strace flag to subprocess at %p, windows error %d",
|
|
||||||
n, GetLastError ());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +592,6 @@ static void
|
||||||
proc_child (unsigned mask, FILE *ofile, pid_t pid)
|
proc_child (unsigned mask, FILE *ofile, pid_t pid)
|
||||||
{
|
{
|
||||||
DEBUG_EVENT ev;
|
DEBUG_EVENT ev;
|
||||||
int processes = 0;
|
|
||||||
time_t cur_time, last_time;
|
time_t cur_time, last_time;
|
||||||
|
|
||||||
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
|
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
|
||||||
|
@ -609,7 +623,6 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid)
|
||||||
if (ev.u.CreateProcessInfo.hFile)
|
if (ev.u.CreateProcessInfo.hFile)
|
||||||
CloseHandle (ev.u.CreateProcessInfo.hFile);
|
CloseHandle (ev.u.CreateProcessInfo.hFile);
|
||||||
add_child (ev.dwProcessId, ev.u.CreateProcessInfo.hProcess);
|
add_child (ev.dwProcessId, ev.u.CreateProcessInfo.hProcess);
|
||||||
processes++;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREATE_THREAD_DEBUG_EVENT:
|
case CREATE_THREAD_DEBUG_EVENT:
|
||||||
|
@ -630,22 +643,20 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid)
|
||||||
remove_child (ev.dwProcessId);
|
remove_child (ev.dwProcessId);
|
||||||
break;
|
break;
|
||||||
case EXCEPTION_DEBUG_EVENT:
|
case EXCEPTION_DEBUG_EVENT:
|
||||||
if (ev.u.Exception.ExceptionRecord.ExceptionCode !=
|
if (ev.u.Exception.ExceptionRecord.ExceptionCode != STATUS_BREAKPOINT)
|
||||||
STATUS_BREAKPOINT)
|
|
||||||
{
|
{
|
||||||
status = DBG_EXCEPTION_NOT_HANDLED;
|
status = DBG_EXCEPTION_NOT_HANDLED;
|
||||||
#if 0
|
if (ev.u.Exception.dwFirstChance)
|
||||||
fprintf (stderr, "exception %p at %p\n",
|
fprintf (ofile, "--- Process %u, exception %p at %p\n", ev.dwProcessId,
|
||||||
ev.u.Exception.ExceptionRecord.ExceptionCode,
|
ev.u.Exception.ExceptionRecord.ExceptionCode,
|
||||||
ev.u.Exception.ExceptionRecord.ExceptionAddress);
|
ev.u.Exception.ExceptionRecord.ExceptionAddress);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ContinueDebugEvent (ev.dwProcessId, ev.dwThreadId, status))
|
if (!ContinueDebugEvent (ev.dwProcessId, ev.dwThreadId, status))
|
||||||
error (0, "couldn't continue debug event, windows error %d",
|
error (0, "couldn't continue debug event, windows error %d",
|
||||||
GetLastError ());
|
GetLastError ());
|
||||||
if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT && --processes == 0)
|
if (!processes)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -864,6 +875,7 @@ struct option longopts[] = {
|
||||||
{"output", required_argument, NULL, 'o'},
|
{"output", required_argument, NULL, 'o'},
|
||||||
{"no-delta", no_argument, NULL, 'd'},
|
{"no-delta", no_argument, NULL, 'd'},
|
||||||
{"pid", required_argument, NULL, 'p'},
|
{"pid", required_argument, NULL, 'p'},
|
||||||
|
{"quiet", no_argument, NULL, 'q'},
|
||||||
{"timestamp", no_argument, NULL, 't'},
|
{"timestamp", no_argument, NULL, 't'},
|
||||||
{"toggle", no_argument, NULL, 'T'},
|
{"toggle", no_argument, NULL, 'T'},
|
||||||
{"trace-children", no_argument, NULL, 'f'},
|
{"trace-children", no_argument, NULL, 'f'},
|
||||||
|
@ -873,7 +885,7 @@ struct option longopts[] = {
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const opts = "+b:dhHfm:no:p:S:tTuvw";
|
static const char *const opts = "+b:dhHfm:no:p:qS:tTuvw";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_version ()
|
print_version ()
|
||||||
|
@ -906,6 +918,7 @@ main (int argc, char **argv)
|
||||||
pid_t pid = 0;
|
pid_t pid = 0;
|
||||||
int opt;
|
int opt;
|
||||||
int toggle = 0;
|
int toggle = 0;
|
||||||
|
int sawquiet = -1;
|
||||||
|
|
||||||
if (load_cygwin ())
|
if (load_cygwin ())
|
||||||
{
|
{
|
||||||
|
@ -963,6 +976,13 @@ character #%d.\n", optarg, (int) (endptr - optarg), endptr);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pid = strtoul (optarg, NULL, 10);
|
pid = strtoul (optarg, NULL, 10);
|
||||||
|
strace_active |= 2;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
if (sawquiet < 0)
|
||||||
|
sawquiet = 1;
|
||||||
|
else
|
||||||
|
sawquiet ^= 1;
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
flush_period = strtoul (optarg, NULL, 10);
|
flush_period = strtoul (optarg, NULL, 10);
|
||||||
|
@ -999,6 +1019,13 @@ character #%d.\n", optarg, (int) (endptr - optarg), endptr);
|
||||||
if (toggle && !pid)
|
if (toggle && !pid)
|
||||||
error (0, "must provide a process id to toggle tracing");
|
error (0, "must provide a process id to toggle tracing");
|
||||||
|
|
||||||
|
if (!pid)
|
||||||
|
quiet = sawquiet < 0 || !sawquiet;
|
||||||
|
else if (sawquiet < 0)
|
||||||
|
quiet = 0;
|
||||||
|
else
|
||||||
|
quiet = sawquiet;
|
||||||
|
|
||||||
if (!mask)
|
if (!mask)
|
||||||
mask = _STRACE_ALL;
|
mask = _STRACE_ALL;
|
||||||
|
|
||||||
|
|
|
@ -1489,6 +1489,8 @@ Trace system calls and signals
|
||||||
numbers for Windows errors
|
numbers for Windows errors
|
||||||
-o, --output=FILENAME set output file to FILENAME
|
-o, --output=FILENAME set output file to FILENAME
|
||||||
-p, --pid=n attach to executing program with cygwin pid n
|
-p, --pid=n attach to executing program with cygwin pid n
|
||||||
|
-q, --quiet toggle "quiet" flag. Defaults to on if "-p",
|
||||||
|
off otherwise.
|
||||||
-S, --flush-period=PERIOD flush buffered strace output every PERIOD secs
|
-S, --flush-period=PERIOD flush buffered strace output every PERIOD secs
|
||||||
-t, --timestamp use an absolute hh:mm:ss timestamp insted of
|
-t, --timestamp use an absolute hh:mm:ss timestamp insted of
|
||||||
the default microsecond timestamp. Implies -d
|
the default microsecond timestamp. Implies -d
|
||||||
|
|
Loading…
Reference in New Issue