⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strace.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
	      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 voidproc_child (unsigned mask, FILE *ofile, pid_t pid){  DEBUG_EVENT ev;  int processes = 0;  time_t cur_time, last_time;  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);  last_time = time (NULL);  while (1)    {      BOOL debug_event = WaitForDebugEvent (&ev, 1000);      DWORD status = DBG_CONTINUE;      if (bufsize && flush_period > 0 &&	  (cur_time = time (NULL)) >= last_time + flush_period)	{	  last_time = cur_time;	  fflush (ofile);	}      if (!debug_event)	continue;      if (pid)	{	  (void) cygwin_internal (CW_STRACE_TOGGLE, pid);	  pid = 0;	}      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 voiddotoggle (pid_t pid){  load_cygwin ();  child_pid = (DWORD) cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);  if (!child_pid)    {      warn (0, "no such cygwin pid - %d", pid);      child_pid = pid;    }  if (cygwin_internal (CW_STRACE_TOGGLE, child_pid))    error (0, "failed to toggle tracing for process %d<%d>", pid, child_pid);  return;}static voiddostrace (unsigned mask, FILE *ofile, pid_t pid, char **argv){  if (!pid)    create_child (argv);  else    attach_process (pid);  proc_child (mask, ofile, pid);  return;}typedef struct tag_mask_mnemonic{  unsigned long val;  const char *text;}mask_mnemonic;static const mask_mnemonic mnemonic_table[] = {  {_STRACE_ALL, "all"},  {_STRACE_FLUSH, "flush"},  {_STRACE_INHERIT, "inherit"},  {_STRACE_UHOH, "uhoh"},  {_STRACE_SYSCALL, "syscall"},  {_STRACE_STARTUP, "startup"},  {_STRACE_DEBUG, "debug"},  {_STRACE_PARANOID, "paranoid"},  {_STRACE_TERMIOS, "termios"},  {_STRACE_SELECT, "select"},  {_STRACE_WM, "wm"},  {_STRACE_SIGP, "sigp"},  {_STRACE_MINIMAL, "minimal"},  {_STRACE_EXITDUMP, "exitdump"},  {_STRACE_SYSTEM, "system"},  {_STRACE_NOMUTEX, "nomutex"},  {_STRACE_MALLOC, "malloc"},  {_STRACE_THREAD, "thread"},  {0, NULL}};static unsigned longmnemonic2ul (const char *nptr, char **endptr){  // Look up mnemonic in table, return value.  // *endptr = ptr to char that breaks match.  const mask_mnemonic *mnp = mnemonic_table;  while (mnp->text != NULL)    {      if (strcmp (mnp->text, nptr) == 0)	{	  // Found a match.	  if (endptr != NULL)	    {	      *endptr = ((char *) nptr) + strlen (mnp->text);	    }	  return mnp->val;	}      mnp++;    }  // Didn't find it.  if (endptr != NULL)    {      *endptr = (char *) nptr;    }  return 0;}static unsigned longparse_mask (const char *ms, char **endptr){  const char *p = ms;  char *newp;  unsigned long retval = 0, thisval;  const size_t bufsize = 16;  char buffer[bufsize];  size_t len;  while (*p != '\0')    {      // First extract the term, terminate it, and lowercase it.      strncpy (buffer, p, bufsize);      buffer[bufsize - 1] = '\0';      len = strcspn (buffer, "+,\0");      buffer[len] = '\0';      strlwr (buffer);      // Check if this is a mnemonic.  We have to do this first or strtoul()      // will false-trigger on anything starting with "a" through "f".      thisval = mnemonic2ul (buffer, &newp);      if (buffer == newp)	{	  // This term isn't mnemonic, check if it's hex.	  thisval = strtoul (buffer, &newp, 16);	  if (newp != buffer + len)	    {	      // Not hex either, syntax error.	      *endptr = (char *) p;	      return 0;	    }	}      p += len;      retval += thisval;      // Handle operators      if (*p == '\0')	break;      if ((*p == '+') || (*p == ','))	{	  // For now these both equate to addition/ORing.  Until we get	  // fancy and add things like "all-<something>", all we need do is	  // continue the looping.	  p++;	  continue;	}      else	{	  // Syntax error	  *endptr = (char *) p;	  return 0;	}    }  *endptr = (char *) p;  return retval;}static voidusage (FILE *where = stderr){  fprintf (where, "\Usage: %s [OPTIONS] <command-line>\n\Usage: %s [OPTIONS] -p <pid>\n\  -b, --buffer-size=SIZE       set size of output file buffer\n\  -d, --no-delta               don't display the delta-t microsecond timestamp\n\  -f, --trace-children         trace child processes (toggle - default true)\n\  -h, --help                   output usage information and exit\n\  -m, --mask=MASK              set message filter mask\n\  -n, --crack-error-numbers    output descriptive text instead of error\n\                               numbers for Windows errors\n\  -o, --output=FILENAME        set output file to FILENAME\n\  -p, --pid=n                  attach to executing program with cygwin pid n\n\  -S, --flush-period=PERIOD    flush buffered strace output every PERIOD secs\n\  -t, --timestamp              use an absolute hh:mm:ss timestamp insted of \n\                               the default microsecond timestamp.  Implies -d\n\  -T, --toggle                 toggle tracing in a process already being\n\                               traced. Requires -p <pid>\n\  -v, --version                output version information and exit\n\  -w, --new-window             spawn program under test in a new window\n\\n", pgm, pgm);  if ( where == stdout)    fprintf (stdout, "\    MASK can be any combination of the following mnemonics and/or hex values\n\    (0x is optional).  Combine masks with '+' or ',' like so:\n\\n\                      --mask=wm+system,malloc+0x00800\n\\n\    Mnemonic Hex     Corresponding Def  Description\n\    =========================================================================\n\    all      0x00001 (_STRACE_ALL)      All strace messages.\n\    flush    0x00002 (_STRACE_FLUSH)    Flush output buffer after each message.\n\    inherit  0x00004 (_STRACE_INHERIT)  Children inherit mask from parent.\n\    uhoh     0x00008 (_STRACE_UHOH)     Unusual or weird phenomenon.\n\    syscall  0x00010 (_STRACE_SYSCALL)  System calls.\n\    startup  0x00020 (_STRACE_STARTUP)  argc/envp printout at startup.\n\    debug    0x00040 (_STRACE_DEBUG)    Info to help debugging. \n\    paranoid 0x00080 (_STRACE_PARANOID) Paranoid info.\n\    termios  0x00100 (_STRACE_TERMIOS)  Info for debugging termios stuff.\n\    select   0x00200 (_STRACE_SELECT)   Info on ugly select internals.\n\    wm       0x00400 (_STRACE_WM)       Trace Windows msgs (enable _strace_wm).\n\    sigp     0x00800 (_STRACE_SIGP)     Trace signal and process handling.\n\    minimal  0x01000 (_STRACE_MINIMAL)  Very minimal strace output.\n\    exitdump 0x04000 (_STRACE_EXITDUMP) Dump strace cache on exit.\n\    system   0x08000 (_STRACE_SYSTEM)   Serious error; goes to console and log.\n\    nomutex  0x10000 (_STRACE_NOMUTEX)  Don't use mutex for synchronization.\n\    malloc   0x20000 (_STRACE_MALLOC)   Trace malloc calls.\n\    thread   0x40000 (_STRACE_THREAD)   Thread-locking calls.\n\");  if (where == stderr)    fprintf (stderr, "Try '%s --help' for more information.\n", pgm);  exit (where == stderr ? 1 : 0 );}struct option longopts[] = {  {"buffer-size", required_argument, NULL, 'b'},  {"help", no_argument, NULL, 'h'},  {"flush-period", required_argument, NULL, 'S'},  {"mask", required_argument, NULL, 'm'},  {"new-window", no_argument, NULL, 'w'},  {"output", required_argument, NULL, 'o'},  {"no-delta", no_argument, NULL, 'd'},  {"pid", required_argument, NULL, 'p'},  {"timestamp", no_argument, NULL, 't'},  {"toggle", no_argument, NULL, 'T'},  {"trace-children", no_argument, NULL, 'f'},  {"translate-error-numbers", no_argument, NULL, 'n'},  {"usecs", no_argument, NULL, 'u'},  {"version", no_argument, NULL, 'v'},  {NULL, 0, NULL, 0}};static const char *const opts = "b:dhfm:no:p:S:tTuvw";static voidprint_version (){  const char *v = strchr (version, ':');  int len;  if (!v)    {      v = "?";      len = 1;    }  else    {      v += 2;      len = strchr (v, ' ') - v;    }  printf ("\%s (cygwin) %.*s\n\System Trace\n\Copyright 2000, 2001, 2002 Red Hat, Inc.\n\Compiled on %s\n\", pgm, len, v, __DATE__);}intmain (int argc, char **argv){  unsigned mask = 0;  FILE *ofile = NULL;  pid_t pid = 0;  int opt;  int toggle = 0;  if (!(pgm = strrchr (*argv, '\\')) && !(pgm = strrchr (*argv, '/')))    pgm = *argv;  else    pgm++;  while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)    switch (opt)      {      case 'b':	bufsize = atoi (optarg);	break;      case 'd':	delta ^= 1;	break;      case 'f':	forkdebug ^= 1;	break;      case 'h':	// Print help and exit	usage (stdout);	break;      case 'm':	{	  char *endptr;	  mask = parse_mask (optarg, &endptr);	  if (*endptr != '\0')	    {	      // Bad mask expression.	      error (0, "syntax error in mask expression \"%s\" near \character #%d.\n", optarg, (int) (endptr - optarg), endptr);	    }	  break;	}      case 'n':	numerror ^= 1;	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 'p':	pid = strtoul (optarg, NULL, 10);	break;      case 'S':	flush_period = strtoul (optarg, NULL, 10);	break;      case 't':	hhmmss ^= 1;	break;      case 'T':	toggle ^= 1;	break;      case 'u':	// FIXME: currently unimplemented	usecs ^= 1;	break;      case 'v':	// Print version info and exit	print_version ();	return 0;      case 'w':	new_window ^= 1;	break;      case '?':	fprintf (stderr, "Try '%s --help' for more information.\n", pgm);	exit (1);      }  if (pid && argv[optind])    error (0, "cannot provide both a command line and a process id");  if (!pid && !argv[optind])    error (0, "must provide either a command line or a process id");  if (toggle && !pid)    error (0, "must provide a process id to toggle tracing");  if (!mask)    mask = 1;  if (bufsize)    setvbuf (ofile, (char *) alloca (bufsize), _IOFBF, bufsize);  if (!ofile)    ofile = stdout;  if (toggle)    dotoggle (pid);  else    dostrace (mask, ofile, pid, argv + optind);}#undef CloseHandlestatic BOOLclose_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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -