Reduce stack pressure throughout Cygwin
* dcrt0.cc (initial_env): Reduce size of local path buffers to
        PATH_MAX.  Allocate debugger_command from process heap.
        (init_windows_system_directory): Very early initialize new global
        variable global_progname.
        * dll_init.cc (dll_list::alloc): Make path buffer static.  Explain why.
        (dll_list::populate_deps): Use tmp_pathbuf for local path buffer.
        * exceptions.cc (debugger_command): Convert to PWCHAR.
        (error_start_init): Allocate debugger_command and fill with wide char
        strings.  Only allocate if NULL.
        (try_to_debug): Just check if debugger_command is a NULL pointer to
        return.  Drop conversion from char to WCHAR and drop local variable
        dbg_cmd.
        * globals.cc (global_progname): New global variable to store Windows
        application path.
        * pinfo.cc (pinfo_basic::pinfo_basic): Just copy progname over from
        global_progname.
        (pinfo::status_exit): Let path_conv create the POSIX path to
        avoid local buffer.
        * pseudo_reloc.cc (__report_error): Utilize global_progname, drop local
        buffer.
        * smallprint.cc (__small_vsprintf): Just utilize global_progname for
        %P format specifier.
        (__small_vswprintf): Ditto.
        * strace.cc (PROTECT): Change to reflect x being a pointer.  Reformat.
        (CHECK): Ditto.  Reformat.
        (strace::activate): Utilize global_progname, drop local buffer.
        Fix formatting.
        (strace::vsprntf): Reduce size of local progname buffer to NAME_MAX.
        Copy and, if necessary, convert only the last path component to
        progname.
        (strace_buf_guard): New muto.
        (buf): New static pointer.
        (strace::vprntf): Use buf under strace_buf_guard lock only.  Allocate
        buffer space for buf on Windows heap.
        * wow64.cc (wow64_respawn_process): Utilize global_progname, drop
        local path buffer.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
			
			
This commit is contained in:
		| @@ -1,3 +1,42 @@ | |||||||
