source: trunk/src/kernel32/oslibdebug.cpp@ 2803

Last change on this file since 2803 was 2803, checked in by sandervl, 26 years ago

Added new logging feature

File size: 12.8 KB
Line 
1/* $Id: oslibdebug.cpp,v 1.2 2000-02-16 14:25:44 sandervl Exp $ */
2
3/*
4 * OS/2 debug apis
5 *
6 * Copyright 1999 Edgar Buerkle
7 *
8 * NOTE: Including os2.h, so not automatic protection against FS trashing!
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13#define INCL_DOSPROCESS
14#define INCL_DOSSEMAPHORES
15#define INCL_DOSQUEUES
16#define INCL_DOSMODULEMGR
17#define INCL_DOSEXCEPTIONS
18#define INCL_DOSERRORS
19#include <os2.h>
20#include <process.h>
21#include <os2sel.h>
22#include <stdlib.h>
23#include <string.h>
24#include <misc.h>
25#include <windllbase.h>
26#include <winconst.h>
27#include "oslibdebug.h"
28
29#define DBG_LOCALLOG DBG_oslibdebug
30#include "dbglocal.h"
31
32#define DEBUG_QUEUENAME "\\QUEUES\\ODINTRACE\\"
33#define DEBUG_QSEMNAME "\\SEM32\\ODINTRACEQ\\"
34#define DEBUG_SEMNAME "\\SEM32\\ODINTRACE\\"
35
36//******************************************************************************
37//******************************************************************************
38VOID _Optlink DebugThread(VOID *argpid)
39{
40 CHAR QueueName[30]=DEBUG_QUEUENAME;
41 CHAR SemName[30]=DEBUG_SEMNAME;
42 CHAR QSemName[30]=DEBUG_QSEMNAME;
43 HQUEUE QueueHandle=0;
44 HEV hevSem=0, hevQSem=0;
45 int rc;
46 uDB_t DbgBuf={0};
47 char path[CCHMAXPATH];
48 Win32DllBase *winmod;
49 LPDEBUG_EVENT lpde;
50 ULONG *pid = (ULONG*)argpid;
51 char tmp[12];
52
53 dprintf(("KERNEL32: DebugThread pid:%d", *pid));
54
55 strcat(QueueName, itoa(getpid(), tmp, 10));
56 rc = DosCreateQueue( &QueueHandle , QUE_FIFO, QueueName);
57 if(rc != 0)
58 {
59 dprintf(("DebugThread: Could not create queue:%s rc:%d", QueueName, rc));
60 return;
61 }
62 strcat(SemName, itoa(getpid(), tmp, 10));
63 rc = DosCreateEventSem(SemName, &hevSem, 0, TRUE);
64 if(rc != 0)
65 {
66 dprintf(("DebugThread: Could not create event sem:%s rc:%d", SemName, rc));
67 DosCloseQueue(QueueHandle);
68 return;
69 }
70 strcat(QSemName, itoa(getpid(), tmp, 10));
71 rc = DosCreateEventSem(QSemName, &hevQSem, 0, FALSE);
72 if(rc != 0)
73 {
74 dprintf(("DebugThread: Could not create event sem:%s rc:%d", QSemName, rc));
75 DosCloseEventSem(hevSem);
76 DosCloseQueue(QueueHandle);
77 return;
78 }
79
80 // connect to debuggee
81 DbgBuf.Cmd = DBG_C_Connect;
82 DbgBuf.Pid = *pid;
83 DbgBuf.Tid = 0;
84 DbgBuf.Value = DBG_L_386;
85 DbgBuf.Addr = 1;
86 rc = DosDebug(&DbgBuf);
87 if (rc != 0)
88 {
89 dprintf(("DosDebug error: rc = %d error:%d", rc, DbgBuf.Value));
90 DosCloseQueue(QueueHandle);
91 DosCloseEventSem(hevSem);
92 return;
93 }
94
95 while(rc == 0)
96 {
97 DosWaitEventSem(hevSem, SEM_INDEFINITE_WAIT);
98
99 DosDebug_GO:
100 DbgBuf.Cmd = DBG_C_Go;
101 DbgBuf.Pid = *pid;
102
103 DebugApi:
104 rc = DosDebug(&DbgBuf);
105 if (rc != 0)
106 dprintf(("DosDebug error: rc = %d", rc));
107
108 switch (DbgBuf.Cmd)
109 {
110 case DBG_N_Success:
111 dprintf(("DosDebug: GO ok"));
112 goto DosDebug_GO;
113 case DBG_N_Error:
114 dprintf(("DosDebug: Error %d", DbgBuf.Value));
115 // if(DbgBuf.Value == ERROR_INVALID_PROCID) connect ?
116 if(DbgBuf.Value == ERROR_EXCL_SEM_ALREADY_OWNED)
117 {
118 rc = 0; // continue
119 goto DosDebug_GO;
120 }
121 break; // end thread !!!
122 case DBG_N_ProcTerm:
123 dprintf(("DosDebug: Process terminated with rc %d\n",DbgBuf.Value));
124 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
125 lpde->dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT_W;
126 lpde->dwProcessId = *pid;
127 lpde->dwThreadId = 0;
128 lpde->u.ExitThread.dwExitCode = DbgBuf.Value;
129 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
130 break;
131 case DBG_N_Exception:
132 dprintf(("DosDebug: Exception"));
133 // lpde = malloc(sizeof(DEBUG_EVENT));
134 // TODO: fill union
135 // DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
136 // break;
137 DbgBuf.Cmd = DBG_C_Continue;
138 DbgBuf.Value = XCPT_CONTINUE_SEARCH;
139 goto DebugApi;
140 case DBG_N_ModuleLoad:
141 DosQueryModuleName(DbgBuf.Value, CCHMAXPATH, path);
142 dprintf(("DosDebug: module loaded [%s]", path));
143
144 winmod = Win32DllBase::findModule(path);
145 // only odin32(win32) modules, hide OS/2 ones
146 if(!winmod)
147 {
148 dprintf(("DosDebug: os/2 module [%s], suppress", path));
149 goto DosDebug_GO;
150 }
151 dprintf(("DosDebug: win32 module [%s], inform", path));
152 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
153 lpde->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT_W;
154 lpde->dwProcessId = *pid;
155 lpde->dwThreadId = 0;
156 lpde->u.LoadDll.hFile = 0;
157 // TODO: make a pe fakeheader in our DLL's (kernel32,...)
158 lpde->u.LoadDll.lpBaseOfDll = WINIMAGE_LOOKUPADDR(winmod);
159 lpde->u.LoadDll.dwDebugInfoFileOffset = 0;
160 lpde->u.LoadDll.nDebugInfoSize = 0;
161 lpde->u.LoadDll.lpImageName = path;
162 lpde->u.LoadDll.fUnicode = FALSE;
163 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
164 break;
165 case DBG_N_CoError:
166 dprintf(("DosDebug: Coprocessor Error"));
167 // TODO: create an exception ?
168 goto DosDebug_GO;
169 break;
170 case DBG_N_ThreadTerm:
171 dprintf(("DosDebug: Thread %d terminated with rc %d", DbgBuf.Tid,DbgBuf.Value));
172 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
173 lpde->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT_W;
174 lpde->dwProcessId = *pid;
175 lpde->dwThreadId = DbgBuf.Tid;
176 lpde->u.ExitThread.dwExitCode = DbgBuf.Value;
177 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
178 break;
179 case DBG_N_AsyncStop:
180 dprintf(("DosDebug: Async stop"));
181 goto DosDebug_GO;
182 break;
183 case DBG_N_NewProc:
184 dprintf(("DosDebug: Debuggee started new Pid %d",DbgBuf.Value));
185 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
186 lpde->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT_W;
187 lpde->dwProcessId = *pid;
188 lpde->dwThreadId = 0;
189 //TODO: fill union
190 lpde->u.CreateProcessInfo.hFile = 0;
191 lpde->u.CreateProcessInfo.hProcess = 0;
192 lpde->u.CreateProcessInfo.hThread = 0;
193 lpde->u.CreateProcessInfo.lpBaseOfImage = NULL;
194 lpde->u.CreateProcessInfo.dwDebugInfoFileOffset = 0;
195 lpde->u.CreateProcessInfo.nDebugInfoSize = 0;
196 lpde->u.CreateProcessInfo.lpThreadLocalBase = NULL;
197 lpde->u.CreateProcessInfo.lpStartAddress = NULL;
198 lpde->u.CreateProcessInfo.lpImageName = NULL;
199 lpde->u.CreateProcessInfo.fUnicode = FALSE;
200 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
201 break;
202 case DBG_N_AliasFree:
203 dprintf(("DosDebug: AliasFree"));
204 goto DosDebug_GO;
205 break;
206 case DBG_N_Watchpoint:
207 dprintf(("DosDebug: WatchPoint"));
208 goto DosDebug_GO;
209 break;
210 case DBG_N_ThreadCreate:
211 dprintf(("DosDebug: Thread %d created",DbgBuf.Tid));
212 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
213 lpde->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT_W;
214 lpde->dwProcessId = *pid;
215 lpde->dwThreadId = DbgBuf.Tid;
216 //TODO: fill union
217 lpde->u.CreateThread.hThread = 0;
218 lpde->u.CreateThread.lpThreadLocalBase = NULL;
219 lpde->u.CreateThread.lpStartAddress = NULL;
220 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
221 break;
222 case DBG_N_ModuleFree:
223 DosQueryModuleName(DbgBuf.Value, CCHMAXPATH, path);
224 dprintf(("DosDebug: ModuleFree [%s]", path));
225 winmod = Win32DllBase::findModule(path);
226 // only odin32(win32) modules, hide OS/2 ones
227 if(!winmod)
228 {
229 dprintf(("DosDebug: os/2 module [%s], suppress", path));
230 break;
231 }
232 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
233 lpde->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT_W;
234 lpde->dwProcessId = *pid;
235 lpde->dwThreadId = 0;
236 lpde->u.UnloadDll.lpBaseOfDll = WINIMAGE_LOOKUPADDR(winmod);
237 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
238 break;
239 case DBG_N_RangeStep:
240 dprintf(("DosDebug: RangeStep"));
241 goto DosDebug_GO;
242 break;
243 default:
244 dprintf(("DosDebug: Unkown Notify %d", DbgBuf.Cmd));
245 goto DosDebug_GO;
246 break;
247 }
248 }
249
250 DosCloseQueue(QueueHandle);
251 DosCloseEventSem(hevSem);
252 DosCloseEventSem(hevQSem);
253 *pid = 0;
254
255}
256//******************************************************************************
257//******************************************************************************
258BOOL OSLibWaitForDebugEvent(LPDEBUG_EVENT lpde, DWORD dwTimeout)
259{
260 CHAR QueueName[30]=DEBUG_QUEUENAME;
261 CHAR SemName[30]=DEBUG_QSEMNAME;
262 LPDEBUG_EVENT lpde_queue;
263 int rc, req;
264 PID pidOwner;
265 HQUEUE QueueHandle=0;
266 REQUESTDATA Request = {0};
267 ULONG len;
268 BYTE prio;
269 HEV hevQSem=0;
270 char tmp[12];
271 USHORT sel = RestoreOS2FS();
272
273 strcat(SemName, itoa(getpid(),tmp, 10));
274 rc = DosOpenEventSem(SemName, &hevQSem);
275 if(rc != 0)
276 goto fail;
277
278 // get a DebugEvent from our DebugThread
279 strcat(QueueName, itoa(getpid(), tmp, 10));
280 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
281 Request.pid = pidOwner;
282 rc = DosReadQueue(QueueHandle, &Request, &len, (PPVOID) &lpde_queue, 0, DCWW_NOWAIT,
283 &prio, hevQSem);
284 if(rc == ERROR_QUE_EMPTY)
285 {
286 if(DosWaitEventSem(hevQSem, dwTimeout) == 0)
287 rc = DosReadQueue(QueueHandle, &Request, &len, (PPVOID) &lpde_queue, 0, DCWW_NOWAIT,
288 &prio, hevQSem);
289 }
290 if(rc != 0)
291 goto fail;
292
293 // copy DebugEvent to user space and free queue pointer
294 memcpy(lpde, lpde_queue, len);
295 free(lpde_queue);
296 // DosCloseEventSem(hevSem);
297 SetFS(sel);
298 return TRUE;
299
300fail:
301 // DosCloseEventSem(hevSem);
302 SetFS(sel);
303 return FALSE;
304}
305//******************************************************************************
306//******************************************************************************
307BOOL OSLibContinueDebugEvent(DWORD dwProcessId, DWORD dwThreadId, DWORD dwContinueStatus)
308{
309 CHAR SemName[30]=DEBUG_SEMNAME;
310 CHAR QueueName[30]=DEBUG_QUEUENAME;
311 PID pidOwner;
312 HQUEUE QueueHandle=0;
313 HEV hev=0;
314 int rc;
315 char tmp[12];
316 ULONG QEntries=0;
317 USHORT sel = RestoreOS2FS();
318
319 // only continue DebugThread, if queue is empty
320 strcat(QueueName, itoa(getpid(), tmp, 10));
321 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
322 rc = DosQueryQueue(QueueHandle, &QEntries);
323 if(QEntries > 0) {
324 SetFS(sel);
325 return TRUE;
326 }
327 // continue DebugThread
328 strcat(SemName, itoa(getpid(), tmp, 10));
329 rc = DosOpenEventSem(SemName, &hev);
330 rc = DosPostEventSem(hev);
331 // DosCloseEventSem(hev);
332 SetFS(sel);
333 return (rc == 0) ? TRUE : FALSE;
334}
335//******************************************************************************
336//******************************************************************************
337BOOL OSLibAddModuleDebugEvent(char *name, BOOL fLoad)
338{
339 Win32DllBase *winmod;
340 LPDEBUG_EVENT lpde;
341 int rc;
342 CHAR QueueName[30]=DEBUG_QUEUENAME;
343 PID pidOwner;
344 HQUEUE QueueHandle=0;
345 char tmp[12];
346 USHORT sel = RestoreOS2FS();
347
348 winmod = Win32DllBase::findModule(name);
349 if(!winmod)
350 {
351 dprintf(("OSLibAddModuleDebugEvent: ERROR could not find module [%s]", name));
352 SetFS(sel);
353 return FALSE;
354 }
355
356// strcat(QueueName, itoa(getDebuggerPID(), tmp, 10));
357 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
358
359 if(fLoad == TRUE)
360 {
361 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
362 lpde->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT_W;
363 lpde->dwProcessId = getpid(); // debuggee pid
364 lpde->dwThreadId = 0;
365 lpde->u.LoadDll.hFile = 0;
366 lpde->u.LoadDll.lpBaseOfDll = WINIMAGE_LOOKUPADDR(winmod);
367 lpde->u.LoadDll.dwDebugInfoFileOffset = 0;
368 lpde->u.LoadDll.nDebugInfoSize = 0;
369 lpde->u.LoadDll.lpImageName = name;
370 lpde->u.LoadDll.fUnicode = FALSE;
371 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
372 }
373 else
374 {
375 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
376 lpde->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT_W;
377 lpde->dwProcessId = getpid(); // debuggee pid
378 lpde->dwThreadId = 0;
379 lpde->u.UnloadDll.lpBaseOfDll = WINIMAGE_LOOKUPADDR(winmod);
380 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
381 }
382 SetFS(sel);
383 return TRUE;
384}
385//******************************************************************************
386//******************************************************************************
387VOID OSLibStartDebugger(ULONG *pid)
388{
389 USHORT sel = RestoreOS2FS();
390 TID tid;
391
392 tid = _beginthread(DebugThread, NULL, 1024, (PVOID) pid);
393 if(tid == 0)
394 {
395 dprintf(("OSLibStartDebugger: Could create debug thread"));
396 SetFS(sel);
397 return;
398 }
399 DosSleep(128);
400 SetFS(sel);
401}
402//******************************************************************************
403//******************************************************************************
Note: See TracBrowser for help on using the repository browser.