Cygwin: strptime: add release note
[newlib-cygwin.git] / winsup / cygwin / strace.cc
blob0010a17c74a0d2b49bec88a2e8e943eafc431797
1 /* strace.cc: system/windows tracing
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
9 #include "winsup.h"
10 #include <ctype.h>
11 #include "cygerrno.h"
12 #include "pinfo.h"
13 #include "perprocess.h"
14 #include "cygwin_version.h"
15 #include "cygthread.h"
16 #include "path.h"
17 #include "fhandler.h"
18 #include "dtable.h"
19 #include "cygheap.h"
20 #include "child_info.h"
21 #include "sync.h"
23 #define PROTECT(x) {x[NT_MAX_PATH - 1] = '\0';}
24 #define CHECK(x) if (x[NT_MAX_PATH - 1] != '\0') \
25 { small_printf ("array bound exceeded %d\n", __LINE__); \
26 ExitProcess (1); \
29 class strace NO_COPY strace;
31 #ifndef NOSTRACE
33 void
34 strace::activate (bool isfork)
36 if (!_active && being_debugged ())
38 char buf[30];
39 __small_sprintf (buf, "cYg%8x %lx %d",
40 _STRACE_INTERFACE_ACTIVATE_ADDR, &_active, isfork);
41 OutputDebugString (buf);
42 if (_active)
44 char pidbuf[80];
45 PWCHAR progname;
46 if (myself)
48 __small_sprintf (pidbuf, "(pid %d, ppid %d, windows pid %u)",
49 myself->pid, myself->ppid ?: 1,
50 GetCurrentProcessId ());
51 progname = myself->progname;
53 else
55 __small_sprintf (pidbuf, "(windows pid %u)",
56 GetCurrentProcessId ());
57 progname = global_progname;
59 prntf (1, NULL, "**********************************************");
60 prntf (1, NULL, "Program name: %W %s", progname, pidbuf);
61 prntf (1, NULL, "OS version: Windows %s", wincap.osname ());
62 prntf (1, NULL, "**********************************************");
67 void
68 strace::dll_info ()
70 if (active ())
72 prntf (1, NULL, "App version: %d.%d, api: %d.%d",
73 user_data->dll_major, user_data->dll_minor,
74 user_data->api_major, user_data->api_minor);
75 prntf (1, NULL, "DLL version: %d.%d, api: %d.%d",
76 cygwin_version.dll_major, cygwin_version.dll_minor,
77 cygwin_version.api_major, cygwin_version.api_minor);
78 prntf (1, NULL, "DLL build: %s", cygwin_version.dll_build_date);
82 int
83 strace::microseconds ()
85 static LONGLONG process_start NO_COPY;
86 clk_monotonic_t *clk = (clk_monotonic_t *) get_clock (CLOCK_MONOTONIC);
88 if (!process_start)
89 process_start = clk->strace_usecs ();
90 return (int) (clk->strace_usecs () - process_start);
93 static int
94 getfunc (char *in_dst, const char *func)
96 const char *p;
97 const char *pe;
98 char *dst = in_dst;
99 for (p = func; (pe = strchr (p, '(')); p = pe + 1)
100 if (isalnum ((int)pe[-1]) || pe[-1] == '_')
101 break;
102 else if (isspace ((int)pe[-1]))
104 pe--;
105 break;
107 if (!pe)
108 pe = strchr (func, '\0');
109 for (p = pe; p > func; p--)
110 if (p != pe && *p == ' ')
112 p++;
113 break;
115 if (*p == '*')
116 p++;
117 while (p < pe)
118 *dst++ = *p++;
120 *dst++ = ':';
121 *dst++ = ' ';
122 *dst = '\0';
124 return dst - in_dst;
127 static char *
128 mypid (char *buf)
130 if (myself && myself->pid)
131 __small_sprintf (buf, "%d", myself->pid);
132 else
133 __small_sprintf (buf, "(%d)", GetCurrentProcessId ());
134 return buf;
137 /* sprintf analog for use by output routines. */
139 strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap)
141 int count;
142 char fmt[80];
143 static NO_COPY bool nonewline = false;
144 DWORD err = GetLastError ();
145 const char *tn = mythreadname ();
147 int microsec = microseconds ();
148 lmicrosec = microsec;
150 __small_sprintf (fmt, "%7d [%s] %s ", microsec, tn, "%W %s%s");
152 SetLastError (err);
154 if (nonewline)
155 count = 0;
156 else
158 PWCHAR pn = NULL;
159 WCHAR progname[NAME_MAX];
160 if (cygwin_finished_initializing && program_invocation_short_name)
162 char *p = strrchr (program_invocation_short_name, '/');
163 if (p)
164 ++p;
165 else
166 p = program_invocation_short_name;
167 char *pe = strrchr (p, '.');
168 if (!pe || !ascii_strcasematch (pe, ".exe"))
169 pe = strrchr (p, '\0');
170 sys_mbstowcs (pn = progname, NAME_MAX, p, pe - p);
172 else
174 PWCHAR p = wcsrchr (global_progname, L'\\');
175 ++p;
176 PWCHAR pe = wcsrchr (p, '.');
177 if (!pe || wcscasecmp (pe, L".exe"))
178 pe = wcsrchr (p, L'\0');
179 pe = wcpncpy (progname, p, pe - p);
180 *pe = L'\0';
181 pn = progname;
183 char tmpbuf[20];
184 count = __small_sprintf (buf, fmt, pn, mypid (tmpbuf),
185 execing ? "!" : "");
186 if (func)
187 count += getfunc (buf + count, func);
190 count += __small_vsprintf (buf + count, infmt, ap);
191 char *p;
192 for (p = buf + count; p > buf; p--)
193 switch (p[-1])
195 case '\n':
196 p[-1] = '\0';
197 break;
198 case '\b':
199 *--p = '\0';
200 nonewline = true;
201 goto done;
202 default:
203 goto addnl;
206 addnl:
207 *p++ = '\n';
208 *p = '\0';
209 nonewline = false;
211 done:
212 return p - buf;
215 /* Write to strace file or strace queue. */
216 void
217 strace::write (unsigned category, const char *buf, int count)
219 # define PREFIX (3 + 8 + 1 + 8 + 1)
220 char outbuf[PREFIX + 1 + count + 1];
221 # define outstuff (outbuf + 12)
222 __small_sprintf (outstuff, "%x %s", category, buf);
223 __small_sprintf (outbuf, "cYg%08x", strlen (outstuff) + 1);
224 outstuff[-1] = ' ';
225 OutputDebugString (outbuf);
226 #undef outstuff
227 #undef PREFIX
230 void
231 strace::write_childpid (pid_t pid)
233 char buf[30];
235 if (!attached () || !being_debugged ())
236 return;
237 __small_sprintf (buf, "cYg%8x %x", _STRACE_CHILD_PID, pid);
238 OutputDebugString (buf);
241 /* Printf function used when tracing system calls.
242 Warning: DO NOT SET ERRNO HERE! */
243 static NO_COPY muto strace_buf_guard;
244 static NO_COPY char *buf;
246 void
247 strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap)
249 DWORD err = GetLastError ();
250 int len;
252 strace_buf_guard.init ("smallprint_buf")->acquire ();
253 /* Creating buffer on Windows process heap to drop stack pressure and
254 keeping our .bss small. */
255 if (!buf)
256 buf = (char *) HeapAlloc (GetProcessHeap (), 0, NT_MAX_PATH);
257 if (!buf)
258 return;
259 PROTECT (buf);
260 SetLastError (err);
262 len = vsprntf (buf, func, fmt, ap);
263 CHECK (buf);
264 if (category & _STRACE_SYSTEM)
266 DWORD done;
267 WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, len, &done, 0);
268 FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE));
269 /* Make sure that the message shows up on the screen, too, since this is
270 a serious error. */
271 if (GetFileType (GetStdHandle (STD_ERROR_HANDLE)) != FILE_TYPE_CHAR)
273 HANDLE h = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE,
274 FILE_SHARE_READ | FILE_SHARE_WRITE,
275 &sec_none, OPEN_EXISTING, 0, 0);
276 if (h != INVALID_HANDLE_VALUE)
278 WriteFile (h, buf, len, &done, 0);
279 CloseHandle (h);
284 #ifndef NOSTRACE
285 if (active ())
286 write (category, buf, len);
287 #endif
288 strace_buf_guard.release ();
289 SetLastError (err);
292 void
293 strace::prntf (unsigned category, const char *func, const char *fmt, ...)
295 va_list ap;
297 va_start (ap, fmt);
298 vprntf (category, func, fmt, ap);
299 va_end (ap);
302 extern "C" void
303 strace_printf (unsigned category, const char *func, const char *fmt, ...)
305 va_list ap;
307 if ((category & _STRACE_SYSTEM) || strace.active ())
309 va_start (ap, fmt);
310 strace.vprntf (category, func, fmt, ap);
311 va_end (ap);
315 static NO_COPY struct tab
317 int v;
318 const char *n;
320 ta[] =
322 { WM_NULL, "WM_NULL" },
323 { WM_CREATE, "WM_CREATE" },
324 { WM_DESTROY, "WM_DESTROY" },
325 { WM_MOVE, "WM_MOVE" },
326 { WM_SIZE, "WM_SIZE" },
327 { WM_ACTIVATE, "WM_ACTIVATE" },
328 { WM_SETFOCUS, "WM_SETFOCUS" },
329 { WM_KILLFOCUS, "WM_KILLFOCUS" },
330 { WM_ENABLE, "WM_ENABLE" },
331 { WM_SETREDRAW, "WM_SETREDRAW" },
332 { WM_SETTEXT, "WM_SETTEXT" },
333 { WM_GETTEXT, "WM_GETTEXT" },
334 { WM_GETTEXTLENGTH, "WM_GETTEXTLENGTH" },
335 { WM_PAINT, "WM_PAINT" },
336 { WM_CLOSE, "WM_CLOSE" },
337 { WM_QUERYENDSESSION, "WM_QUERYENDSESSION" },
338 { WM_QUIT, "WM_QUIT" },
339 { WM_QUERYOPEN, "WM_QUERYOPEN" },
340 { WM_ERASEBKGND, "WM_ERASEBKGND" },
341 { WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE" },
342 { WM_ENDSESSION, "WM_ENDSESSION" },
343 { WM_SHOWWINDOW, "WM_SHOWWINDOW" },
344 { WM_WININICHANGE, "WM_WININICHANGE" },
345 { WM_DEVMODECHANGE, "WM_DEVMODECHANGE" },
346 { WM_ACTIVATEAPP, "WM_ACTIVATEAPP" },
347 { WM_FONTCHANGE, "WM_FONTCHANGE" },
348 { WM_TIMECHANGE, "WM_TIMECHANGE" },
349 { WM_CANCELMODE, "WM_CANCELMODE" },
350 { WM_SETCURSOR, "WM_SETCURSOR" },
351 { WM_MOUSEACTIVATE, "WM_MOUSEACTIVATE" },
352 { WM_CHILDACTIVATE, "WM_CHILDACTIVATE" },
353 { WM_QUEUESYNC, "WM_QUEUESYNC" },
354 { WM_GETMINMAXINFO, "WM_GETMINMAXINFO" },
355 { WM_PAINTICON, "WM_PAINTICON" },
356 { WM_ICONERASEBKGND, "WM_ICONERASEBKGND" },
357 { WM_NEXTDLGCTL, "WM_NEXTDLGCTL" },
358 { WM_SPOOLERSTATUS, "WM_SPOOLERSTATUS" },
359 { WM_DRAWITEM, "WM_DRAWITEM" },
360 { WM_MEASUREITEM, "WM_MEASUREITEM" },
361 { WM_DELETEITEM, "WM_DELETEITEM" },
362 { WM_VKEYTOITEM, "WM_VKEYTOITEM" },
363 { WM_CHARTOITEM, "WM_CHARTOITEM" },
364 { WM_SETFONT, "WM_SETFONT" },
365 { WM_GETFONT, "WM_GETFONT" },
366 { WM_SETHOTKEY, "WM_SETHOTKEY" },
367 { WM_GETHOTKEY, "WM_GETHOTKEY" },
368 { WM_QUERYDRAGICON, "WM_QUERYDRAGICON" },
369 { WM_COMPAREITEM, "WM_COMPAREITEM" },
370 { WM_COMPACTING, "WM_COMPACTING" },
371 { WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING" },
372 { WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED" },
373 { WM_POWER, "WM_POWER" },
374 { WM_COPYDATA, "WM_COPYDATA" },
375 { WM_CANCELJOURNAL, "WM_CANCELJOURNAL" },
376 { WM_NCCREATE, "WM_NCCREATE" },
377 { WM_NCDESTROY, "WM_NCDESTROY" },
378 { WM_NCCALCSIZE, "WM_NCCALCSIZE" },
379 { WM_NCHITTEST, "WM_NCHITTEST" },
380 { WM_NCPAINT, "WM_NCPAINT" },
381 { WM_NCACTIVATE, "WM_NCACTIVATE" },
382 { WM_GETDLGCODE, "WM_GETDLGCODE" },
383 { WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE" },
384 { WM_NCLBUTTONDOWN, "WM_NCLBUTTONDOWN" },
385 { WM_NCLBUTTONUP, "WM_NCLBUTTONUP" },
386 { WM_NCLBUTTONDBLCLK, "WM_NCLBUTTONDBLCLK" },
387 { WM_NCRBUTTONDOWN, "WM_NCRBUTTONDOWN" },
388 { WM_NCRBUTTONUP, "WM_NCRBUTTONUP" },
389 { WM_NCRBUTTONDBLCLK, "WM_NCRBUTTONDBLCLK" },
390 { WM_NCMBUTTONDOWN, "WM_NCMBUTTONDOWN" },
391 { WM_NCMBUTTONUP, "WM_NCMBUTTONUP" },
392 { WM_NCMBUTTONDBLCLK, "WM_NCMBUTTONDBLCLK" },
393 { WM_KEYFIRST, "WM_KEYFIRST" },
394 { WM_KEYDOWN, "WM_KEYDOWN" },
395 { WM_KEYUP, "WM_KEYUP" },
396 { WM_CHAR, "WM_CHAR" },
397 { WM_DEADCHAR, "WM_DEADCHAR" },
398 { WM_SYSKEYDOWN, "WM_SYSKEYDOWN" },
399 { WM_SYSKEYUP, "WM_SYSKEYUP" },
400 { WM_SYSCHAR, "WM_SYSCHAR" },
401 { WM_SYSDEADCHAR, "WM_SYSDEADCHAR" },
402 { WM_KEYLAST, "WM_KEYLAST" },
403 { WM_INITDIALOG, "WM_INITDIALOG" },
404 { WM_COMMAND, "WM_COMMAND" },
405 { WM_SYSCOMMAND, "WM_SYSCOMMAND" },
406 { WM_TIMER, "WM_TIMER" },
407 { WM_HSCROLL, "WM_HSCROLL" },
408 { WM_VSCROLL, "WM_VSCROLL" },
409 { WM_INITMENU, "WM_INITMENU" },
410 { WM_INITMENUPOPUP, "WM_INITMENUPOPUP" },
411 { WM_MENUSELECT, "WM_MENUSELECT" },
412 { WM_MENUCHAR, "WM_MENUCHAR" },
413 { WM_ENTERIDLE, "WM_ENTERIDLE" },
414 { WM_CTLCOLORMSGBOX, "WM_CTLCOLORMSGBOX" },
415 { WM_CTLCOLOREDIT, "WM_CTLCOLOREDIT" },
416 { WM_CTLCOLORLISTBOX, "WM_CTLCOLORLISTBOX" },
417 { WM_CTLCOLORBTN, "WM_CTLCOLORBTN" },
418 { WM_CTLCOLORDLG, "WM_CTLCOLORDLG" },
419 { WM_CTLCOLORSCROLLBAR, "WM_CTLCOLORSCROLLBAR" },
420 { WM_CTLCOLORSTATIC, "WM_CTLCOLORSTATIC" },
421 { WM_MOUSEFIRST, "WM_MOUSEFIRST" },
422 { WM_MOUSEMOVE, "WM_MOUSEMOVE" },
423 { WM_LBUTTONDOWN, "WM_LBUTTONDOWN" },
424 { WM_LBUTTONUP, "WM_LBUTTONUP" },
425 { WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK" },
426 { WM_RBUTTONDOWN, "WM_RBUTTONDOWN" },
427 { WM_RBUTTONUP, "WM_RBUTTONUP" },
428 { WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK" },
429 { WM_MBUTTONDOWN, "WM_MBUTTONDOWN" },
430 { WM_MBUTTONUP, "WM_MBUTTONUP" },
431 { WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK" },
432 { WM_MOUSELAST, "WM_MOUSELAST" },
433 { WM_PARENTNOTIFY, "WM_PARENTNOTIFY" },
434 { WM_ENTERMENULOOP, "WM_ENTERMENULOOP" },
435 { WM_EXITMENULOOP, "WM_EXITMENULOOP" },
436 { WM_MDICREATE, "WM_MDICREATE" },
437 { WM_MDIDESTROY, "WM_MDIDESTROY" },
438 { WM_MDIACTIVATE, "WM_MDIACTIVATE" },
439 { WM_MDIRESTORE, "WM_MDIRESTORE" },
440 { WM_MDINEXT, "WM_MDINEXT" },
441 { WM_MDIMAXIMIZE, "WM_MDIMAXIMIZE" },
442 { WM_MDITILE, "WM_MDITILE" },
443 { WM_MDICASCADE, "WM_MDICASCADE" },
444 { WM_MDIICONARRANGE, "WM_MDIICONARRANGE" },
445 { WM_MDIGETACTIVE, "WM_MDIGETACTIVE" },
446 { WM_MDISETMENU, "WM_MDISETMENU" },
447 { WM_DROPFILES, "WM_DROPFILES" },
448 { WM_MDIREFRESHMENU, "WM_MDIREFRESHMENU" },
449 { WM_CUT, "WM_CUT" },
450 { WM_COPY, "WM_COPY" },
451 { WM_PASTE, "WM_PASTE" },
452 { WM_CLEAR, "WM_CLEAR" },
453 { WM_UNDO, "WM_UNDO" },
454 { WM_RENDERFORMAT, "WM_RENDERFORMAT" },
455 { WM_RENDERALLFORMATS, "WM_RENDERALLFORMATS" },
456 { WM_DESTROYCLIPBOARD, "WM_DESTROYCLIPBOARD" },
457 { WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD" },
458 { WM_PAINTCLIPBOARD, "WM_PAINTCLIPBOARD" },
459 { WM_VSCROLLCLIPBOARD, "WM_VSCROLLCLIPBOARD" },
460 { WM_SIZECLIPBOARD, "WM_SIZECLIPBOARD" },
461 { WM_ASKCBFORMATNAME, "WM_ASKCBFORMATNAME" },
462 { WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN" },
463 { WM_HSCROLLCLIPBOARD, "WM_HSCROLLCLIPBOARD" },
464 { WM_QUERYNEWPALETTE, "WM_QUERYNEWPALETTE" },
465 { WM_PALETTEISCHANGING, "WM_PALETTEISCHANGING" },
466 { WM_PALETTECHANGED, "WM_PALETTECHANGED" },
467 { WM_HOTKEY, "WM_HOTKEY" },
468 { WM_PENWINFIRST, "WM_PENWINFIRST" },
469 { WM_PENWINLAST, "WM_PENWINLAST" },
470 { WM_ASYNCIO, "ASYNCIO" },
471 { 0, 0 }};
473 void
474 strace::wm (int message, int word, int lon)
476 if (active ())
478 int i;
480 for (i = 0; ta[i].n; i++)
482 if (ta[i].v == message)
484 prntf (_STRACE_WM, NULL, "wndproc %d %s %d %d", message, ta[i].n, word, lon);
485 return;
488 prntf (_STRACE_WM, NULL, "wndproc %d unknown %d %d", message, word, lon);
491 #endif /*NOSTRACE*/