From d542443ea4e9615e66b729fc4a93ec72a5305fff Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 28 Feb 2000 05:05:33 +0000 Subject: [PATCH] * dcrt0.cc (set_os_type): Record OS name string. (getprogname): Eliminate obsolete function. (dll_crt0_1): Move initial strace initialization output to set_myself. * exceptions.cc (interruptible): Add debugging output. (interrupt_setup): New function. (interrupt_now): Use interrupt_setup to set up common interrupt handler stuff. (interrupt_on_return): Ditto. (call_handler): Move signal_arrived arm and clear threads to region where signalled thread is suspended or suffer races. * pinfo.cc (set_myself): Output interesting information when strace is first initialized. Initialize progname here. * sigproc.cc (sig_dispatch_pending): Modify to ensure that flush signal are sent synchronously. * strace.cc (strace_vsprintf): Move code into strace program. * uname.cc (uname): Use 'osname' global to construct cygwin name + Windows type + version. --- winsup/cygwin/ChangeLog | 20 ++++++++++ winsup/cygwin/dcrt0.cc | 66 +++++++++++---------------------- winsup/cygwin/exceptions.cc | 73 +++++++++++++++---------------------- winsup/cygwin/pinfo.cc | 21 +++++++++-- winsup/cygwin/sigproc.cc | 11 ++++-- winsup/cygwin/strace.cc | 42 ++++++--------------- winsup/cygwin/uname.cc | 30 ++------------- 7 files changed, 110 insertions(+), 153 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 83c70d277..71120baab 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +Sun Feb 27 23:11:57 2000 Christopher Faylor + + * dcrt0.cc (set_os_type): Record OS name string. + (getprogname): Eliminate obsolete function. + (dll_crt0_1): Move initial strace initialization output to set_myself. + * exceptions.cc (interruptible): Add debugging output. + (interrupt_setup): New function. + (interrupt_now): Use interrupt_setup to set up common interrupt handler + stuff. + (interrupt_on_return): Ditto. + (call_handler): Move signal_arrived arm and clear threads to region + where signalled thread is suspended or suffer races. + * pinfo.cc (set_myself): Output interesting information when strace is + first initialized. Initialize progname here. + * sigproc.cc (sig_dispatch_pending): Modify to ensure that flush signal + are sent synchronously. + * strace.cc (strace_vsprintf): Move code into strace program. + * uname.cc (uname): Use 'osname' global to construct cygwin name + + Windows type + version. + Fri Feb 25 19:26:42 2000 Christopher Faylor * exceptions.cc (interruptible): Make a little more structured. diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index a0bd58e13..4029d6c1f 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -80,7 +80,7 @@ do_global_ctors (void (**in_pfunc)(), int force) if (!force) { if (user_data->forkee || user_data->run_ctors_p) - return; // inherit constructed stuff from parent pid + return; // inherit constructed stuff from parent pid user_data->run_ctors_p = 1; } @@ -101,6 +101,8 @@ do_global_ctors (void (**in_pfunc)(), int force) /* remember the type of Win32 OS being run for future use. */ os_type NO_COPY os_being_run; +char NO_COPY osname[40]; + /* set_os_type: Set global variable os_being_run with type of Win32 operating system being run. This information is used internally to manage the inconsistency in Win32 API calls between Win32 OSes. */ @@ -109,28 +111,37 @@ static void set_os_type () { OSVERSIONINFO os_version_info; - os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + const char *os; + memset (&os_version_info, 0, sizeof os_version_info); + os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&os_version_info); switch (os_version_info.dwPlatformId) { case VER_PLATFORM_WIN32_NT: os_being_run = winNT; + os = "NT"; break; case VER_PLATFORM_WIN32_WINDOWS: if (os_version_info.dwMinorVersion == 0) - os_being_run = win95; + { + os_being_run = win95; + os = "95"; + } else /* os_version_info.dwMinorVersion == 10 */ - os_being_run = win98; - break; - case VER_PLATFORM_WIN32s: - os_being_run = win32s; + { + os_being_run = win98; + os = "98"; + } break; default: os_being_run = unknown; + os = "??"; break; } + __small_sprintf (osname, "%s-%d.%d", os, os_version_info.dwMajorVersion, + os_version_info.dwMinorVersion); } host_dependent_constants NO_COPY host_dependent; @@ -165,31 +176,6 @@ host_dependent_constants::init (void) } } -/* Save the program name. It's used in debugging messages and by - the fork code (forking spawns a copy of us). Copy it into a temp and - then into the final spot because debugging messages use - myself->progname. Try getting the absolute path from the - module handle, if this fails get the name from the path. - This call references $PATH so we can't do this until the environment - vars are set up. */ -/* FIXME: What if argv[0] is relative, $PATH changes, and then the program - tries to do a fork? */ - -static void __stdcall -getprogname (char *argv0) -{ - char tmp[MAX_PATH]; - - if (user_data->hmodule != 0) - { - if (GetModuleFileName (user_data->hmodule, tmp, MAX_PATH) == 0) - find_exec (argv0, tmp); - } - else - find_exec (argv0, tmp); - strcpy (myself->progname, tmp); -} - /* * Replaces -@file in the command line with the contents of the file. * There may be multiple -@file's in a single command line @@ -733,13 +719,6 @@ dll_crt0_1 () uinfo_init (); #endif - syscall_printf ("Application CYGWIN version: %d.%d, api: %d.%d", - user_data->dll_major, user_data->dll_minor, - user_data->api_major, user_data->api_minor); - syscall_printf ("CYGWIN DLL version: %d.%d, api: %d.%d", - cygwin_version.dll_major, cygwin_version.dll_minor, - cygwin_version.api_major, cygwin_version.api_minor); - /* Scan the command line and build argv. Expand wildcards if not called from another cygwin process. */ build_argv (line, argv, argc, @@ -754,7 +733,6 @@ dll_crt0_1 () argv[0] = new_argv0; } - getprogname (argv[0]); /* Set up __progname for getopt error call. */ __progname = argv[0]; @@ -819,11 +797,11 @@ dll_crt0 (per_process *uptr) /* We don't want subprocesses to inherit this */ if (!dynamically_loaded) - { + { if (!DuplicateHandle (me, child_proc_info->parent_alive, - me, &parent_alive, 0, 0, - DUPLICATE_SAME_ACCESS - | DUPLICATE_CLOSE_SOURCE)) + me, &parent_alive, 0, 0, + DUPLICATE_SAME_ACCESS + | DUPLICATE_CLOSE_SOURCE)) system_printf ("parent_alive DuplicateHandle failed, %E"); } else if (parent_alive) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 1cfe1e701..dfacbc935 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -643,38 +643,33 @@ interruptible (DWORD pc) windows_system_directory_length); } + sigproc_printf ("interruptible %d", res); return res; # undef h #endif } -void +static void __stdcall +interrupt_setup (int sig, struct sigaction& siga, void *handler, DWORD retaddr) +{ + sigsave.retaddr = retaddr; + sigsave.oldmask = myself->getsigmask (); // Remember for restoration + /* FIXME: Not multi-thread aware */ + set_process_mask (myself->getsigmask () | siga.sa_mask | SIGTOMASK (sig)); + sigsave.func = (void (*)(int)) handler; + sigsave.sig = sig; + sigsave.saved_errno = -1; // Flag: no errno to save +} + +static void interrupt_now (CONTEXT *ctx, int sig, struct sigaction& siga, void *handler) { - DWORD oldmask = myself->getsigmask (); - set_process_mask (myself->getsigmask () | siga.sa_mask | SIGTOMASK (sig)); - - DWORD *sp = (DWORD *) ctx->Esp; - *(--sp) = ctx->Eip; /* ctxinal IP where program was suspended */ - *(--sp) = ctx->EFlags; - *(--sp) = ctx->Esi; - *(--sp) = ctx->Edi; - *(--sp) = ctx->Edx; - *(--sp) = ctx->Ecx; - *(--sp) = ctx->Ebx; - *(--sp) = ctx->Eax; - *(--sp) = (DWORD)-1; /* no saved errno. */ - *(--sp) = oldmask; - *(--sp) = sig; - *(--sp) = (DWORD) sigreturn; - - ctx->Esp = (DWORD) sp; - ctx->Eip = (DWORD) handler; - + interrupt_setup (sig, siga, handler, ctx->Eip); + ctx->Eip = (DWORD) sigdelayed; SetThreadContext (myself->getthread2signal(), ctx); /* Restart the thread */ } -int +static int interrupt_on_return (CONTEXT *ctx, int sig, struct sigaction& siga, void *handler) { int i; @@ -692,15 +687,11 @@ interrupt_on_return (CONTEXT *ctx, int sig, struct sigaction& siga, void *handle if (interruptible (thestack->sf.AddrReturn.Offset)) { DWORD *addr_retaddr = ((DWORD *)thestack->sf.AddrFrame.Offset) + 1; - if (*addr_retaddr != thestack->sf.AddrReturn.Offset) - break; - sigsave.retaddr = *addr_retaddr; - *addr_retaddr = (DWORD) sigdelayed; - sigsave.oldmask = myself->getsigmask (); // Remember for restoration - set_process_mask (myself->getsigmask () | siga.sa_mask | SIGTOMASK (sig)); - sigsave.func = (void (*)(int)) handler; - sigsave.sig = sig; - sigsave.saved_errno = -1; // Flag: no errno to save + if (*addr_retaddr == thestack->sf.AddrReturn.Offset) + { + interrupt_setup (sig, siga, handler, *addr_retaddr); + *addr_retaddr = (DWORD) sigdelayed; + } break; } @@ -720,6 +711,7 @@ call_handler (int sig, struct sigaction& siga, void *handler) { CONTEXT *cx, orig; int interrupted = 1; + HANDLE hth; int res; if (hExeced != NULL && hExeced != INVALID_HANDLE_VALUE) @@ -727,15 +719,10 @@ call_handler (int sig, struct sigaction& siga, void *handler) SetEvent (signal_arrived); // For an EINTR case sigproc_printf ("armed signal_arrived"); exec_exit = sig; // Maybe we'll exit with this value - return 1; + goto out; } + hth = myself->getthread2signal (); - /* Suspend the running thread, grab its context somewhere safe - and run the exception handler in the context of the thread - - we have to do that since sometimes they don't return - and if - this thread doesn't return, you won't ever get another exception. */ - - HANDLE hth = myself->getthread2signal (); /* Suspend the thread which will receive the signal. But first ensure that this thread doesn't have the sync_proc_subproc and mask_sync mutos, since we need those (hack alert). If the thread-to-be-suspended has either of @@ -792,20 +779,18 @@ call_handler (int sig, struct sigaction& siga, void *handler) interrupted = 0; } - (void) ResumeThread (hth); - if (interrupted) { - /* Apparently we have to set signal_arrived after resuming the thread or it - is possible that the event will be ignored. */ (void) SetEvent (signal_arrived); // For an EINTR case + sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); /* Clear any waiting threads prior to dispatching to handler function */ proc_subproc(PROC_CLEARWAIT, 1); } - sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); + + (void) ResumeThread (hth); out: - sigproc_printf ("returning"); + sigproc_printf ("returning %d", interrupted); return interrupted; } #endif /* i386 */ diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 789a47920..b4873c544 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -46,6 +46,24 @@ set_myself (pinfo *p) __small_sprintf (buf, "cYg%8x %x %x", _STRACE_INTERFACE_ACTIVATE_ADDR, &strace_active); OutputDebugString (buf); + + (void) GetModuleFileName (NULL, myself->progname, + sizeof(myself->progname)); + if (strace_active) + { + extern char osname[]; + strace_printf (1, "**********************************************"); + strace_printf (1, "Program name: %s", myself->progname); + strace_printf (1, "App version: %d.%d, api: %d.%d", + user_data->dll_major, user_data->dll_minor, + user_data->api_major, user_data->api_minor); + strace_printf (1, "DLL version: %d.%d, api: %d.%d", + cygwin_version.dll_major, cygwin_version.dll_minor, + cygwin_version.api_major, cygwin_version.api_minor); + strace_printf (1, "OS version: Windows %s", osname); + strace_printf (1, "**********************************************"); + } + return myself; } @@ -77,9 +95,6 @@ pinfo_init (LPBYTE info) if (!set_myself (cygwin_shared->p.allocate_pid ())) api_fatal ("No more processes"); - - (void) GetModuleFileName (NULL, myself->progname, - sizeof(myself->progname)); myself->ppid = myself->pgid = myself->sid = myself->pid; myself->ctty = -1; myself->uid = USHRT_MAX; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 991d91ffb..9c868edca 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -550,7 +550,7 @@ sig_clear (int sig) /* Force the wait_sig thread to wake up and scan the sigtodo array. */ extern "C" int __stdcall -sig_dispatch_pending (int force) +sig_dispatch_pending (int justwake) { if (!hwait_sig) return 0; @@ -559,7 +559,7 @@ sig_dispatch_pending (int force) #ifdef DEBUGGING sip_printf ("pending_signals %d", was_pending); #endif - if (!was_pending && !force) + if (!was_pending && !justwake) #ifdef DEBUGGING sip_printf ("no need to wake anything up"); #else @@ -568,7 +568,9 @@ sig_dispatch_pending (int force) else { wait_for_me (); - if (ReleaseSemaphore (sigcatch_nosync, 1, NULL)) + if (!justwake) + (void) sig_send (myself, __SIGFLUSH); + else if (ReleaseSemaphore (sigcatch_nosync, 1, NULL)) #ifdef DEBUGGING sip_printf ("woke up wait_sig"); #else @@ -578,6 +580,7 @@ sig_dispatch_pending (int force) /*sip_printf ("I'm going away now")*/; else system_printf ("%E releasing sigcatch_nosync(%p)", sigcatch_nosync); + } return was_pending; } @@ -958,7 +961,7 @@ getsem (pinfo *p, const char *str, int init, int max) DWORD winpid = GetCurrentProcessId (); h = CreateSemaphore (allow_ntsec ? sec_user (sa_buf) : &sec_none_nih, - init, max, str = shared_name (str, winpid)); + init, max, str = shared_name (str, winpid)); p = myself; } else diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc index 742feaed1..d76f7b84a 100644 --- a/winsup/cygwin/strace.cc +++ b/winsup/cygwin/strace.cc @@ -63,30 +63,16 @@ static int strace_vsprintf (char *buf, const char *infmt, va_list ap) { int count; - char fmt[80], unkfmt[80]; + char fmt[80]; static int nonewline = FALSE; DWORD err = GetLastError (); + const char *tn = threadname (0); -#ifndef STRACE_HHMMSS static int lmicrosec = 0; int microsec = strace_microseconds (); - int dmicrosec = lmicrosec ? microsec - lmicrosec : 0; lmicrosec = microsec; - __small_sprintf (fmt, "%5d %7d [%s] %s ", - dmicrosec, microsec, threadname (0), "%s %d%s"); - __small_sprintf (unkfmt, "%6d %7d [%s] %s ", - dmicrosec, microsec, threadname (0), - "(unknown)"); -#else - SYSTEMTIME st; - GetLocalTime (&st); - const char *tn = threadname (0); - __small_sprintf (fmt, "%02d:%02d:%02d [%s] %s ", - st.wHour, st.wMinute, st.wSecond, tn, "%s %d%s"); - __small_sprintf (unkfmt, "%02d:%02d:%02d [%s] %s ", - st.wHour, st.wMinute, st.wSecond, tn, "***"); -#endif + __small_sprintf (fmt, "%7d [%s] %s ", microsec, tn, "%s %d%s"); SetLastError (err); if (nonewline) @@ -101,21 +87,15 @@ strace_vsprintf (char *buf, const char *infmt, va_list ap) else { char *p, progname[sizeof (myself->progname)]; - static BOOL NO_COPY output_path_once = FALSE; - if (!output_path_once) - output_path_once = !!(p = myself->progname); + if ((p = strrchr (myself->progname, '\\')) != NULL) + p++; else - { - if ((p = strrchr (myself->progname, '\\')) != NULL) - p++; - else - p = myself->progname; - strcpy (progname, p); - if ((p = strrchr (progname, '.')) != NULL) - *p = '\000'; - p = progname; - } - count = __small_sprintf (buf, fmt, p && *p ? p : "(unknown)", + p = myself->progname; + strcpy (progname, p); + if ((p = strrchr (progname, '.')) != NULL) + *p = '\000'; + p = progname; + count = __small_sprintf (buf, fmt, p && *p ? p : "?", myself->pid, hExeced ? "!" : ""); } diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc index 101855cd7..d15214613 100644 --- a/winsup/cygwin/uname.cc +++ b/winsup/cygwin/uname.cc @@ -15,16 +15,14 @@ details. */ #include "winsup.h" /* uname: POSIX 4.4.1.1 */ -extern "C" -int +extern "C" int uname (struct utsname *name) { DWORD len; SYSTEM_INFO sysinfo; - OSVERSIONINFO os_version_info; + extern char osname[]; - os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - GetVersionEx (&os_version_info); + __small_sprintf (name->sysname, "CYGWIN_%s", osname); GetSystemInfo (&sysinfo); @@ -33,28 +31,6 @@ uname (struct utsname *name) len = sizeof (name->nodename) - 1; GetComputerNameA (name->nodename, &len); - /* Operating system type */ - switch (os_being_run) - { - case winNT: - strcpy (name->sysname, "CYGWIN_NT"); - break; - case win98: - strcpy (name->sysname, "CYGWIN_98"); - break; - case win95: - strcpy (name->sysname, "CYGWIN_95"); - break; - default: - strcpy (name->sysname, "CYGWIN_??"); - break; - } - - __small_sprintf (strchr (name->sysname, '\0'), "-%d.%d", - os_version_info.dwMajorVersion, - os_version_info.dwMinorVersion); - - /* Cygwin dll release */ __small_sprintf (name->release, "%d.%d.%d(%d.%d/%d/%d)", cygwin_version.dll_major / 1000,