Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/utils/strace.cc')
-rw-r--r--winsup/utils/strace.cc657
1 files changed, 0 insertions, 657 deletions
diff --git a/winsup/utils/strace.cc b/winsup/utils/strace.cc
deleted file mode 100644
index 58547ed4a..000000000
--- a/winsup/utils/strace.cc
+++ /dev/null
@@ -1,657 +0,0 @@
-/* strace.cc
-
- Copyright 2000, 2001 Red Hat Inc.
-
- Written by Chris Faylor <cgf@redhat.com>
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#include <windows.h>
-#include <signal.h>
-#include "sys/strace.h"
-
-/* GCC runtime library's C++ EH code unfortunately pulls in stdio, and we
- get undefine references to __impure_ptr, and hence the following
- hack. It should be reasonably safe however as long as this file
- is built using -mno-cygwin as is intended. */
-int _impure_ptr;
-
-/* we *know* we're being built with GCC */
-#define alloca __builtin_alloca
-
-static const char *pgm;
-static int forkdebug = 0;
-static int numerror = 1;
-static int usecs = 1;
-static int delta = 1;
-static int hhmmss = 0;
-static int bufsize = 0;
-
-static BOOL close_handle (HANDLE h, DWORD ok);
-
-#define CloseHandle(h) close_handle(h, 0)
-
-struct child_list
-{
- DWORD id;
- HANDLE hproc;
- int saw_stars;
- char nfields;
- long long start_time;
- DWORD last_usecs;
- struct child_list *next;
- child_list ():id (0), hproc (NULL), saw_stars (0), nfields (0),
- start_time (0), last_usecs (0), next (NULL)
- {
- }
-};
-
-child_list children;
-
-static void
-warn (int geterrno, const char *fmt, ...)
-{
- va_list args;
- char buf[4096];
-
- va_start (args, fmt);
- sprintf (buf, "%s: ", pgm);
- vsprintf (strchr (buf, '\0'), fmt, args);
- if (geterrno)
- perror (buf);
- else
- {
- fputs (buf, stderr);
- fputs ("\n", stderr);
- }
-}
-
-static void __attribute__ ((noreturn))
-error (int geterrno, const char *fmt, ...)
-{
- va_list args;
- char buf[4096];
-
- va_start (args, fmt);
- sprintf (buf, "%s: ", pgm);
- vsprintf (strchr (buf, '\0'), fmt, args);
- if (geterrno)
- perror (buf);
- else
- {
- fputs (buf, stderr);
- fputs ("\n", stderr);
- }
- ExitProcess (1);
-}
-
-DWORD lastid = 0;
-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 = new (child_list);
- children.next->next = c;
- lastid = children.next->id = id;
- HANDLE me = GetCurrentProcess ();
- lasth = children.next->hproc = hproc;
-}
-
-static child_list *
-get_child (DWORD id)
-{
- child_list *c;
- for (c = &children; (c = c->next) != NULL;)
- if (c->id == id)
- return c;
-
- error (0, "no process id %d found", id);
-}
-
-static void
-remove_child (DWORD id)
-{
- child_list *c;
- if (id == lastid)
- lastid = 0;
- for (c = &children; c->next != NULL; c = c->next)
- if (c->next->id == id)
- {
- child_list *c1 = c->next;
- c->next = c1->next;
- delete c1;
- return;
- }
-
- error (0, "no process id %d found", id);
-}
-
-#define LINE_BUF_CHUNK 128
-
-class linebuf
-{
- size_t alloc;
-public:
- size_t ix;
- char *buf;
- linebuf ()
- {
- ix = 0;
- alloc = 0;
- buf = NULL;
- }
- ~linebuf ()
- {
- if (buf)
- free (buf);
- }
- void add (const char *what, int len);
- void add (const char *what)
- {
- add (what, strlen (what));
- }
- void prepend (const char *what, int len);
-};
-
-void
-linebuf::add (const char *what, int len)
-{
- size_t newix;
- if ((newix = ix + len) >= alloc)
- {
- alloc += LINE_BUF_CHUNK + len;
- buf = (char *) realloc (buf, alloc + 1);
- }
- memcpy (buf + ix, what, len);
- ix = newix;
- buf[ix] = '\0';
-}
-
-void
-linebuf::prepend (const char *what, int len)
-{
- int buflen;
- size_t newix;
- if ((newix = ix + len) >= alloc)
- {
- alloc += LINE_BUF_CHUNK + len;
- buf = (char *) realloc (buf, alloc + 1);
- buf[ix] = '\0';
- }
- if ((buflen = strlen (buf)))
- memmove (buf + len, buf, buflen + 1);
- else
- buf[newix] = '\0';
- memcpy (buf, what, len);
- ix = newix;
-}
-
-static void
-make_command_line (linebuf & one_line, char **argv)
-{
- for (; *argv; argv++)
- {
- char *p = NULL;
- const char *a = *argv;
-
- int len = strlen (a);
- if (len != 0 && !(p = strpbrk (a, " \t\n\r\"")))
- one_line.add (a, len);
- else
- {
- one_line.add ("\"", 1);
- for (; p; a = p, p = strchr (p, '"'))
- {
- one_line.add (a, ++p - a);
- if (p[-1] == '"')
- one_line.add ("\"", 1);
- }
- if (*a)
- one_line.add (a);
- one_line.add ("\"", 1);
- }
- one_line.add (" ", 1);
- }
-
- if (one_line.ix)
- one_line.buf[one_line.ix - 1] = '\0';
- else
- one_line.add ("", 1);
-}
-
-static DWORD child_pid;
-
-static BOOL WINAPI
-ctrl_c (DWORD)
-{
- static int tic = 1;
- if ((tic ^= 1) && !GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0))
- error (0, "couldn't send CTRL-C to child, win32 error %d\n",
- GetLastError ());
- return TRUE;
-}
-
-static void
-create_child (char **argv)
-{
- linebuf one_line;
-
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- BOOL ret;
- DWORD flags;
-
- if (!*argv)
- error (0, "no program argument specified");
-
- memset (&si, 0, sizeof (si));
- si.cb = sizeof (si);
-
- /* cygwin32_conv_to_win32_path (exec_file, real_path); */
-
- flags = forkdebug ? 0 : DEBUG_ONLY_THIS_PROCESS;
- flags |=
- /*CREATE_NEW_PROCESS_GROUP | */ CREATE_DEFAULT_ERROR_MODE | DEBUG_PROCESS;
-
- make_command_line (one_line, argv);
-
- SetConsoleCtrlHandler (NULL, 0);
- ret = CreateProcess (0, one_line.buf, /* command line */
- NULL, /* Security */
- NULL, /* thread */
- TRUE, /* inherit handles */
- flags, /* start flags */
- NULL, NULL, /* current directory */
- &si, &pi);
- if (!ret)
- error (0, "error creating process %s, (error %d)", *argv,
- GetLastError ());
-
- CloseHandle (pi.hThread);
- CloseHandle (pi.hProcess);
- child_pid = pi.dwProcessId;
- SetConsoleCtrlHandler (ctrl_c, 1);
-}
-
-static int
-output_winerror (FILE *ofile, char *s)
-{
- char *winerr = strstr (s, "Win32 error ");
- if (!winerr)
- return 0;
-
- DWORD errnum = atoi (winerr + sizeof ("Win32 error ") - 1);
- if (!errnum)
- return 0;
-
- /*
- * NOTE: Currently there is no policy for how long the
- * the buffers are, and looks like 256 is a smallest one
- * (dlfcn.cc). Other than error 1395 (length 213) and
- * error 1015 (length 249), the rest are all under 188
- * characters, and so I'll use 189 as the buffer length.
- * For those longer error messages, FormatMessage will
- * return FALSE, and we'll get the old behaviour such as
- * ``Win32 error 1395'' etc.
- */
- char buf[4096];
- if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
- | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- errnum,
- MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) buf, sizeof (buf), NULL))
- return 0;
-
- /* Get rid the trailing CR/NL pair. */
- char *p = strchr (buf, '\0');
- p[-2] = '\n';
- p[-1] = '\0';
-
- *winerr = '\0';
- fputs (s, ofile);
- fputs (buf, ofile);
- return 1;
-}
-
-static SYSTEMTIME *
-syst (long long t)
-{
- FILETIME n;
- static SYSTEMTIME st;
- long long now = t + ((long long) usecs * 10);
- n.dwHighDateTime = now >> 32;
- n.dwLowDateTime = now & 0xffffffff;
- FileTimeToSystemTime (&n, &st);
- return &st;
-}
-
-static void __stdcall
-handle_output_debug_string (DWORD id, LPVOID p, unsigned mask, FILE *ofile)
-{
- int len;
- int special;
- char alen[3 + 8 + 1];
- DWORD nbytes;
- child_list *child = get_child (id);
- HANDLE hchild = child->hproc;
-#define INTROLEN (sizeof (alen) - 1)
-
- if (id == lastid && hchild != lasth)
- warn (0, "%p != %p", hchild, lasth);
-
- alen[INTROLEN] = '\0';
- if (!ReadProcessMemory (hchild, p, alen, INTROLEN, &nbytes))
-#ifndef DEBUGGING
- return;
-#else
- error (0,
- "couldn't get message length from subprocess %d<%p>, windows error %d",
- id, hchild, GetLastError ());
-#endif
-
- if (strncmp (alen, "cYg", 3))
- return;
- len = (int) strtoul (alen + 3, NULL, 16);
- if (!len)
- return;
-
- if (len > 0)
- special = 0;
- else
- {
- special = len;
- if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
- len = 17;
- }
-
- char *buf;
- buf = (char *) alloca (len + 65) + 10;
-
- if (!ReadProcessMemory (hchild, ((char *) p) + INTROLEN, buf, len, &nbytes))
- error (0, "couldn't get message from subprocess, windows error %d",
- GetLastError ());
-
- buf[len] = '\0';
- char *s = strtok (buf, " ");
-
- unsigned n = strtoul (s, NULL, 16);
-
- s = strchr (s, '\0') + 1;
-
- if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
- {
- DWORD new_flag = 1;
- if (!WriteProcessMemory (hchild, (LPVOID) n, &new_flag,
- sizeof (new_flag), &nbytes))
- error (0,
- "couldn't write strace flag to subprocess, windows error %d",
- GetLastError ());
- return;
- }
-
- char *origs = s;
-
- if (mask & n)
- /* got it */ ;
- else if (!(mask & _STRACE_ALL) || (n & _STRACE_NOTALL))
- return; /* This should not be included in "all" output */
-
- DWORD dusecs, usecs;
- char *ptusec, *ptrest;
-
- dusecs = strtoul (s, &ptusec, 10);
- char *q = ptusec;
- while (*q == ' ')
- q++;
- if (*q != '[')
- {
- usecs = strtoul (q, &ptrest, 10);
- while (*ptrest == ' ')
- ptrest++;
- }
- else
- {
- ptrest = q;
- ptusec = s;
- usecs = dusecs;
- }
-
- if (child->saw_stars == 0)
- {
- FILETIME st;
- char *news;
-
- GetSystemTimeAsFileTime (&st);
- FileTimeToLocalFileTime (&st, &st);
- child->start_time = st.dwHighDateTime;
- child->start_time <<= 32;
- child->start_time |= st.dwLowDateTime;
- if (*(news = ptrest) != '[')
- child->saw_stars = 2;
- else
- {
- child->saw_stars++;
- while ((news = strchr (news, ' ')) != NULL && *++news != '*')
- child->nfields++;
- if (news == NULL)
- child->saw_stars++;
- else
- {
- s = news;
- child->nfields++;
- }
- }
- }
- else if (child->saw_stars < 2)
- {
- int i;
- char *news;
- if (*(news = ptrest) != '[')
- child->saw_stars = 2;
- else
- {
- for (i = 0; i < child->nfields; i++)
- if ((news = strchr (news, ' ')) == NULL)
- break; // Should never happen
- else
- news++;
-
- if (news == NULL)
- child->saw_stars = 2;
- else
- {
- s = news;
- if (*s == '*')
- {
- SYSTEMTIME *st = syst (child->start_time);
- fprintf (ofile,
- "Date/Time: %d-%02d-%02d %02d:%02d:%02d\n",
- st->wYear, st->wMonth, st->wDay, st->wHour,
- st->wMinute, st->wSecond);
- child->saw_stars++;
- }
- }
- }
- }
-
- long long d = usecs - child->last_usecs;
- char intbuf[40];
-
- if (child->saw_stars < 2 || s != origs)
- /* Nothing */ ;
- else if (hhmmss)
- {
- s = ptrest - 9;
- SYSTEMTIME *st = syst (child->start_time + (long long) usecs * 10);
- sprintf (s, "%02d:%02d:%02d", st->wHour, st->wMinute, st->wSecond);
- *strchr (s, '\0') = ' ';
- }
- else if (!delta)
- s = ptusec;
- else
- {
- s = ptusec;
- sprintf (intbuf, "%5d ", (int) d);
- int len = strlen (intbuf);
-
- memcpy ((s -= len), intbuf, len);
- }
-
- child->last_usecs = usecs;
- if (numerror || !output_winerror (ofile, s))
- fputs (s, ofile);
- if (!bufsize)
- fflush (ofile);
-}
-
-static void
-proc_child (unsigned mask, FILE *ofile)
-{
- DEBUG_EVENT ev;
- int processes = 0;
- SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
- while (1)
- {
- BOOL debug_event = WaitForDebugEvent (&ev, 1000);
- DWORD status = DBG_CONTINUE;
- if (!debug_event)
- continue;
-
- switch (ev.dwDebugEventCode)
- {
- case CREATE_PROCESS_DEBUG_EVENT:
- if (ev.u.CreateProcessInfo.hFile)
- CloseHandle (ev.u.CreateProcessInfo.hFile);
- add_child (ev.dwProcessId, ev.u.CreateProcessInfo.hProcess);
- processes++;
- break;
-
- case CREATE_THREAD_DEBUG_EVENT:
- break;
-
- case LOAD_DLL_DEBUG_EVENT:
- if (ev.u.LoadDll.hFile)
- CloseHandle (ev.u.LoadDll.hFile);
- break;
-
- case OUTPUT_DEBUG_STRING_EVENT:
- handle_output_debug_string (ev.dwProcessId,
- ev.u.DebugString.lpDebugStringData,
- mask, ofile);
- break;
-
- case EXIT_PROCESS_DEBUG_EVENT:
- remove_child (ev.dwProcessId);
- break;
- case EXCEPTION_DEBUG_EVENT:
- if (ev.u.Exception.ExceptionRecord.ExceptionCode !=
- STATUS_BREAKPOINT)
- {
- status = DBG_EXCEPTION_NOT_HANDLED;
-#if 0
- fprintf (stderr, "exception %p at %p\n",
- ev.u.Exception.ExceptionRecord.ExceptionCode,
- ev.u.Exception.ExceptionRecord.ExceptionAddress);
-#endif
- }
- break;
- }
- if (!ContinueDebugEvent (ev.dwProcessId, ev.dwThreadId, status))
- error (0, "couldn't continue debug event, windows error %d",
- GetLastError ());
- if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT && --processes == 0)
- break;
- }
-}
-
-static void
-dostrace (unsigned mask, FILE *ofile, char **argv)
-{
- create_child (argv);
- proc_child (mask, ofile);
-
- return;
-}
-
-int
-main (int argc, char **argv)
-{
- unsigned mask = 0;
- FILE *ofile = NULL;
- int opt;
-
- if (!(pgm = strrchr (*argv, '\\')) && !(pgm = strrchr (*argv, '/')))
- pgm = *argv;
- else
- pgm++;
-
- while ((opt = getopt (argc, argv, "b:m:o:fndut")) != EOF)
- switch (opt)
- {
- case 'f':
- forkdebug ^= 1;
- break;
- case 'b':
- bufsize = atoi (optarg);
- break;
- case 'm':
- mask = strtoul (optarg, NULL, 16);
- break;
- case 'o':
- if ((ofile = fopen (optarg, "w")) == NULL)
- error (1, "can't open %s", optarg);
-#ifdef F_SETFD
- (void) fcntl (fileno (ofile), F_SETFD, 0);
-#endif
- break;
- case 'n':
- numerror ^= 1;
- break;
- case 't':
- hhmmss ^= 1;
- break;
- case 'd':
- delta ^= 1;
- break;
- case 'u':
- usecs ^= 1;
- }
-
- if (!mask)
- mask = 1;
-
- if (bufsize)
- setvbuf (ofile, (char *) alloca (bufsize), _IOFBF, bufsize);
-
- if (!ofile)
- ofile = stdout;
-
- dostrace (mask, ofile, argv + optind);
-}
-
-#undef CloseHandle
-
-static BOOL
-close_handle (HANDLE h, DWORD ok)
-{
- child_list *c;
- for (c = &children; (c = c->next) != NULL;)
- if (c->hproc == h && c->id != ok)
- error (0, "Closing child handle %p", h);
- return CloseHandle (h);
-}