3 Copyright 2000, 2002 Red Hat, Inc.
5 This file is part of RDA, the Red Hat Debug Agent (and library).
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Alternative licenses for RDA may be arranged by contacting Red Hat,
30 #include <sys/strace.h>
33 #error The windows.h header is required when compiling for a Win32 target.
36 #include <sys/cygwin.h>
41 output_winerror (FILE *ofile, char *s)
43 char *winerr = strstr (s, "Win32 error ");
47 DWORD errnum = atoi (winerr + sizeof ("Win32 error ") - 1);
52 * NOTE: Currently there is no policy for how long the
53 * the buffers are, and looks like 256 is a smallest one
54 * (dlfcn.cc). Other than error 1395 (length 213) and
55 * error 1015 (length 249), the rest are all under 188
56 * characters, and so I'll use 189 as the buffer length.
57 * For those longer error messages, FormatMessage will
58 * return FALSE, and we'll get the old behaviour such as
59 * ``Win32 error 1395'' etc.
62 if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
63 | FORMAT_MESSAGE_IGNORE_INSERTS,
66 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
67 (LPTSTR) buf, sizeof (buf), NULL))
70 /* Get rid the trailing CR/NL pair. */
71 char *p = strchr (buf, '\0');
86 long long now = t + ((long long) 1/*usecs*/ * 10);
87 n.dwHighDateTime = now >> 32;
88 n.dwLowDateTime = now & 0xffffffff;
89 FileTimeToSystemTime (&n, &st);
93 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
94 #define INTROLEN (3 + 8)
97 win32_output_debug_string (child_process *process, DEBUG_EVENT &ev)
99 /* This includes the terminating null character already. */
100 DWORD size = ev.u.DebugString.nDebugStringLength;
101 BOOL unicode = ev.u.DebugString.fUnicode;
103 char *s = (char *) alloca (unicode ? 2 * size : size);
105 if (!ReadProcessMemory (process->process_hdl,
106 ev.u.DebugString.lpDebugStringData,
107 s, unicode ? 2 * size : size, NULL))
109 process->debug ("\nReadProcessMemory failed with error %d\n",
113 if (!strncmp (s, CYGWIN_SIGNAL_STRING, sizeof CYGWIN_SIGNAL_STRING - 1))
115 /* Cygwin raised a signal. */
116 process->set_break (strtol (s + sizeof CYGWIN_SIGNAL_STRING - 1, NULL,0));
118 process->debug ("Win32: Cygwin raised a signal %d\n",
119 process->stop_signal ());
121 return process->stop_signal ();
127 str = (char *) alloca (size);
128 WideCharToMultiByte (CP_ACP, 0, (const WCHAR *) s, -1,
129 str, size, NULL, NULL);
132 if (strncmp (s, "cYg", 3) && process->debug_process ())
134 fprintf (stderr, "%s\n", s);
138 if (!process->trace ())
141 int len = (int) strtoul (s + 3, NULL, 16);
151 if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
154 char *buf = s + INTROLEN;
157 s = strtok (buf, " ");
159 unsigned n = strtoul (s, NULL, 16);
161 s = strchr (s, '\0') + 1;
163 if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
167 if (!WriteProcessMemory (process->process_hdl, (LPVOID) n, &new_flag,
168 sizeof (new_flag), &nbytes))
169 process->debug ("Win32: couldn't write strace flag to child, "
170 "windows error %d", GetLastError ());
176 if (process->trace () & n)
178 else if (!(process->trace () & _STRACE_ALL) || (n & _STRACE_NOTALL))
179 return 0; /* This should not be included in "all" output */
182 char *ptusec, *ptrest;
184 dusecs = strtoul (s, &ptusec, 10);
190 usecs = strtoul (q, &ptrest, 10);
191 while (*ptrest == ' ')
201 if (process->saw_stars == 0)
206 GetSystemTimeAsFileTime (&st);
207 FileTimeToLocalFileTime (&st, &st);
208 process->start_time = st.dwHighDateTime;
209 process->start_time <<= 32;
210 process->start_time |= st.dwLowDateTime;
211 if (*(news = ptrest) != '[')
212 process->saw_stars = 2;
215 process->saw_stars++;
216 while ((news = strchr (news, ' ')) != NULL && *++news != '*')
219 process->saw_stars++;
227 else if (process->saw_stars < 2)
231 if (*(news = ptrest) != '[')
232 process->saw_stars = 2;
235 for (i = 0; i < process->nfields; i++)
236 if ((news = strchr (news, ' ')) == NULL)
237 break; // Should never happen
242 process->saw_stars = 2;
248 SYSTEMTIME *st = syst (process->start_time);
250 "Date/Time: %d-%02d-%02d %02d:%02d:%02d\n",
251 st->wYear, st->wMonth, st->wDay, st->wHour,
252 st->wMinute, st->wSecond);
253 process->saw_stars++;
259 long long d = usecs - process->last_usecs;
263 sprintf (intbuf, "%5d ", (int) d);
264 len = strlen (intbuf);
266 memcpy ((s -= len), intbuf, len);
268 process->last_usecs = usecs;
269 if (!output_winerror (stderr, s))