|  | 2015-07-19  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* dcrt0.cc (initial_env): Reduce size of local path buffers to | ||||||
|  | 	PATH_MAX.  Allocate debugger_command from process heap. | ||||||
|  | 	(init_windows_system_directory): Very early initialize new global | ||||||
|  | 	variable global_progname. | ||||||
|  | 	* dll_init.cc (dll_list::alloc): Make path buffer static.  Explain why. | ||||||
|  | 	(dll_list::populate_deps): Use tmp_pathbuf for local path buffer. | ||||||
|  | 	* exceptions.cc (debugger_command): Convert to PWCHAR. | ||||||
|  | 	(error_start_init): Allocate debugger_command and fill with wide char | ||||||
|  | 	strings.  Only allocate if NULL. | ||||||
|  | 	(try_to_debug): Just check if debugger_command is a NULL pointer to | ||||||
|  | 	return.  Drop conversion from char to WCHAR and drop local variable | ||||||
|  | 	dbg_cmd. | ||||||
|  | 	* globals.cc (global_progname): New global variable to store Windows | ||||||
|  | 	application path. | ||||||
|  | 	* pinfo.cc (pinfo_basic::pinfo_basic): Just copy progname over from | ||||||
|  | 	global_progname. | ||||||
|  | 	(pinfo::status_exit): Let path_conv create the POSIX path to | ||||||
|  | 	avoid local buffer. | ||||||
|  | 	* pseudo_reloc.cc (__report_error): Utilize global_progname, drop local | ||||||
|  | 	buffer. | ||||||
|  | 	* smallprint.cc (__small_vsprintf): Just utilize global_progname for | ||||||
|  | 	%P format specifier. | ||||||
|  | 	(__small_vswprintf): Ditto. | ||||||
|  | 	* strace.cc (PROTECT): Change to reflect x being a pointer.  Reformat. | ||||||
|  | 	(CHECK): Ditto.  Reformat. | ||||||
|  | 	(strace::activate): Utilize global_progname, drop local buffer. | ||||||
|  | 	Fix formatting. | ||||||
|  | 	(strace::vsprntf): Reduce size of local progname buffer to NAME_MAX. | ||||||
|  | 	Copy and, if necessary, convert only the last path component to | ||||||
|  | 	progname. | ||||||
|  | 	(strace_buf_guard): New muto. | ||||||
|  | 	(buf): New static pointer. | ||||||
|  | 	(strace::vprntf): Use buf under strace_buf_guard lock only.  Allocate | ||||||
|  | 	buffer space for buf on Windows heap. | ||||||
|  | 	* wow64.cc (wow64_respawn_process): Utilize global_progname, drop | ||||||
|  | 	local path buffer. | ||||||
|  |  | ||||||
| 2015-07-18  Corinna Vinschen  <corinna@vinschen.de> | 2015-07-18  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* gendef: Remove unused 64 bit versions of __sjfault and __ljfault. | 	* gendef: Remove unused 64 bit versions of __sjfault and __ljfault. | ||||||
|   | |||||||
| @@ -509,11 +509,11 @@ initial_env () | |||||||
|     _cygwin_testing = 1; |     _cygwin_testing = 1; | ||||||
|  |  | ||||||
| #ifdef DEBUGGING | #ifdef DEBUGGING | ||||||
|   char buf[NT_MAX_PATH]; |   char buf[PATH_MAX]; | ||||||
|   if (GetEnvironmentVariableA ("CYGWIN_DEBUG", buf, sizeof (buf) - 1)) |   if (GetEnvironmentVariableA ("CYGWIN_DEBUG", buf, sizeof (buf) - 1)) | ||||||
|     { |     { | ||||||
|       char buf1[NT_MAX_PATH]; |       char buf1[PATH_MAX]; | ||||||
|       GetModuleFileName (NULL, buf1, NT_MAX_PATH); |       GetModuleFileName (NULL, buf1, PATH_MAX); | ||||||
|       char *p = strpbrk (buf, ":="); |       char *p = strpbrk (buf, ":="); | ||||||
|       if (!p) |       if (!p) | ||||||
| 	p = (char *) "gdb.exe -nw"; | 	p = (char *) "gdb.exe -nw"; | ||||||
| @@ -521,6 +521,13 @@ initial_env () | |||||||
| 	*p++ = '\0'; | 	*p++ = '\0'; | ||||||
|       if (strcasestr (buf1, buf)) |       if (strcasestr (buf1, buf)) | ||||||
| 	{ | 	{ | ||||||
|  | 	  extern PWCHAR debugger_command; | ||||||
|  |  | ||||||
|  | 	  debugger_command = (PWCHAR) HeapAlloc (GetProcessHeap (), 0, | ||||||
|  | 						 (2 * NT_MAX_PATH + 20) | ||||||
|  | 						 * sizeof (WCHAR)); | ||||||
|  | 	  if (!debugger_command) | ||||||
|  | 	    return; | ||||||
| 	  error_start_init (p); | 	  error_start_init (p); | ||||||
| 	  jit_debug = true; | 	  jit_debug = true; | ||||||
| 	  try_to_debug (); | 	  try_to_debug (); | ||||||
| @@ -736,6 +743,7 @@ void | |||||||
| dll_crt0_0 () | dll_crt0_0 () | ||||||
| { | { | ||||||
|   wincap.init (); |   wincap.init (); | ||||||
|  |   GetModuleFileNameW (NULL, global_progname, NT_MAX_PATH); | ||||||
|   child_proc_info = get_cygwin_startup_info (); |   child_proc_info = get_cygwin_startup_info (); | ||||||
|   init_windows_system_directory (); |   init_windows_system_directory (); | ||||||
|   initial_env (); |   initial_env (); | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ details. */ | |||||||
| #include <wchar.h> | #include <wchar.h> | ||||||
| #include <sys/reent.h> | #include <sys/reent.h> | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
|  | #include <tls_pbuf.h> | ||||||
|  |  | ||||||
| extern void __stdcall check_sanity_and_sync (per_process *); | extern void __stdcall check_sanity_and_sync (per_process *); | ||||||
|  |  | ||||||
| @@ -178,7 +179,9 @@ dll_list::find_by_modname (const PWCHAR modname) | |||||||
| dll * | dll * | ||||||
| dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) | dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) | ||||||
| { | { | ||||||
|   WCHAR buf[NT_MAX_PATH]; |   /* Called under loader lock conditions so this function can't be called | ||||||
|  |      multiple times in parallel.  A static buffer is safe. */ | ||||||
|  |   static WCHAR buf[NT_MAX_PATH]; | ||||||
|   GetModuleFileNameW (h, buf, NT_MAX_PATH); |   GetModuleFileNameW (h, buf, NT_MAX_PATH); | ||||||
|   PWCHAR name = buf; |   PWCHAR name = buf; | ||||||
|   if (!wcsncmp (name, L"\\\\?\\", 4)) |   if (!wcsncmp (name, L"\\\\?\\", 4)) | ||||||
| @@ -264,7 +267,9 @@ dll_list::append (dll* d) | |||||||
|  |  | ||||||
| void dll_list::populate_deps (dll* d) | void dll_list::populate_deps (dll* d) | ||||||
| { | { | ||||||
|   WCHAR wmodname[NT_MAX_PATH]; |   tmp_pathbuf tp; | ||||||
|  |  | ||||||
|  |   PWCHAR wmodname = tp.w_get (); | ||||||
|   pefile* pef = (pefile*) d->handle; |   pefile* pef = (pefile*) d->handle; | ||||||
|   PIMAGE_DATA_DIRECTORY dd = pef->idata_dir (IMAGE_DIRECTORY_ENTRY_IMPORT); |   PIMAGE_DATA_DIRECTORY dd = pef->idata_dir (IMAGE_DIRECTORY_ENTRY_IMPORT); | ||||||
|   /* Annoyance: calling crealloc with a NULL pointer will use the |   /* Annoyance: calling crealloc with a NULL pointer will use the | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ details. */ | |||||||
| #define CALL_HANDLER_RETRY_OUTER 10 | #define CALL_HANDLER_RETRY_OUTER 10 | ||||||
| #define CALL_HANDLER_RETRY_INNER 10 | #define CALL_HANDLER_RETRY_INNER 10 | ||||||
|  |  | ||||||
| char debugger_command[2 * NT_MAX_PATH + 20]; | PWCHAR debugger_command; | ||||||
| extern u_char _sigbe; | extern u_char _sigbe; | ||||||
| extern u_char _sigdelayed_end; | extern u_char _sigdelayed_end; | ||||||
|  |  | ||||||
| @@ -112,18 +112,19 @@ extern "C" void | |||||||
| error_start_init (const char *buf) | error_start_init (const char *buf) | ||||||
| { | { | ||||||
|   if (!buf || !*buf) |   if (!buf || !*buf) | ||||||
|     { |  | ||||||
|       debugger_command[0] = '\0'; |  | ||||||
|     return; |     return; | ||||||
|     } |   if (!debugger_command && | ||||||
|  |       !(debugger_command = (PWCHAR) malloc ((2 * NT_MAX_PATH + 20) | ||||||
|  | 					    * sizeof (WCHAR)))) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|   char pgm[NT_MAX_PATH]; |   PWCHAR cp = debugger_command | ||||||
|   if (!GetModuleFileName (NULL, pgm, NT_MAX_PATH)) | 	      + sys_mbstowcs (debugger_command, NT_MAX_PATH, buf) - 1; | ||||||
|     strcpy (pgm, "cygwin1.dll"); |   cp = wcpcpy (cp, L" \""); | ||||||
|   for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\')) |   wcpcpy (cp, global_progname); | ||||||
|     *p = '/'; |   for (PWCHAR p = wcschr (cp, L'\\'); p; p = wcschr (p, L'\\')) | ||||||
|  |     *p = L'/'; | ||||||
|   __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm); |   wcscat (cp, L"\""); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -474,9 +475,9 @@ cygwin_stackdump () | |||||||
| extern "C" int | extern "C" int | ||||||
| try_to_debug (bool waitloop) | try_to_debug (bool waitloop) | ||||||
| { | { | ||||||
|   debug_printf ("debugger_command '%s'", debugger_command); |   if (!debugger_command) | ||||||
|   if (*debugger_command == '\0') |  | ||||||
|     return 0; |     return 0; | ||||||
|  |   debug_printf ("debugger_command '%W'", debugger_command); | ||||||
|   if (being_debugged ()) |   if (being_debugged ()) | ||||||
|     { |     { | ||||||
|       extern void break_here (); |       extern void break_here (); | ||||||
| @@ -484,8 +485,8 @@ try_to_debug (bool waitloop) | |||||||
|       return 0; |       return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   __small_sprintf (strchr (debugger_command, '\0'), " %u", |   PWCHAR dbg_end = wcschr (debugger_command, L'\0'); | ||||||
| 		   GetCurrentProcessId ()); |   __small_swprintf (dbg_end, L" %u", GetCurrentProcessId ()); | ||||||
|  |  | ||||||
|   LONG prio = GetThreadPriority (GetCurrentThread ()); |   LONG prio = GetThreadPriority (GetCurrentThread ()); | ||||||
|   SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); |   SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); | ||||||
| @@ -529,10 +530,8 @@ try_to_debug (bool waitloop) | |||||||
|   console_printf ("*** starting debugger for pid %u, tid %u\n", |   console_printf ("*** starting debugger for pid %u, tid %u\n", | ||||||
| 		  cygwin_pid (GetCurrentProcessId ()), GetCurrentThreadId ()); | 		  cygwin_pid (GetCurrentProcessId ()), GetCurrentThreadId ()); | ||||||
|   BOOL dbg; |   BOOL dbg; | ||||||
|   WCHAR dbg_cmd[strlen(debugger_command) + 1]; |  | ||||||
|   sys_mbstowcs (dbg_cmd, strlen(debugger_command) + 1, debugger_command); |  | ||||||
|   dbg = CreateProcessW (NULL, |   dbg = CreateProcessW (NULL, | ||||||
| 			dbg_cmd, | 			debugger_command, | ||||||
| 			NULL, | 			NULL, | ||||||
| 			NULL, | 			NULL, | ||||||
| 			FALSE, | 			FALSE, | ||||||
| @@ -542,6 +541,7 @@ try_to_debug (bool waitloop) | |||||||
| 			&si, | 			&si, | ||||||
| 			&pi); | 			&pi); | ||||||
|  |  | ||||||
|  |   *dbg_end = L'\0'; | ||||||
|   if (!dbg) |   if (!dbg) | ||||||
|     system_printf ("Failed to start debugger, %E"); |     system_printf ("Failed to start debugger, %E"); | ||||||
|   else |   else | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ UINT windows_system_directory_length; | |||||||
| WCHAR system_wow64_directory[MAX_PATH]; | WCHAR system_wow64_directory[MAX_PATH]; | ||||||
| UINT system_wow64_directory_length; | UINT system_wow64_directory_length; | ||||||
| #endif /* !__x86_64__ */ | #endif /* !__x86_64__ */ | ||||||
|  | WCHAR global_progname[NT_MAX_PATH]; | ||||||
|  |  | ||||||
| /* program exit the program */ | /* program exit the program */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -38,7 +38,9 @@ public: | |||||||
| pinfo_basic::pinfo_basic () | pinfo_basic::pinfo_basic () | ||||||
| { | { | ||||||
|   pid = dwProcessId = GetCurrentProcessId (); |   pid = dwProcessId = GetCurrentProcessId (); | ||||||
|   GetModuleFileNameW (NULL, progname, sizeof (progname) / sizeof (WCHAR)); |   PWCHAR pend = wcpncpy (progname, global_progname, | ||||||
|  | 			 sizeof (progname) / sizeof (WCHAR) - 1); | ||||||
|  |   *pend = L'\0'; | ||||||
|   /* Default uid/gid are needed very early to initialize shared user info. */ |   /* Default uid/gid are needed very early to initialize shared user info. */ | ||||||
|   uid = ILLEGAL_UID; |   uid = ILLEGAL_UID; | ||||||
|   gid = ILLEGAL_GID; |   gid = ILLEGAL_GID; | ||||||
| @@ -120,20 +122,18 @@ pinfo::status_exit (DWORD x) | |||||||
|     { |     { | ||||||
|     case STATUS_DLL_NOT_FOUND: |     case STATUS_DLL_NOT_FOUND: | ||||||
|       { |       { | ||||||
| 	char posix_prog[NT_MAX_PATH]; |  | ||||||
| 	path_conv pc; | 	path_conv pc; | ||||||
| 	if (!procinfo) | 	if (!procinfo) | ||||||
| 	   pc.check ("/dev/null"); | 	   pc.check ("/dev/null", PC_NOWARN | PC_POSIX); | ||||||
| 	else | 	else | ||||||
| 	  { | 	  { | ||||||
| 	    UNICODE_STRING uc; | 	    UNICODE_STRING uc; | ||||||
| 	    RtlInitUnicodeString(&uc, procinfo->progname); | 	    RtlInitUnicodeString(&uc, procinfo->progname); | ||||||
| 	    pc.check (&uc, PC_NOWARN); | 	    pc.check (&uc, PC_NOWARN | PC_POSIX); | ||||||
| 	  } | 	  } | ||||||
| 	mount_table->conv_to_posix_path (pc.get_win32 (), posix_prog, 1); |  | ||||||
| 	small_printf ("%s: error while loading shared libraries: %s: cannot " | 	small_printf ("%s: error while loading shared libraries: %s: cannot " | ||||||
| 		      "open shared object file: No such file or directory\n", | 		      "open shared object file: No such file or directory\n", | ||||||
| 		      posix_prog, find_first_notloaded_dll (pc)); | 		      pc.get_posix (), find_first_notloaded_dll (pc)); | ||||||
| 	x = 127 << 8; | 	x = 127 << 8; | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|   | |||||||
| @@ -85,20 +85,18 @@ __report_error (const char *msg, ...) | |||||||
|    * cygwin ptys. |    * cygwin ptys. | ||||||
|    */ |    */ | ||||||
|   char buf[128]; |   char buf[128]; | ||||||
|   WCHAR module[PATH_MAX]; |   char *posix_module = NULL; | ||||||
|   char * posix_module = NULL; |  | ||||||
|   static const char UNKNOWN_MODULE[] = "<unknown module>: "; |   static const char UNKNOWN_MODULE[] = "<unknown module>: "; | ||||||
|   static const char CYGWIN_FAILURE_MSG[] = "Cygwin runtime failure: "; |   static const char CYGWIN_FAILURE_MSG[] = "Cygwin runtime failure: "; | ||||||
|   HANDLE errh = GetStdHandle (STD_ERROR_HANDLE); |   HANDLE errh = GetStdHandle (STD_ERROR_HANDLE); | ||||||
|   ssize_t modulelen = GetModuleFileNameW (NULL, module, PATH_MAX); |  | ||||||
|   va_list args; |   va_list args; | ||||||
|  |  | ||||||
|   /* FIXME: cleanup further to avoid old use of cygwin_internal */ |   /* FIXME: cleanup further to avoid old use of cygwin_internal */ | ||||||
|   if (errh == INVALID_HANDLE_VALUE) |   if (errh == INVALID_HANDLE_VALUE) | ||||||
|     cygwin_internal (CW_EXIT_PROCESS, STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION, 1); |     cygwin_internal (CW_EXIT_PROCESS, STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION, 1); | ||||||
|  |  | ||||||
|   if (modulelen > 0) |   posix_module = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, | ||||||
|     posix_module = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, module); | 					      global_progname); | ||||||
|  |  | ||||||
|   va_start (args, msg); |   va_start (args, msg); | ||||||
|   vsnprintf (buf, sizeof (buf), msg, args); |   vsnprintf (buf, sizeof (buf), msg, args); | ||||||
|   | |||||||
| @@ -284,12 +284,6 @@ gen_decimalLL: | |||||||
| 		  dst = rnarg (dst, 16, 0, len, pad); | 		  dst = rnarg (dst, 16, 0, len, pad); | ||||||
| #endif | #endif | ||||||
| 		  break; | 		  break; | ||||||
| 		case 'P': |  | ||||||
| 		  if (!GetModuleFileName (NULL, tmp, NT_MAX_PATH)) |  | ||||||
| 		    s = "cygwin program"; |  | ||||||
| 		  else |  | ||||||
| 		    s = tmp; |  | ||||||
| 		  goto fillin; |  | ||||||
| 		case '.': | 		case '.': | ||||||
| 		  n = strtol (fmt, (char **) &fmt, 10); | 		  n = strtol (fmt, (char **) &fmt, 10); | ||||||
| 		  if (*fmt++ != 's') | 		  if (*fmt++ != 's') | ||||||
| @@ -311,6 +305,9 @@ gen_decimalLL: | |||||||
| 		    else | 		    else | ||||||
| 		      *dst++ = *s++; | 		      *dst++ = *s++; | ||||||
| 		  break; | 		  break; | ||||||
|  | 		case 'P': | ||||||
|  | 		  RtlInitUnicodeString (us = &uw, global_progname); | ||||||
|  | 		  goto wfillin; | ||||||
| 		case 'W': | 		case 'W': | ||||||
| 		  w = va_arg (ap, PWCHAR); | 		  w = va_arg (ap, PWCHAR); | ||||||
| 		  RtlInitUnicodeString (us = &uw, w ?: L"(null)"); | 		  RtlInitUnicodeString (us = &uw, w ?: L"(null)"); | ||||||
| @@ -613,10 +610,7 @@ gen_decimalLL: | |||||||
| #endif | #endif | ||||||
| 		  break; | 		  break; | ||||||
| 		case L'P': | 		case L'P': | ||||||
| 		  if (!GetModuleFileNameW (NULL, tmp, NT_MAX_PATH)) | 		  RtlInitUnicodeString (us = &uw, global_progname); | ||||||
| 		    RtlInitUnicodeString (us = &uw, L"cygwin program"); |  | ||||||
| 		  else |  | ||||||
| 		    RtlInitUnicodeString (us = &uw, tmp); |  | ||||||
| 		  goto fillin; | 		  goto fillin; | ||||||
| 		case L'.': | 		case L'.': | ||||||
| 		  n = wcstoul (fmt, (wchar_t **) &fmt, 10); | 		  n = wcstoul (fmt, (wchar_t **) &fmt, 10); | ||||||
|   | |||||||
| @@ -21,9 +21,13 @@ details. */ | |||||||
| #include "dtable.h" | #include "dtable.h" | ||||||
| #include "cygheap.h" | #include "cygheap.h" | ||||||
| #include "child_info.h" | #include "child_info.h" | ||||||
|  | #include "sync.h" | ||||||
|  |  | ||||||
| #define PROTECT(x) x[sizeof (x)-1] = 0 | #define PROTECT(x) {x[NT_MAX_PATH - 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[NT_MAX_PATH - 1] != '\0') \ | ||||||
|  | 		   { small_printf ("array bound exceeded %d\n", __LINE__); \ | ||||||
|  | 		     ExitProcess (1); \ | ||||||
|  | 		   } | ||||||
|  |  | ||||||
| class strace NO_COPY strace; | class strace NO_COPY strace; | ||||||
|  |  | ||||||
| @@ -35,25 +39,25 @@ strace::activate (bool isfork) | |||||||
|   if (!_active && being_debugged ()) |   if (!_active && being_debugged ()) | ||||||
|     { |     { | ||||||
|       char buf[30]; |       char buf[30]; | ||||||
|       __small_sprintf (buf, "cYg%8x %lx %d", _STRACE_INTERFACE_ACTIVATE_ADDR, &_active, isfork); |       __small_sprintf (buf, "cYg%8x %lx %d", | ||||||
|  | 		       _STRACE_INTERFACE_ACTIVATE_ADDR, &_active, isfork); | ||||||
|       OutputDebugString (buf); |       OutputDebugString (buf); | ||||||
|       if (_active) |       if (_active) | ||||||
| 	{ | 	{ | ||||||
| 	  char pidbuf[80]; | 	  char pidbuf[80]; | ||||||
| 	  WCHAR progname_buf[NT_MAX_PATH - 512]; | 	  PWCHAR progname; | ||||||
| 	  WCHAR *progname; |  | ||||||
| 	  if (myself) | 	  if (myself) | ||||||
| 	    { | 	    { | ||||||
| 	      __small_sprintf (pidbuf, "(pid %d, ppid %d, windows pid %u)", myself->pid, | 	      __small_sprintf (pidbuf, "(pid %d, ppid %d, windows pid %u)", | ||||||
| 			       myself->ppid ?: 1, GetCurrentProcessId ()); | 			       myself->pid, myself->ppid ?: 1, | ||||||
|  | 			       GetCurrentProcessId ()); | ||||||
| 	      progname = myself->progname; | 	      progname = myself->progname; | ||||||
| 	    } | 	    } | ||||||
| 	  else | 	  else | ||||||
| 	    { | 	    { | ||||||
| 	      GetModuleFileNameW (NULL, progname_buf, | 	      __small_sprintf (pidbuf, "(windows pid %u)", | ||||||
| 	      			  sizeof progname_buf / sizeof (WCHAR)); | 			       GetCurrentProcessId ()); | ||||||
| 	      __small_sprintf (pidbuf, "(windows pid %u)", GetCurrentProcessId ()); | 	      progname = global_progname; | ||||||
| 	      progname = progname_buf; |  | ||||||
| 	    } | 	    } | ||||||
| 	  prntf (1, NULL, "**********************************************"); | 	  prntf (1, NULL, "**********************************************"); | ||||||
| 	  prntf (1, NULL, "Program name: %W %s", progname, pidbuf); | 	  prntf (1, NULL, "Program name: %W %s", progname, pidbuf); | ||||||
| @@ -151,32 +155,32 @@ strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap) | |||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       PWCHAR pn = NULL; |       PWCHAR pn = NULL; | ||||||
|       WCHAR progname[NT_MAX_PATH]; |       WCHAR progname[NAME_MAX]; | ||||||
|       if (!cygwin_finished_initializing) |       if (cygwin_finished_initializing && __progname) | ||||||
| 	pn = (myself) ? myself->progname : NULL; | 	{ | ||||||
|       else if (__progname) | 	  char *p = strrchr (__progname, '/'); | ||||||
| 	sys_mbstowcs(pn = progname, NT_MAX_PATH, __progname); | 	  if (p) | ||||||
|  | 	    ++p; | ||||||
|       WCHAR empty[1] = {}; |  | ||||||
|       PWCHAR p; |  | ||||||
|       if (!pn) |  | ||||||
| 	GetModuleFileNameW (NULL, pn = progname, sizeof (progname)); |  | ||||||
|       if (!pn) |  | ||||||
| 	p = empty; |  | ||||||
|       else if ((p = wcsrchr (pn, L'\\')) != NULL) |  | ||||||
| 	p++; |  | ||||||
|       else if ((p = wcsrchr (pn, L'/')) != NULL) |  | ||||||
| 	p++; |  | ||||||
| 	  else | 	  else | ||||||
| 	p = pn; | 	    p = __progname; | ||||||
|       if (p != progname) | 	  char *pe = strrchr (p, '.'); | ||||||
| 	wcscpy (progname, p); | 	  if (!pe || !ascii_strcasematch (pe, ".exe")) | ||||||
|       if ((p = wcsrchr (progname, '.')) != NULL | 	    pe = strrchr (p, '\0'); | ||||||
| 	  && !wcscasecmp (p, L".exe")) | 	  sys_mbstowcs (pn = progname, NAME_MAX, p, pe - p); | ||||||
| 	*p = '\000'; | 	} | ||||||
|       p = progname; |       else | ||||||
|  | 	{ | ||||||
|  | 	  PWCHAR p = wcsrchr (global_progname, L'\\'); | ||||||
|  | 	  ++p; | ||||||
|  | 	  PWCHAR pe = wcsrchr (p, '.'); | ||||||
|  | 	  if (!pe || wcscasecmp (pe, L".exe")) | ||||||
|  | 	    pe = wcsrchr (p, L'\0'); | ||||||
|  | 	  pe = wcpncpy (progname, p, pe - p); | ||||||
|  | 	  *pe = L'\0'; | ||||||
|  | 	  pn = progname; | ||||||
|  | 	} | ||||||
|       char tmpbuf[20]; |       char tmpbuf[20]; | ||||||
|       count = __small_sprintf (buf, fmt, *p ? p : L"?", mypid (tmpbuf), |       count = __small_sprintf (buf, fmt, pn, mypid (tmpbuf), | ||||||
| 			       execing ? "!" : ""); | 			       execing ? "!" : ""); | ||||||
|       if (func) |       if (func) | ||||||
| 	count += getfunc (buf + count, func); | 	count += getfunc (buf + count, func); | ||||||
| @@ -235,14 +239,22 @@ strace::write_childpid (pid_t pid) | |||||||
|  |  | ||||||
| /* 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! */ | ||||||
|  | static NO_COPY muto strace_buf_guard; | ||||||
|  | static NO_COPY char *buf; | ||||||
|  |  | ||||||
| void | void | ||||||
| strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap) | strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap) | ||||||
| { | { | ||||||
|   DWORD err = GetLastError (); |   DWORD err = GetLastError (); | ||||||
|   int len; |   int len; | ||||||
|   char buf[NT_MAX_PATH]; |  | ||||||
|  |  | ||||||
|  |   strace_buf_guard.init ("smallprint_buf")->acquire (); | ||||||
|  |   /* Creating buffer on Windows process heap to drop stack pressure and | ||||||
|  |      keeping our .bss small. */ | ||||||
|  |   if (!buf) | ||||||
|  |     buf = (char *) HeapAlloc (GetProcessHeap (), 0, NT_MAX_PATH); | ||||||
|  |   if (!buf) | ||||||
|  |     return; | ||||||
|   PROTECT (buf); |   PROTECT (buf); | ||||||
|   SetLastError (err); |   SetLastError (err); | ||||||
|  |  | ||||||
| @@ -272,6 +284,7 @@ strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap | |||||||
|   if (active ()) |   if (active ()) | ||||||
|     write (category, buf, len); |     write (category, buf, len); | ||||||
| #endif | #endif | ||||||
|  |   strace_buf_guard.release (); | ||||||
|   SetLastError (err); |   SetLastError (err); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -192,19 +192,17 @@ wow64_revert_to_original_stack (PVOID &allocationbase) | |||||||
| void | void | ||||||
| wow64_respawn_process () | wow64_respawn_process () | ||||||
| { | { | ||||||
|   WCHAR path[PATH_MAX]; |  | ||||||
|   PROCESS_INFORMATION pi; |   PROCESS_INFORMATION pi; | ||||||
|   STARTUPINFOW si; |   STARTUPINFOW si; | ||||||
|   DWORD ret = 0; |   DWORD ret = 0; | ||||||
|  |  | ||||||
|   GetModuleFileNameW (NULL, path, PATH_MAX); |  | ||||||
|   GetStartupInfoW (&si); |   GetStartupInfoW (&si); | ||||||
|   if (!CreateProcessW (path, GetCommandLineW (), NULL, NULL, TRUE, |   if (!CreateProcessW (global_progname, GetCommandLineW (), NULL, NULL, TRUE, | ||||||
| 		       CREATE_DEFAULT_ERROR_MODE | 		       CREATE_DEFAULT_ERROR_MODE | ||||||
| 		       | GetPriorityClass (GetCurrentProcess ()), | 		       | GetPriorityClass (GetCurrentProcess ()), | ||||||
| 		       NULL, NULL, &si, &pi)) | 		       NULL, NULL, &si, &pi)) | ||||||
|     api_fatal ("Failed to create process <%W> <%W>, %E", |     api_fatal ("Failed to create process <%W> <%W>, %E", | ||||||
| 	       path, GetCommandLineW ()); | 	       global_progname, GetCommandLineW ()); | ||||||
|   CloseHandle (pi.hThread); |   CloseHandle (pi.hThread); | ||||||
|   if (WaitForSingleObject (pi.hProcess, INFINITE) == WAIT_FAILED) |   if (WaitForSingleObject (pi.hProcess, INFINITE) == WAIT_FAILED) | ||||||
|     api_fatal ("Waiting for process %u failed, %E", pi.dwProcessId); |     api_fatal ("Waiting for process %u failed, %E", pi.dwProcessId); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user