1 /* strace.cc: system/windows tracing
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
20 #include "perprocess.h"
21 #include "cygwin_version.h"
24 #include "cygthread.h"
29 #include "child_info.h"
31 #define PROTECT(x) x[sizeof (x)-1] = 0
32 #define CHECK(x) if (x[sizeof (x)-1] != 0) { small_printf ("array bound exceeded %d\n", __LINE__); ExitProcess (1); }
34 class strace NO_COPY strace;
41 if (_active || !being_debugged ())
45 __small_sprintf (buf, "cYg%8x %x", _STRACE_INTERFACE_ACTIVATE_ADDR, &_active);
46 OutputDebugString (buf);
51 if (myself->progname[0])
52 __small_sprintf (pidbuf, "(pid %d, ppid %d)", myself->pid, myself->ppid ?: 1);
55 GetModuleFileName (NULL, myself->progname, sizeof (myself->progname));
56 __small_sprintf (pidbuf, "(windows pid %d)", GetCurrentProcessId ());
58 prntf (1, NULL, "**********************************************");
59 prntf (1, NULL, "Program name: %s %s", myself->progname, pidbuf);
60 prntf (1, NULL, "App version: %d.%d, api: %d.%d",
61 user_data->dll_major, user_data->dll_minor,
62 user_data->api_major, user_data->api_minor);
63 prntf (1, NULL, "DLL version: %d.%d, api: %d.%d",
64 cygwin_version.dll_major, cygwin_version.dll_minor,
65 cygwin_version.api_major, cygwin_version.api_minor);
66 prntf (1, NULL, "DLL build: %s", cygwin_version.dll_build_date);
67 prntf (1, NULL, "OS version: Windows %s", wincap.osname ());
69 prntf (1, NULL, "Heap size: %u", cygheap->user_heap.chunk);
70 prntf (1, NULL, "**********************************************");
75 strace::microseconds ()
78 return (int) now.usecs (true);
82 getfunc (char *in_dst, const char *func)
87 for (p = func; (pe = strchr (p, '(')); p = pe + 1)
88 if (isalnum ((int)pe[-1]) || pe[-1] == '_')
90 else if (isspace ((int)pe[-1]))
96 pe = strchr (func, '\0');
97 for (p = pe; p > func; p--)
98 if (p != pe && *p == ' ')
118 if (myself && myself->pid)
119 __small_sprintf (buf, "%d", myself->pid);
121 __small_sprintf (buf, "(%d)", cygwin_pid (GetCurrentProcessId ()));
125 extern "C" char *__progname;
127 /* sprintf analog for use by output routines. */
129 strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap)
133 static NO_COPY bool nonewline = false;
134 DWORD err = GetLastError ();
135 const char *tn = cygthread::name ();
137 int microsec = microseconds ();
138 lmicrosec = microsec;
140 __small_sprintf (fmt, "%7d [%s] %s ", microsec, tn, "%s %s%s");
149 if (!cygwin_finished_initializing)
150 pn = myself ? myself->progname : NULL;
157 char progname[NT_MAX_PATH];
159 GetModuleFileName (NULL, pn = progname, sizeof (progname));
162 else if ((p = strrchr (pn, '\\')) != NULL)
164 else if ((p = strrchr (pn, '/')) != NULL)
169 strcpy (progname, p);
170 if ((p = strrchr (progname, '.')) != NULL
171 && ascii_strcasematch (p, ".exe"))
175 count = __small_sprintf (buf, fmt, p && *p ? p : "?", mypid (tmpbuf),
178 count += getfunc (buf + count, func);
181 count += __small_vsprintf (buf + count, infmt, ap);
183 for (p = buf + count; p > buf; p--)
206 /* Write to strace file or strace queue. */
208 strace::write (unsigned category, const char *buf, int count)
210 # define PREFIX (3 + 8 + 1 + 8 + 1)
211 char outbuf[PREFIX + 1 + count + 1];
212 # define outstuff (outbuf + 12)
213 __small_sprintf (outstuff, "%x %s", category, buf);
214 __small_sprintf (outbuf, "cYg%08x", strlen (outstuff) + 1);
216 OutputDebugString (outbuf);
222 strace::write_childpid (child_info& ch, DWORD pid)
226 if (!attached () || !being_debugged ())
228 WaitForSingleObject (ch.subproc_ready, 30000);
229 __small_sprintf (buf, "cYg%8x %x", _STRACE_CHILD_PID, pid);
230 OutputDebugString (buf);
233 /* Printf function used when tracing system calls.
234 Warning: DO NOT SET ERRNO HERE! */
237 strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap)
239 DWORD err = GetLastError ();
246 len = vsprntf (buf, func, fmt, ap);
248 if (category & _STRACE_SYSTEM)
251 WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, len, &done, 0);
252 FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE));
253 /* Make sure that the message shows up on the screen, too, since this is
255 if (GetFileType (GetStdHandle (STD_ERROR_HANDLE)) != FILE_TYPE_CHAR)
257 HANDLE h = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE,
258 FILE_SHARE_WRITE | FILE_SHARE_WRITE,
259 &sec_none, OPEN_EXISTING, 0, 0);
260 if (h != INVALID_HANDLE_VALUE)
261 WriteFile (h, buf, len, &done, 0);
268 write (category, buf, len);
274 strace::prntf (unsigned category, const char *func, const char *fmt, ...)
279 vprntf (category, func, fmt, ap);
283 strace_printf (unsigned category, const char *func, const char *fmt, ...)
287 if ((category & _STRACE_SYSTEM) || strace.active ())
290 strace.vprntf (category, func, fmt, ap);
294 static NO_COPY struct tab
301 { WM_NULL, "WM_NULL" },
302 { WM_CREATE, "WM_CREATE" },
303 { WM_DESTROY, "WM_DESTROY" },
304 { WM_MOVE, "WM_MOVE" },
305 { WM_SIZE, "WM_SIZE" },
306 { WM_ACTIVATE, "WM_ACTIVATE" },
307 { WM_SETFOCUS, "WM_SETFOCUS" },
308 { WM_KILLFOCUS, "WM_KILLFOCUS" },
309 { WM_ENABLE, "WM_ENABLE" },
310 { WM_SETREDRAW, "WM_SETREDRAW" },
311 { WM_SETTEXT, "WM_SETTEXT" },
312 { WM_GETTEXT, "WM_GETTEXT" },
313 { WM_GETTEXTLENGTH, "WM_GETTEXTLENGTH" },
314 { WM_PAINT, "WM_PAINT" },
315 { WM_CLOSE, "WM_CLOSE" },
316 { WM_QUERYENDSESSION, "WM_QUERYENDSESSION" },
317 { WM_QUIT, "WM_QUIT" },
318 { WM_QUERYOPEN, "WM_QUERYOPEN" },
319 { WM_ERASEBKGND, "WM_ERASEBKGND" },
320 { WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE" },
321 { WM_ENDSESSION, "WM_ENDSESSION" },
322 { WM_SHOWWINDOW, "WM_SHOWWINDOW" },
323 { WM_WININICHANGE, "WM_WININICHANGE" },
324 { WM_DEVMODECHANGE, "WM_DEVMODECHANGE" },
325 { WM_ACTIVATEAPP, "WM_ACTIVATEAPP" },
326 { WM_FONTCHANGE, "WM_FONTCHANGE" },
327 { WM_TIMECHANGE, "WM_TIMECHANGE" },
328 { WM_CANCELMODE, "WM_CANCELMODE" },
329 { WM_SETCURSOR, "WM_SETCURSOR" },
330 { WM_MOUSEACTIVATE, "WM_MOUSEACTIVATE" },
331 { WM_CHILDACTIVATE, "WM_CHILDACTIVATE" },
332 { WM_QUEUESYNC, "WM_QUEUESYNC" },
333 { WM_GETMINMAXINFO, "WM_GETMINMAXINFO" },
334 { WM_PAINTICON, "WM_PAINTICON" },
335 { WM_ICONERASEBKGND, "WM_ICONERASEBKGND" },
336 { WM_NEXTDLGCTL, "WM_NEXTDLGCTL" },
337 { WM_SPOOLERSTATUS, "WM_SPOOLERSTATUS" },
338 { WM_DRAWITEM, "WM_DRAWITEM" },
339 { WM_MEASUREITEM, "WM_MEASUREITEM" },
340 { WM_DELETEITEM, "WM_DELETEITEM" },
341 { WM_VKEYTOITEM, "WM_VKEYTOITEM" },
342 { WM_CHARTOITEM, "WM_CHARTOITEM" },
343 { WM_SETFONT, "WM_SETFONT" },
344 { WM_GETFONT, "WM_GETFONT" },
345 { WM_SETHOTKEY, "WM_SETHOTKEY" },
346 { WM_GETHOTKEY, "WM_GETHOTKEY" },
347 { WM_QUERYDRAGICON, "WM_QUERYDRAGICON" },
348 { WM_COMPAREITEM, "WM_COMPAREITEM" },
349 { WM_COMPACTING, "WM_COMPACTING" },
350 { WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING" },
351 { WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED" },
352 { WM_POWER, "WM_POWER" },
353 { WM_COPYDATA, "WM_COPYDATA" },
354 { WM_CANCELJOURNAL, "WM_CANCELJOURNAL" },
355 { WM_NCCREATE, "WM_NCCREATE" },
356 { WM_NCDESTROY, "WM_NCDESTROY" },
357 { WM_NCCALCSIZE, "WM_NCCALCSIZE" },
358 { WM_NCHITTEST, "WM_NCHITTEST" },
359 { WM_NCPAINT, "WM_NCPAINT" },
360 { WM_NCACTIVATE, "WM_NCACTIVATE" },
361 { WM_GETDLGCODE, "WM_GETDLGCODE" },
362 { WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE" },
363 { WM_NCLBUTTONDOWN, "WM_NCLBUTTONDOWN" },
364 { WM_NCLBUTTONUP, "WM_NCLBUTTONUP" },
365 { WM_NCLBUTTONDBLCLK, "WM_NCLBUTTONDBLCLK" },
366 { WM_NCRBUTTONDOWN, "WM_NCRBUTTONDOWN" },
367 { WM_NCRBUTTONUP, "WM_NCRBUTTONUP" },
368 { WM_NCRBUTTONDBLCLK, "WM_NCRBUTTONDBLCLK" },
369 { WM_NCMBUTTONDOWN, "WM_NCMBUTTONDOWN" },
370 { WM_NCMBUTTONUP, "WM_NCMBUTTONUP" },
371 { WM_NCMBUTTONDBLCLK, "WM_NCMBUTTONDBLCLK" },
372 { WM_KEYFIRST, "WM_KEYFIRST" },
373 { WM_KEYDOWN, "WM_KEYDOWN" },
374 { WM_KEYUP, "WM_KEYUP" },
375 { WM_CHAR, "WM_CHAR" },
376 { WM_DEADCHAR, "WM_DEADCHAR" },
377 { WM_SYSKEYDOWN, "WM_SYSKEYDOWN" },
378 { WM_SYSKEYUP, "WM_SYSKEYUP" },
379 { WM_SYSCHAR, "WM_SYSCHAR" },
380 { WM_SYSDEADCHAR, "WM_SYSDEADCHAR" },
381 { WM_KEYLAST, "WM_KEYLAST" },
382 { WM_INITDIALOG, "WM_INITDIALOG" },
383 { WM_COMMAND, "WM_COMMAND" },
384 { WM_SYSCOMMAND, "WM_SYSCOMMAND" },
385 { WM_TIMER, "WM_TIMER" },
386 { WM_HSCROLL, "WM_HSCROLL" },
387 { WM_VSCROLL, "WM_VSCROLL" },
388 { WM_INITMENU, "WM_INITMENU" },
389 { WM_INITMENUPOPUP, "WM_INITMENUPOPUP" },
390 { WM_MENUSELECT, "WM_MENUSELECT" },
391 { WM_MENUCHAR, "WM_MENUCHAR" },
392 { WM_ENTERIDLE, "WM_ENTERIDLE" },
393 { WM_CTLCOLORMSGBOX, "WM_CTLCOLORMSGBOX" },
394 { WM_CTLCOLOREDIT, "WM_CTLCOLOREDIT" },
395 { WM_CTLCOLORLISTBOX, "WM_CTLCOLORLISTBOX" },
396 { WM_CTLCOLORBTN, "WM_CTLCOLORBTN" },
397 { WM_CTLCOLORDLG, "WM_CTLCOLORDLG" },
398 { WM_CTLCOLORSCROLLBAR, "WM_CTLCOLORSCROLLBAR" },
399 { WM_CTLCOLORSTATIC, "WM_CTLCOLORSTATIC" },
400 { WM_MOUSEFIRST, "WM_MOUSEFIRST" },
401 { WM_MOUSEMOVE, "WM_MOUSEMOVE" },
402 { WM_LBUTTONDOWN, "WM_LBUTTONDOWN" },
403 { WM_LBUTTONUP, "WM_LBUTTONUP" },
404 { WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK" },
405 { WM_RBUTTONDOWN, "WM_RBUTTONDOWN" },
406 { WM_RBUTTONUP, "WM_RBUTTONUP" },
407 { WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK" },
408 { WM_MBUTTONDOWN, "WM_MBUTTONDOWN" },
409 { WM_MBUTTONUP, "WM_MBUTTONUP" },
410 { WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK" },
411 { WM_MOUSELAST, "WM_MOUSELAST" },
412 { WM_PARENTNOTIFY, "WM_PARENTNOTIFY" },
413 { WM_ENTERMENULOOP, "WM_ENTERMENULOOP" },
414 { WM_EXITMENULOOP, "WM_EXITMENULOOP" },
415 { WM_MDICREATE, "WM_MDICREATE" },
416 { WM_MDIDESTROY, "WM_MDIDESTROY" },
417 { WM_MDIACTIVATE, "WM_MDIACTIVATE" },
418 { WM_MDIRESTORE, "WM_MDIRESTORE" },
419 { WM_MDINEXT, "WM_MDINEXT" },
420 { WM_MDIMAXIMIZE, "WM_MDIMAXIMIZE" },
421 { WM_MDITILE, "WM_MDITILE" },
422 { WM_MDICASCADE, "WM_MDICASCADE" },
423 { WM_MDIICONARRANGE, "WM_MDIICONARRANGE" },
424 { WM_MDIGETACTIVE, "WM_MDIGETACTIVE" },
425 { WM_MDISETMENU, "WM_MDISETMENU" },
426 { WM_DROPFILES, "WM_DROPFILES" },
427 { WM_MDIREFRESHMENU, "WM_MDIREFRESHMENU" },
428 { WM_CUT, "WM_CUT" },
429 { WM_COPY, "WM_COPY" },
430 { WM_PASTE, "WM_PASTE" },
431 { WM_CLEAR, "WM_CLEAR" },
432 { WM_UNDO, "WM_UNDO" },
433 { WM_RENDERFORMAT, "WM_RENDERFORMAT" },
434 { WM_RENDERALLFORMATS, "WM_RENDERALLFORMATS" },
435 { WM_DESTROYCLIPBOARD, "WM_DESTROYCLIPBOARD" },
436 { WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD" },
437 { WM_PAINTCLIPBOARD, "WM_PAINTCLIPBOARD" },
438 { WM_VSCROLLCLIPBOARD, "WM_VSCROLLCLIPBOARD" },
439 { WM_SIZECLIPBOARD, "WM_SIZECLIPBOARD" },
440 { WM_ASKCBFORMATNAME, "WM_ASKCBFORMATNAME" },
441 { WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN" },
442 { WM_HSCROLLCLIPBOARD, "WM_HSCROLLCLIPBOARD" },
443 { WM_QUERYNEWPALETTE, "WM_QUERYNEWPALETTE" },
444 { WM_PALETTEISCHANGING, "WM_PALETTEISCHANGING" },
445 { WM_PALETTECHANGED, "WM_PALETTECHANGED" },
446 { WM_HOTKEY, "WM_HOTKEY" },
447 { WM_PENWINFIRST, "WM_PENWINFIRST" },
448 { WM_PENWINLAST, "WM_PENWINLAST" },
449 { WM_ASYNCIO, "ASYNCIO" },
453 strace::wm (int message, int word, int lon)
459 for (i = 0; ta[i].n; i++)
461 if (ta[i].v == message)
463 prntf (_STRACE_WM, NULL, "wndproc %d %s %d %d", message, ta[i].n, word, lon);
467 prntf (_STRACE_WM, NULL, "wndproc %d unknown %d %d", message, word, lon);