]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/strace.cc
Throughout, update copyrights to reflect dates which correspond to main-branch
[newlib-cygwin.git] / winsup / cygwin / strace.cc
CommitLineData
1fd5e000
CF
1/* strace.cc: system/windows tracing
2
bc837d22
CF
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
1fd5e000
CF
5
6This file is part of Cygwin.
7
8This software is a copyrighted work licensed under the terms of the
9Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10details. */
11
4c8d72de 12#include "winsup.h"
d0b178fe
DD
13#include <wingdi.h>
14#include <winuser.h>
20d7f758 15#include <ctype.h>
169c465a 16#include "cygerrno.h"
e2ebe117 17#include "pinfo.h"
494a66d9
CF
18#include "perprocess.h"
19#include "cygwin_version.h"
b6bd7037 20#include "cygthread.h"
1cc651ec 21#include "path.h"
7ac61736 22#include "fhandler.h"
1cc651ec 23#include "dtable.h"
1cc651ec 24#include "cygheap.h"
5d970405 25#include "child_info.h"
1fd5e000 26
f0227ea3
CF
27#define PROTECT(x) x[sizeof (x)-1] = 0
28#define CHECK(x) if (x[sizeof (x)-1] != 0) { small_printf ("array bound exceeded %d\n", __LINE__); ExitProcess (1); }
1fd5e000 29
03a2ce9a 30class strace NO_COPY strace;
1fd5e000 31
1fd5e000
CF
32#ifndef NOSTRACE
33
bc3f0d64 34void
8942ed09 35strace::activate (bool isfork)
1af6bb97 36{
5025bf33 37 if (!_active && being_debugged ())
1af6bb97
CF
38 {
39 char buf[30];
8942ed09 40 __small_sprintf (buf, "cYg%8x %x %d", _STRACE_INTERFACE_ACTIVATE_ADDR, &_active, isfork);
1af6bb97 41 OutputDebugString (buf);
ef8bff85 42 if (_active)
5d970405 43 {
ef8bff85
CF
44 char pidbuf[80];
45 WCHAR progname_buf[NT_MAX_PATH - 512];
46 WCHAR *progname;
47 if (myself)
48 {
49 __small_sprintf (pidbuf, "(pid %d, ppid %d, windows pid %u)", myself->pid,
50 myself->ppid ?: 1, GetCurrentProcessId ());
51 progname = myself->progname;
52 }
53 else
54 {
55 GetModuleFileNameW (NULL, progname_buf, sizeof (myself->progname));
56 __small_sprintf (pidbuf, "(windows pid %u)", GetCurrentProcessId ());
57 progname = progname_buf;
58 }
59 prntf (1, NULL, "**********************************************");
60 prntf (1, NULL, "Program name: %W %s", progname, pidbuf);
61 prntf (1, NULL, "OS version: Windows %s", wincap.osname ());
ef8bff85 62 prntf (1, NULL, "**********************************************");
5d970405 63 }
a7162526
CV
64 }
65}
66
67void
68strace::dll_info ()
69{
70 if (active ())
71 {
494a66d9
CF
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);
494a66d9
CF
79 }
80}
81
5abc9b83 82int
60b68f0d 83strace::microseconds ()
1fd5e000 84{
b150f523
YS
85 static hires_ns now;
86 return (int) now.usecs ();
1fd5e000 87}
1fd5e000 88
20d7f758
CF
89static int __stdcall
90getfunc (char *in_dst, const char *func)
91{
92 const char *p;
93 const char *pe;
94 char *dst = in_dst;
95 for (p = func; (pe = strchr (p, '(')); p = pe + 1)
96 if (isalnum ((int)pe[-1]) || pe[-1] == '_')
97 break;
f0227ea3 98 else if (isspace ((int)pe[-1]))
20d7f758
CF
99 {
100 pe--;
101 break;
102 }
103 if (!pe)
104 pe = strchr (func, '\0');
105 for (p = pe; p > func; p--)
106 if (p != pe && *p == ' ')
107 {
108 p++;
109 break;
110 }
111 if (*p == '*')
112 p++;
113 while (p < pe)
114 *dst++ = *p++;
115
116 *dst++ = ':';
117 *dst++ = ' ';
118 *dst = '\0';
119
120 return dst - in_dst;
121}
122
5d970405
CF
123static char *
124mypid (char *buf)
125{
126 if (myself && myself->pid)
127 __small_sprintf (buf, "%d", myself->pid);
128 else
ef8bff85 129 __small_sprintf (buf, "(%d)", GetCurrentProcessId ());
5d970405
CF
130 return buf;
131}
132
1fd5e000 133/* sprintf analog for use by output routines. */
5abc9b83 134int
20d7f758 135strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap)
1fd5e000
CF
136{
137 int count;
d542443e 138 char fmt[80];
2e008fb9 139 static NO_COPY bool nonewline = false;
1fd5e000 140 DWORD err = GetLastError ();
b6bd7037 141 const char *tn = cygthread::name ();
1fd5e000 142
5abc9b83 143 int microsec = microseconds ();
1fd5e000
CF
144 lmicrosec = microsec;
145
d3258e06 146 __small_sprintf (fmt, "%7d [%s] %s ", microsec, tn, "%W %s%s");
1fd5e000
CF
147
148 SetLastError (err);
20d7f758 149
1fd5e000 150 if (nonewline)
20d7f758 151 count = 0;
1fd5e000
CF
152 else
153 {
d3258e06
CF
154 PWCHAR pn = NULL;
155 WCHAR progname[NT_MAX_PATH];
5d970405 156 if (!cygwin_finished_initializing)
d3258e06 157 pn = (myself) ? myself->progname : NULL;
5d970405 158 else if (__progname)
d3258e06 159 sys_mbstowcs(pn = progname, NT_MAX_PATH, __progname);
5d970405 160
d3258e06 161 PWCHAR p;
1ec4f618 162 if (!pn)
d3258e06 163 GetModuleFileNameW (NULL, pn = progname, sizeof (progname));
5d970405
CF
164 if (!pn)
165 /* hmm */;
d3258e06 166 else if ((p = wcsrchr (pn, L'\\')) != NULL)
57bf29e8 167 p++;
d3258e06 168 else if ((p = wcsrchr (pn, L'/')) != NULL)
d542443e 169 p++;
1fd5e000 170 else
57bf29e8 171 p = pn;
5d970405 172 if (p != progname)
d3258e06
CF
173 wcscpy (progname, p);
174 if ((p = wcsrchr (progname, '.')) != NULL
175 && !wcscasecmp (p, L".exe"))
d542443e
CF
176 *p = '\000';
177 p = progname;
5d970405 178 char tmpbuf[20];
d3258e06 179 count = __small_sprintf (buf, fmt, *p ? p : L"?", mypid (tmpbuf),
4c45a897 180 execing ? "!" : "");
20d7f758
CF
181 if (func)
182 count += getfunc (buf + count, func);
1fd5e000
CF
183 }
184
185 count += __small_vsprintf (buf + count, infmt, ap);
186 char *p;
187 for (p = buf + count; p > buf; p--)
188 switch (p[-1])
189 {
190 case '\n':
191 p[-1] = '\0';
192 break;
193 case '\b':
194 *--p = '\0';
2e008fb9 195 nonewline = true;
1fd5e000
CF
196 goto done;
197 default:
198 goto addnl;
199 }
200
201addnl:
202 *p++ = '\n';
203 *p = '\0';
2e008fb9 204 nonewline = false;
1fd5e000
CF
205
206done:
207 return p - buf;
208}
209
210/* Write to strace file or strace queue. */
5abc9b83
CF
211void
212strace::write (unsigned category, const char *buf, int count)
1fd5e000
CF
213{
214# define PREFIX (3 + 8 + 1 + 8 + 1)
215 char outbuf[PREFIX + 1 + count + 1];
216# define outstuff (outbuf + 12)
217 __small_sprintf (outstuff, "%x %s", category, buf);
218 __small_sprintf (outbuf, "cYg%08x", strlen (outstuff) + 1);
219 outstuff[-1] = ' ';
220 OutputDebugString (outbuf);
4c45a897
CF
221#undef outstuff
222#undef PREFIX
1fd5e000
CF
223}
224
5d970405 225void
ef8bff85 226strace::write_childpid (DWORD pid)
5d970405
CF
227{
228 char buf[30];
229
230 if (!attached () || !being_debugged ())
231 return;
5d970405
CF
232 __small_sprintf (buf, "cYg%8x %x", _STRACE_CHILD_PID, pid);
233 OutputDebugString (buf);
234}
235
1fd5e000
CF
236/* Printf function used when tracing system calls.
237 Warning: DO NOT SET ERRNO HERE! */
238
239void
88429768 240strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap)
1fd5e000
CF
241{
242 DWORD err = GetLastError ();
a16b738d 243 int len;
43657e6b 244 char buf[NT_MAX_PATH];
1fd5e000 245
c90e1cf1 246 PROTECT (buf);
a5a965ff 247 SetLastError (err);
1fd5e000 248
a16b738d 249 len = vsprntf (buf, func, fmt, ap);
c90e1cf1 250 CHECK (buf);
a5a965ff
CF
251 if (category & _STRACE_SYSTEM)
252 {
253 DWORD done;
a16b738d 254 WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, len, &done, 0);
a5a965ff 255 FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE));
a16b738d
CF
256 /* Make sure that the message shows up on the screen, too, since this is
257 a serious error. */
258 if (GetFileType (GetStdHandle (STD_ERROR_HANDLE)) != FILE_TYPE_CHAR)
259 {
260 HANDLE h = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE,
fc3e7da6 261 FILE_SHARE_READ | FILE_SHARE_WRITE,
a16b738d
CF
262 &sec_none, OPEN_EXISTING, 0, 0);
263 if (h != INVALID_HANDLE_VALUE)
d85a0c24
CF
264 {
265 WriteFile (h, buf, len, &done, 0);
266 CloseHandle (h);
267 }
a16b738d 268 }
1fd5e000 269 }
a5a965ff
CF
270
271#ifndef NOSTRACE
5d970405 272 if (active ())
a16b738d 273 write (category, buf, len);
a5a965ff 274#endif
1fd5e000
CF
275 SetLastError (err);
276}
277
88429768
CV
278void
279strace::prntf (unsigned category, const char *func, const char *fmt, ...)
280{
281 va_list ap;
282
283 va_start (ap, fmt);
335556d5 284 vprntf (category, func, fmt, ap);
4cd31fc8 285 va_end (ap);
88429768
CV
286}
287
288extern "C" void
289strace_printf (unsigned category, const char *func, const char *fmt, ...)
290{
291 va_list ap;
292
5d970405 293 if ((category & _STRACE_SYSTEM) || strace.active ())
88429768
CV
294 {
295 va_start (ap, fmt);
296 strace.vprntf (category, func, fmt, ap);
4cd31fc8 297 va_end (ap);
88429768
CV
298 }
299}
300
bc6ed549 301static NO_COPY struct tab
1fd5e000
CF
302{
303 int v;
304 const char *n;
305}
306ta[] =
307{
308 { WM_NULL, "WM_NULL" },
309 { WM_CREATE, "WM_CREATE" },
310 { WM_DESTROY, "WM_DESTROY" },
311 { WM_MOVE, "WM_MOVE" },
312 { WM_SIZE, "WM_SIZE" },
313 { WM_ACTIVATE, "WM_ACTIVATE" },
314 { WM_SETFOCUS, "WM_SETFOCUS" },
315 { WM_KILLFOCUS, "WM_KILLFOCUS" },
316 { WM_ENABLE, "WM_ENABLE" },
317 { WM_SETREDRAW, "WM_SETREDRAW" },
318 { WM_SETTEXT, "WM_SETTEXT" },
319 { WM_GETTEXT, "WM_GETTEXT" },
320 { WM_GETTEXTLENGTH, "WM_GETTEXTLENGTH" },
321 { WM_PAINT, "WM_PAINT" },
322 { WM_CLOSE, "WM_CLOSE" },
323 { WM_QUERYENDSESSION, "WM_QUERYENDSESSION" },
324 { WM_QUIT, "WM_QUIT" },
325 { WM_QUERYOPEN, "WM_QUERYOPEN" },
326 { WM_ERASEBKGND, "WM_ERASEBKGND" },
327 { WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE" },
328 { WM_ENDSESSION, "WM_ENDSESSION" },
329 { WM_SHOWWINDOW, "WM_SHOWWINDOW" },
330 { WM_WININICHANGE, "WM_WININICHANGE" },
331 { WM_DEVMODECHANGE, "WM_DEVMODECHANGE" },
332 { WM_ACTIVATEAPP, "WM_ACTIVATEAPP" },
333 { WM_FONTCHANGE, "WM_FONTCHANGE" },
334 { WM_TIMECHANGE, "WM_TIMECHANGE" },
335 { WM_CANCELMODE, "WM_CANCELMODE" },
336 { WM_SETCURSOR, "WM_SETCURSOR" },
337 { WM_MOUSEACTIVATE, "WM_MOUSEACTIVATE" },
338 { WM_CHILDACTIVATE, "WM_CHILDACTIVATE" },
339 { WM_QUEUESYNC, "WM_QUEUESYNC" },
340 { WM_GETMINMAXINFO, "WM_GETMINMAXINFO" },
341 { WM_PAINTICON, "WM_PAINTICON" },
342 { WM_ICONERASEBKGND, "WM_ICONERASEBKGND" },
343 { WM_NEXTDLGCTL, "WM_NEXTDLGCTL" },
344 { WM_SPOOLERSTATUS, "WM_SPOOLERSTATUS" },
345 { WM_DRAWITEM, "WM_DRAWITEM" },
346 { WM_MEASUREITEM, "WM_MEASUREITEM" },
347 { WM_DELETEITEM, "WM_DELETEITEM" },
348 { WM_VKEYTOITEM, "WM_VKEYTOITEM" },
349 { WM_CHARTOITEM, "WM_CHARTOITEM" },
350 { WM_SETFONT, "WM_SETFONT" },
351 { WM_GETFONT, "WM_GETFONT" },
352 { WM_SETHOTKEY, "WM_SETHOTKEY" },
353 { WM_GETHOTKEY, "WM_GETHOTKEY" },
354 { WM_QUERYDRAGICON, "WM_QUERYDRAGICON" },
355 { WM_COMPAREITEM, "WM_COMPAREITEM" },
356 { WM_COMPACTING, "WM_COMPACTING" },
357 { WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING" },
358 { WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED" },
359 { WM_POWER, "WM_POWER" },
360 { WM_COPYDATA, "WM_COPYDATA" },
361 { WM_CANCELJOURNAL, "WM_CANCELJOURNAL" },
362 { WM_NCCREATE, "WM_NCCREATE" },
363 { WM_NCDESTROY, "WM_NCDESTROY" },
364 { WM_NCCALCSIZE, "WM_NCCALCSIZE" },
365 { WM_NCHITTEST, "WM_NCHITTEST" },
366 { WM_NCPAINT, "WM_NCPAINT" },
367 { WM_NCACTIVATE, "WM_NCACTIVATE" },
368 { WM_GETDLGCODE, "WM_GETDLGCODE" },
369 { WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE" },
370 { WM_NCLBUTTONDOWN, "WM_NCLBUTTONDOWN" },
371 { WM_NCLBUTTONUP, "WM_NCLBUTTONUP" },
372 { WM_NCLBUTTONDBLCLK, "WM_NCLBUTTONDBLCLK" },
373 { WM_NCRBUTTONDOWN, "WM_NCRBUTTONDOWN" },
374 { WM_NCRBUTTONUP, "WM_NCRBUTTONUP" },
375 { WM_NCRBUTTONDBLCLK, "WM_NCRBUTTONDBLCLK" },
376 { WM_NCMBUTTONDOWN, "WM_NCMBUTTONDOWN" },
377 { WM_NCMBUTTONUP, "WM_NCMBUTTONUP" },
378 { WM_NCMBUTTONDBLCLK, "WM_NCMBUTTONDBLCLK" },
379 { WM_KEYFIRST, "WM_KEYFIRST" },
380 { WM_KEYDOWN, "WM_KEYDOWN" },
381 { WM_KEYUP, "WM_KEYUP" },
382 { WM_CHAR, "WM_CHAR" },
383 { WM_DEADCHAR, "WM_DEADCHAR" },
384 { WM_SYSKEYDOWN, "WM_SYSKEYDOWN" },
385 { WM_SYSKEYUP, "WM_SYSKEYUP" },
386 { WM_SYSCHAR, "WM_SYSCHAR" },
387 { WM_SYSDEADCHAR, "WM_SYSDEADCHAR" },
388 { WM_KEYLAST, "WM_KEYLAST" },
389 { WM_INITDIALOG, "WM_INITDIALOG" },
390 { WM_COMMAND, "WM_COMMAND" },
391 { WM_SYSCOMMAND, "WM_SYSCOMMAND" },
392 { WM_TIMER, "WM_TIMER" },
393 { WM_HSCROLL, "WM_HSCROLL" },
394 { WM_VSCROLL, "WM_VSCROLL" },
395 { WM_INITMENU, "WM_INITMENU" },
396 { WM_INITMENUPOPUP, "WM_INITMENUPOPUP" },
397 { WM_MENUSELECT, "WM_MENUSELECT" },
398 { WM_MENUCHAR, "WM_MENUCHAR" },
399 { WM_ENTERIDLE, "WM_ENTERIDLE" },
400 { WM_CTLCOLORMSGBOX, "WM_CTLCOLORMSGBOX" },
401 { WM_CTLCOLOREDIT, "WM_CTLCOLOREDIT" },
402 { WM_CTLCOLORLISTBOX, "WM_CTLCOLORLISTBOX" },
403 { WM_CTLCOLORBTN, "WM_CTLCOLORBTN" },
404 { WM_CTLCOLORDLG, "WM_CTLCOLORDLG" },
405 { WM_CTLCOLORSCROLLBAR, "WM_CTLCOLORSCROLLBAR" },
406 { WM_CTLCOLORSTATIC, "WM_CTLCOLORSTATIC" },
407 { WM_MOUSEFIRST, "WM_MOUSEFIRST" },
408 { WM_MOUSEMOVE, "WM_MOUSEMOVE" },
409 { WM_LBUTTONDOWN, "WM_LBUTTONDOWN" },
410 { WM_LBUTTONUP, "WM_LBUTTONUP" },
411 { WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK" },
412 { WM_RBUTTONDOWN, "WM_RBUTTONDOWN" },
413 { WM_RBUTTONUP, "WM_RBUTTONUP" },
414 { WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK" },
415 { WM_MBUTTONDOWN, "WM_MBUTTONDOWN" },
416 { WM_MBUTTONUP, "WM_MBUTTONUP" },
417 { WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK" },
418 { WM_MOUSELAST, "WM_MOUSELAST" },
419 { WM_PARENTNOTIFY, "WM_PARENTNOTIFY" },
420 { WM_ENTERMENULOOP, "WM_ENTERMENULOOP" },
421 { WM_EXITMENULOOP, "WM_EXITMENULOOP" },
422 { WM_MDICREATE, "WM_MDICREATE" },
423 { WM_MDIDESTROY, "WM_MDIDESTROY" },
424 { WM_MDIACTIVATE, "WM_MDIACTIVATE" },
425 { WM_MDIRESTORE, "WM_MDIRESTORE" },
426 { WM_MDINEXT, "WM_MDINEXT" },
427 { WM_MDIMAXIMIZE, "WM_MDIMAXIMIZE" },
428 { WM_MDITILE, "WM_MDITILE" },
429 { WM_MDICASCADE, "WM_MDICASCADE" },
430 { WM_MDIICONARRANGE, "WM_MDIICONARRANGE" },
431 { WM_MDIGETACTIVE, "WM_MDIGETACTIVE" },
432 { WM_MDISETMENU, "WM_MDISETMENU" },
433 { WM_DROPFILES, "WM_DROPFILES" },
434 { WM_MDIREFRESHMENU, "WM_MDIREFRESHMENU" },
435 { WM_CUT, "WM_CUT" },
436 { WM_COPY, "WM_COPY" },
437 { WM_PASTE, "WM_PASTE" },
438 { WM_CLEAR, "WM_CLEAR" },
439 { WM_UNDO, "WM_UNDO" },
440 { WM_RENDERFORMAT, "WM_RENDERFORMAT" },
441 { WM_RENDERALLFORMATS, "WM_RENDERALLFORMATS" },
442 { WM_DESTROYCLIPBOARD, "WM_DESTROYCLIPBOARD" },
443 { WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD" },
444 { WM_PAINTCLIPBOARD, "WM_PAINTCLIPBOARD" },
445 { WM_VSCROLLCLIPBOARD, "WM_VSCROLLCLIPBOARD" },
446 { WM_SIZECLIPBOARD, "WM_SIZECLIPBOARD" },
447 { WM_ASKCBFORMATNAME, "WM_ASKCBFORMATNAME" },
448 { WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN" },
449 { WM_HSCROLLCLIPBOARD, "WM_HSCROLLCLIPBOARD" },
450 { WM_QUERYNEWPALETTE, "WM_QUERYNEWPALETTE" },
451 { WM_PALETTEISCHANGING, "WM_PALETTEISCHANGING" },
452 { WM_PALETTECHANGED, "WM_PALETTECHANGED" },
453 { WM_HOTKEY, "WM_HOTKEY" },
454 { WM_PENWINFIRST, "WM_PENWINFIRST" },
455 { WM_PENWINLAST, "WM_PENWINLAST" },
456 { WM_ASYNCIO, "ASYNCIO" },
457 { 0, 0 }};
458
5abc9b83
CF
459void
460strace::wm (int message, int word, int lon)
1fd5e000 461{
5d970405 462 if (active ())
1fd5e000
CF
463 {
464 int i;
465
466 for (i = 0; ta[i].n; i++)
467 {
468 if (ta[i].v == message)
469 {
335556d5 470 prntf (_STRACE_WM, NULL, "wndproc %d %s %d %d", message, ta[i].n, word, lon);
1fd5e000
CF
471 return;
472 }
473 }
335556d5 474 prntf (_STRACE_WM, NULL, "wndproc %d unknown %d %d", message, word, lon);
1fd5e000
CF
475 }
476}
1fd5e000 477#endif /*NOSTRACE*/
This page took 0.527123 seconds and 5 git commands to generate.