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

Last change on this file since 10433 was 10433, checked in by bird, 22 years ago

#682: Test for DEBUG_LOGGING not DEBUG. dprintf may be used in release.

File size: 21.7 KB
Line 
1/* $Id: oslibdebug.cpp,v 1.8 2004-01-30 22:17:00 bird Exp $ */
2
3/*
4 * OS/2 debug apis
5 *
6 * Copyright 2000 Sander van Leeuwen
7 * Copyright 2000 Edgar Buerkle
8 * Copyright 2000 Michal Necasek
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 <os2wrap.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#include <stdio.h>
29
30#define DBG_LOCALLOG DBG_oslibdebug
31#include "dbglocal.h"
32static int superpid = 0;
33
34#define DEBUG_SEMNAME "\\SEM32\\ODINTRACE\\"
35#define DEBUG_QUEUENAME "\\QUEUES\\ODINTRACE\\"
36#define DEBUG_QSEMNAME "\\SEM32\\ODINTRACEQ\\"
37
38#define DEBUG_WINQSEMNAME "\\SEM32\\WINTRACEQ\\"
39#define DEBUG_WINQUEUENAME "\\QUEUES\\WINTRACE\\"
40
41#ifdef DEBUG
42typedef struct
43{
44 LPSTR pszMsg;
45 UINT msg;
46} MSGDESC, *PMSGDESC;
47
48//
49// Message description table. Describes each message that can be spied on.
50// This table must be kept in sorted order.
51//
52MSGDESC debugMsgs[] =
53{
54 { "EXCEPTION_DEBUG_EVENT", EXCEPTION_DEBUG_EVENT},
55 { "CREATE_THREAD_DEBUG_EVENT", CREATE_THREAD_DEBUG_EVENT}, // 0x0001
56 { "CREATE_PROCESS_DEBUG_EVENT", CREATE_PROCESS_DEBUG_EVENT},
57 { "EXIT_THREAD_DEBUG_EVENT", EXIT_THREAD_DEBUG_EVENT},
58 { "EXIT_PROCESS_DEBUG_EVENT", EXIT_PROCESS_DEBUG_EVENT}, // 0x0005
59 { "LOAD_DLL_DEBUG_EVENT", LOAD_DLL_DEBUG_EVENT},
60 { "UNLOAD_DLL_DEBUG_EVENT", UNLOAD_DLL_DEBUG_EVENT},
61 { "OUTPUT_DEBUG_STRING_EVENT", OUTPUT_DEBUG_STRING_EVENT},
62 { "RIP_EVENT", RIP_EVENT}
63};
64
65INT gcMessages = sizeof(debugMsgs) / sizeof(MSGDESC);
66
67char *GetDebugMsgText(int Msg)
68{
69 static char msgtxt[64];
70 int i;
71
72 for(i=0;i<gcMessages;i++) {
73 if(debugMsgs[i].msg == Msg)
74 return(debugMsgs[i].pszMsg);
75 }
76 sprintf(msgtxt, "%s %X ","Unknown Message ", Msg);
77 return(msgtxt);
78}
79#endif
80
81//******************************************************************************
82//******************************************************************************
83VOID _Optlink DebugThread(VOID *argpid)
84{
85 BOOL fTerminate = FALSE;
86 CHAR QueueName[30] = DEBUG_QUEUENAME;
87 CHAR WinQueueName[30] = DEBUG_WINQUEUENAME;
88 CHAR SemName[30] = DEBUG_SEMNAME;
89 CHAR QSemName[30] = DEBUG_QSEMNAME;
90 CHAR WinQSemName[30] = DEBUG_WINQSEMNAME;
91 HQUEUE QueueHandle = 0;
92 HQUEUE WinQueueHandle = 0;
93 HEV hevSem = 0,
94 hevQSem = 0,
95 hevWinQSem = 0;
96 uDB_t DbgBuf = {0};
97 int rc, rc2;
98 char path[CCHMAXPATH];
99 Win32DllBase *winmod;
100 REQUESTDATA Request = {0};
101 LPDEBUG_EVENT lpde,lpde2;
102 ULONG *pid = (ULONG*)argpid;
103 ULONG staticPid = *pid;
104 ULONG ulDataLen = 0, ulElemCode = 0, ulNumCalled = 0;
105 PVOID DataBuffer;
106 BYTE Priority = 0;
107 char tmp[12];
108
109 dprintf(("KERNEL32: DebugThread pid:%d", *pid));
110 //------------ Output queue ----------------
111 strcat(QueueName, itoa(*pid, tmp, 10));
112 rc = DosCreateQueue( &QueueHandle , QUE_FIFO, QueueName);
113 if(rc != 0)
114 {
115 dprintf(("DebugThread: Could not create output queue:%s rc:%d", QueueName, rc));
116 return;
117 }
118 dprintf(("DebugThread: Output queue %s created", QueueName));
119 //------------ Odin internal queue ----------------
120 strcat(WinQueueName, itoa(*pid, tmp, 10));
121 rc = DosCreateQueue( &WinQueueHandle , QUE_FIFO, WinQueueName);
122 if(rc != 0)
123 {
124 dprintf(("DebugThread: Could not create Odin queue:%s rc:%d", WinQueueName, rc));
125 return;
126 }
127 dprintf(("DebugThread: Odin internal win32 queue %s created", WinQueueName));
128 //------------- Main Debug Semaphore -----------------
129 strcat(SemName, itoa(*pid, tmp, 10));
130 rc = DosCreateEventSem(SemName, &hevSem, 0, TRUE);
131 if(rc != 0)
132 {
133 dprintf(("DebugThread: Could not create main debug sem:%s rc:%d", SemName, rc));
134 DosCloseQueue(QueueHandle);
135 DosCloseQueue(WinQueueHandle);
136 return;
137 }
138 dprintf(("DebugThread: Main debug semaphore %s created", SemName));
139
140 //------------- Odin internal queue semaphor ---------------
141 strcat(WinQSemName, itoa(*pid, tmp, 10));
142 rc = DosCreateEventSem(WinQSemName, &hevWinQSem, 0, FALSE);
143 if(rc != 0)
144 {
145 dprintf(("DebugThread: Could not create odin internal queue sem:%s rc:%d", QSemName, rc));
146 DosCloseEventSem(hevSem);
147 DosCloseQueue(WinQueueHandle);
148 DosCloseQueue(QueueHandle);
149 return;
150 }
151 dprintf(("DebugThread: Odin internal queue semaphore %s created", WinQSemName));
152
153 //------------- Output queue semaphor ---------------
154 strcat(QSemName, itoa(*pid, tmp, 10));
155 rc = DosCreateEventSem(QSemName, &hevQSem, 0, FALSE);
156 if(rc != 0)
157 {
158 dprintf(("DebugThread: Could not create event output queue sem:%s rc:%d", QSemName, rc));
159 DosCloseEventSem(hevSem);
160 DosCloseEventSem(hevWinQSem);
161 DosCloseQueue(WinQueueHandle);
162 DosCloseQueue(QueueHandle);
163 return;
164 }
165
166 // connect to debuggee
167 DbgBuf.Cmd = DBG_C_Connect;
168 DbgBuf.Pid = *pid;
169 DbgBuf.Tid = 0;
170 DbgBuf.Value = DBG_L_386;
171 DbgBuf.Addr = 1;
172 rc = DosDebug(&DbgBuf);
173 if (rc != 0)
174 {
175 dprintf(("DosDebug error: rc = %d error:%d", rc, DbgBuf.Value));
176 DosCloseQueue(WinQueueHandle);
177 DosCloseQueue(QueueHandle);
178 DosCloseEventSem(hevSem);
179 return;
180 }
181
182 while (rc == 0)
183 {
184 DosWaitEventSem(hevSem, SEM_INDEFINITE_WAIT);
185 DosResetEventSem(hevSem,&ulNumCalled);
186
187DosDebug_GO:
188 DbgBuf.Cmd = DBG_C_Go;
189 DbgBuf.Pid = *pid;
190
191 DebugApi:
192 rc = DosDebug(&DbgBuf);
193 if (rc != 0)
194 dprintf(("DosDebug error: rc = %d", rc));
195
196 if (fTerminate) // break out of the while loop
197 break;
198
199 switch (DbgBuf.Cmd)
200 {
201 case DBG_N_Success:
202 dprintf(("DosDebug: GO ok"));
203 goto DosDebug_GO;
204
205 case DBG_N_Error:
206 dprintf(("DosDebug: Error %d", DbgBuf.Value));
207 // if(DbgBuf.Value == ERROR_INVALID_PROCID) connect ?
208 if(DbgBuf.Value == ERROR_EXCL_SEM_ALREADY_OWNED)
209 {
210 rc = 0; // continue
211 goto DosDebug_GO;
212 }
213 break; // end thread !!!
214
215 case DBG_N_ProcTerm:
216 dprintf(("DosDebug: Process terminated with rc %d\n", DbgBuf.Value));
217 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
218 lpde->dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT_W;
219 lpde->dwProcessId = *pid;
220 lpde->dwThreadId = 0;
221 lpde->u.ExitThread.dwExitCode = DbgBuf.Value;
222 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
223 // We should now fire final DBG_C_Go and end processing. We shouldn't
224 // get any more debug events.
225 fTerminate = TRUE;
226 // goto DosDebug_GO; *pid is invalid?!?
227 DbgBuf.Cmd = DBG_C_Go;
228 DbgBuf.Pid = staticPid;
229 goto DebugApi;
230 break;
231
232 case DBG_N_Exception:
233 dprintf(("DosDebug: Exception"));
234 // lpde = malloc(sizeof(DEBUG_EVENT));
235 // TODO: fill union
236 // DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
237 // break;
238 if (DbgBuf.Value == 0 && DbgBuf.Buffer == XCPT_BREAKPOINT)
239 {
240 dprintf(("Breakpoint encountered"));
241 // This may be win32 event exception as well as common int3
242 Priority = 0;
243 ulElemCode = 0;
244 rc2 = DosPeekQueue(WinQueueHandle,&Request, &ulDataLen, (PPVOID)&lpde, &ulElemCode,DCWW_NOWAIT, &Priority, hevWinQSem);
245 if(rc2 == 0)
246 {
247 //There is a win32 event here
248 rc = DosReadQueue(WinQueueHandle, &Request, &ulDataLen, (PPVOID) &lpde, 0, DCWW_NOWAIT,
249 &Priority, hevWinQSem);
250 if (rc != 0)
251 dprintf(("DebugThread - DosReadQueue failed!"));
252 //Forward it to receiver
253 lpde2 = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
254 OSLibDebugReadMemory ( lpde, lpde2,sizeof(DEBUG_EVENT),NULL);
255 #ifdef DEBUG
256 dprintf(("DebugThread Win32 Event %s",GetDebugMsgText(lpde2->dwDebugEventCode)));
257 #endif
258 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde2, 0);
259 //Stay stopped
260 }
261 dprintf(("DebugThread - waiting for continue signal"));
262 DosWaitEventSem(hevSem, SEM_INDEFINITE_WAIT);
263 DosResetEventSem(hevSem,&ulNumCalled);
264 DbgBuf.Cmd = DBG_C_ReadReg;
265 rc = DosDebug(&DbgBuf);
266 if (rc != 0)
267 dprintf(("DosDebug error: rc = %d", rc));
268 DbgBuf.EIP++;
269 DbgBuf.Cmd = DBG_C_WriteReg;
270 rc = DosDebug(&DbgBuf);
271 if (rc != 0)
272 dprintf(("DosDebug error: rc = %d", rc));
273 DbgBuf.Cmd = DBG_C_Continue;
274 DbgBuf.Value = XCPT_CONTINUE_EXECUTION;
275 goto DebugApi;
276 }
277 DbgBuf.Cmd = DBG_C_Continue;
278 DbgBuf.Value = XCPT_CONTINUE_SEARCH;
279 goto DebugApi;
280
281 case DBG_N_ModuleLoad:
282 DosQueryModuleName(DbgBuf.Value, CCHMAXPATH, path);
283 dprintf(("DosDebug: module loaded [%s]", path));
284
285 winmod = Win32DllBase::findModule(path);
286 // only odin32(win32) modules, hide OS/2 ones
287 if(!winmod)
288 {
289 dprintf(("DosDebug: os/2 module [%s], suppress", path));
290 goto DosDebug_GO;
291 }
292 dprintf(("DosDebug: win32 module [%s], inform", path));
293 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
294 lpde->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT_W;
295 lpde->dwProcessId = *pid;
296 lpde->dwThreadId = 0;
297 lpde->u.LoadDll.hFile = 0;
298 // TODO: make a pe fakeheader in our DLL's (kernel32,...)
299 lpde->u.LoadDll.lpBaseOfDll = (PVOID)winmod->getInstanceHandle();
300 lpde->u.LoadDll.dwDebugInfoFileOffset = 0;
301 lpde->u.LoadDll.nDebugInfoSize = 0;
302 lpde->u.LoadDll.lpImageName = path;
303 lpde->u.LoadDll.fUnicode = FALSE;
304 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
305 break;
306
307 case DBG_N_CoError:
308 dprintf(("DosDebug: Coprocessor Error"));
309 // TODO: create an exception ?
310 goto DosDebug_GO;
311 break;
312
313 case DBG_N_ThreadTerm:
314 dprintf(("DosDebug: Thread %d terminated with rc %d", DbgBuf.Tid,DbgBuf.Value));
315 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
316 lpde->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT_W;
317 lpde->dwProcessId = *pid;
318 lpde->dwThreadId = DbgBuf.Tid;
319 lpde->u.ExitThread.dwExitCode = DbgBuf.Value;
320 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
321 break;
322
323 case DBG_N_AsyncStop:
324 dprintf(("DosDebug: Async stop"));
325 goto DosDebug_GO;
326 break;
327
328 case DBG_N_NewProc:
329 dprintf(("DosDebug: Debuggee started new Pid %d",DbgBuf.Value));
330 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
331 lpde->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT_W;
332 lpde->dwProcessId = *pid;
333 lpde->dwThreadId = 0;
334 //TODO: fill union
335 lpde->u.CreateProcessInfo.hFile = 0;
336 lpde->u.CreateProcessInfo.hProcess = 0;
337 lpde->u.CreateProcessInfo.hThread = 0;
338 lpde->u.CreateProcessInfo.lpBaseOfImage = NULL;
339 lpde->u.CreateProcessInfo.dwDebugInfoFileOffset = 0;
340 lpde->u.CreateProcessInfo.nDebugInfoSize = 0;
341 lpde->u.CreateProcessInfo.lpThreadLocalBase = NULL;
342 lpde->u.CreateProcessInfo.lpStartAddress = NULL;
343 lpde->u.CreateProcessInfo.lpImageName = NULL;
344 lpde->u.CreateProcessInfo.fUnicode = FALSE;
345 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
346 break;
347
348 case DBG_N_AliasFree:
349 dprintf(("DosDebug: AliasFree"));
350 goto DosDebug_GO;
351 break;
352
353 case DBG_N_Watchpoint:
354 dprintf(("DosDebug: WatchPoint"));
355 goto DosDebug_GO;
356 break;
357
358 case DBG_N_ThreadCreate:
359 // Note: Win32 debuggers expect a process creation event first!
360 dprintf(("DosDebug: Thread %d created",DbgBuf.Tid));
361
362 if (DbgBuf.Tid == 1) { // Is this the first thread of a process?
363 // If so, fake a process creation event
364 dprintf(("DosDebug: Faking process creation event"));
365 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
366 lpde->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT_W;
367 lpde->dwProcessId = *pid;
368 lpde->dwThreadId = 0;
369 //TODO: fill union
370 lpde->u.CreateProcessInfo.hFile = 0;
371 lpde->u.CreateProcessInfo.hProcess = 0;
372 lpde->u.CreateProcessInfo.hThread = 10;
373 lpde->u.CreateProcessInfo.lpBaseOfImage = NULL;
374 lpde->u.CreateProcessInfo.dwDebugInfoFileOffset = 0;
375 lpde->u.CreateProcessInfo.nDebugInfoSize = 0;
376 lpde->u.CreateProcessInfo.lpThreadLocalBase = NULL;
377 lpde->u.CreateProcessInfo.lpStartAddress = NULL;
378 lpde->u.CreateProcessInfo.lpImageName = NULL;
379 lpde->u.CreateProcessInfo.fUnicode = FALSE;
380 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
381 }
382 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
383 lpde->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT_W;
384 lpde->dwProcessId = *pid;
385 lpde->dwThreadId = DbgBuf.Tid;
386 //TODO: fill union
387 lpde->u.CreateThread.hThread = 0;
388 lpde->u.CreateThread.lpThreadLocalBase = NULL;
389 lpde->u.CreateThread.lpStartAddress = NULL;
390 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
391 break;
392
393 case DBG_N_ModuleFree:
394 DosQueryModuleName(DbgBuf.Value, CCHMAXPATH, path);
395 dprintf(("DosDebug: ModuleFree [%s]", path));
396 winmod = Win32DllBase::findModule(path);
397 // only odin32(win32) modules, hide OS/2 ones
398 if(!winmod)
399 {
400 dprintf(("DosDebug: os/2 module [%s], suppress", path));
401 goto DosDebug_GO;
402 }
403 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
404 lpde->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT_W;
405 lpde->dwProcessId = *pid;
406 lpde->dwThreadId = 0;
407 lpde->u.UnloadDll.lpBaseOfDll = (PVOID)winmod->getInstanceHandle();
408 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
409 break;
410
411 case DBG_N_RangeStep:
412 dprintf(("DosDebug: RangeStep"));
413 goto DosDebug_GO;
414 break;
415
416 default:
417 dprintf(("DosDebug: Unkown Notify %d", DbgBuf.Cmd));
418 goto DosDebug_GO;
419 break;
420 }
421 }
422
423 dprintf(("DosDebug - ending the service thread"));
424 DosCloseQueue(QueueHandle);
425 DosCloseQueue(WinQueueHandle);
426 DosCloseEventSem(hevSem);
427 DosCloseEventSem(hevQSem);
428// *pid = 0; No can do - for some reason *pid is invalid by now
429}
430
431//******************************************************************************
432//******************************************************************************
433BOOL OSLibWaitForDebugEvent(LPDEBUG_EVENT lpde, DWORD dwTimeout)
434{
435 CHAR QueueName[30]=DEBUG_QUEUENAME;
436 CHAR SemName[30]=DEBUG_QSEMNAME;
437 LPDEBUG_EVENT lpde_queue;
438 int rc, req;
439 PID pidOwner;
440 HQUEUE QueueHandle=0;
441 REQUESTDATA Request = {0};
442 ULONG len;
443 BYTE prio;
444 HEV hevQSem=0;
445 char tmp[12];
446 USHORT sel = RestoreOS2FS();
447
448 strcat(SemName, itoa(superpid,tmp, 10));
449 rc = DosOpenEventSem(SemName, &hevQSem);
450 if(rc != 0)
451 goto fail;
452
453 // get a DebugEvent from our DebugThread
454 strcat(QueueName, itoa(superpid, tmp, 10));
455 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
456 Request.pid = pidOwner;
457 rc = DosReadQueue(QueueHandle, &Request, &len, (PPVOID) &lpde_queue, 0, DCWW_NOWAIT,
458 &prio, hevQSem);
459 if(rc == ERROR_QUE_EMPTY)
460 {
461 if(DosWaitEventSem(hevQSem, dwTimeout) == 0)
462 rc = DosReadQueue(QueueHandle, &Request, &len, (PPVOID) &lpde_queue, 0, DCWW_NOWAIT,
463 &prio, hevQSem);
464 }
465 if(rc != 0)
466 goto fail;
467
468 // copy DebugEvent to user space and free queue pointer
469 memcpy(lpde, lpde_queue, len);
470 // free our lpd
471 free(lpde_queue);
472 // DosCloseEventSem(hevSem);
473 SetFS(sel);
474 return TRUE;
475
476fail:
477 // DosCloseEventSem(hevSem);
478 SetFS(sel);
479 return FALSE;
480}
481//******************************************************************************
482//******************************************************************************
483BOOL OSLibContinueDebugEvent(DWORD dwProcessId, DWORD dwThreadId, DWORD dwContinueStatus)
484{
485 CHAR SemName[30]=DEBUG_SEMNAME;
486 CHAR QueueName[30]=DEBUG_QUEUENAME;
487 PID pidOwner;
488 HQUEUE QueueHandle=0;
489 HEV hev=0;
490 int rc;
491 char tmp[12];
492 ULONG QEntries=0;
493 USHORT sel = RestoreOS2FS();
494
495 // only continue DebugThread, if queue is empty
496 strcat(QueueName, itoa(superpid, tmp, 10));
497 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
498 rc = DosQueryQueue(QueueHandle, &QEntries);
499 if(QEntries > 0) {
500 SetFS(sel);
501 return TRUE;
502 }
503 // continue DebugThread
504 strcat(SemName, itoa(superpid, tmp, 10));
505 rc = DosOpenEventSem(SemName, &hev);
506 if (rc != 0)
507 {
508 dprintf(("OSLibContinueDebugEvent: Failed to open even semaphore rc:%d",rc));
509 return FALSE;
510 }
511 rc = DosPostEventSem(hev);
512 if (rc != 0)
513 {
514 dprintf(("OSLibContinueDebugEvent: Failed to trigger semaphore rc:%d",rc));
515 return FALSE;
516 }
517 // DosCloseEventSem(hev);
518 SetFS(sel);
519 return TRUE;
520}
521//******************************************************************************
522//******************************************************************************
523BOOL OSLibAddModuleDebugEvent(char *name, BOOL fLoad)
524{
525 Win32DllBase *winmod;
526 LPDEBUG_EVENT lpde;
527 int rc;
528 CHAR QueueName[30]=DEBUG_QUEUENAME;
529 PID pidOwner;
530 HQUEUE QueueHandle=0;
531 char tmp[12];
532 USHORT sel = RestoreOS2FS();
533
534 winmod = Win32DllBase::findModule(name);
535 if(!winmod)
536 {
537 dprintf(("OSLibAddModuleDebugEvent: ERROR could not find module [%s]", name));
538 SetFS(sel);
539 return FALSE;
540 }
541
542// strcat(QueueName, itoa(getDebuggerPID(), tmp, 10));
543 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
544
545 if(fLoad == TRUE)
546 {
547 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
548 lpde->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT_W;
549 lpde->dwProcessId = getpid(); // debuggee pid
550 lpde->dwThreadId = 0;
551 lpde->u.LoadDll.hFile = 0;
552 lpde->u.LoadDll.lpBaseOfDll = (PVOID)winmod->getInstanceHandle();
553 lpde->u.LoadDll.dwDebugInfoFileOffset = 0;
554 lpde->u.LoadDll.nDebugInfoSize = 0;
555 lpde->u.LoadDll.lpImageName = name;
556 lpde->u.LoadDll.fUnicode = FALSE;
557 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
558 }
559 else
560 {
561 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
562 lpde->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT_W;
563 lpde->dwProcessId = getpid(); // debuggee pid
564 lpde->dwThreadId = 0;
565 lpde->u.UnloadDll.lpBaseOfDll = (PVOID)winmod->getInstanceHandle();
566 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
567 }
568 SetFS(sel);
569 return TRUE;
570}
571//******************************************************************************
572//******************************************************************************
573VOID OSLibStartDebugger(ULONG *pid)
574{
575 USHORT sel = RestoreOS2FS();
576 TID tid;
577
578 tid = _beginthread(DebugThread, NULL, 1024, (PVOID) pid);
579 superpid = *pid;
580 if (tid == 0)
581 {
582 dprintf(("OSLibStartDebugger: Could not create debug thread!"));
583 SetFS(sel);
584 return;
585 }
586 DosSleep(128);
587 SetFS(sel);
588}
589//******************************************************************************
590//******************************************************************************
591VOID OSLibDebugReadMemory(LPCVOID lpBaseAddress,LPVOID lpBuffer, DWORD cbRead, LPDWORD lpNumberOfBytesRead)
592{
593 uDB_t DbgBuf = {0};
594 USHORT sel = RestoreOS2FS();
595 APIRET rc;
596 dprintf(("OSLibDebugReadMemory - reading from pid %d",superpid));
597 DbgBuf.Pid = superpid;
598 DbgBuf.Cmd = DBG_C_ReadMemBuf;
599 DbgBuf.Addr = (ULONG)lpBaseAddress;
600 DbgBuf.Buffer = (ULONG)lpBuffer;
601 DbgBuf.Len = cbRead;
602 rc = DosDebug(&DbgBuf);
603 if (rc != 0)
604 {
605 dprintf(("OSLibDebugReadMemory(DosDebug) error: rc = %d error:%d", rc, DbgBuf.Value));
606 SetFS(sel);
607 return;
608 }
609 if (lpNumberOfBytesRead)
610 *lpNumberOfBytesRead = cbRead;
611 SetFS(sel);
612 return;
613}
614//******************************************************************************
615//******************************************************************************
616BOOL OSLibAddWin32Event(LPDEBUG_EVENT lpde)
617{
618 uDB_t DbgBuf = {0};
619 USHORT sel = RestoreOS2FS();
620 APIRET rc;
621 CHAR WinQueueName[30] = DEBUG_WINQUEUENAME;
622 CHAR SemName[30] = DEBUG_SEMNAME;
623 HEV hevSem = 0;
624 HANDLE WinQueueHandle;
625 LPDEBUG_EVENT lpde_copy = NULL;
626 char tmp[12];
627 PID pidOwner;
628
629 dprintf(("OSLibAddWin32Event"));
630 // open main debug semaphore
631 strcat(SemName, itoa(getpid(),tmp, 10));
632 rc = DosOpenEventSem(SemName, &hevSem);
633 if(rc != 0)
634 {
635 dprintf(("OSLibAddWin32Event failed to open semaphore %s - rc %d",SemName, rc));
636 goto fail;
637 }
638
639 // open Queues
640 strcat(WinQueueName, itoa(getpid(), tmp, 10));
641 rc = DosOpenQueue(&pidOwner, &WinQueueHandle, WinQueueName);
642 if (rc != 0)
643 {
644 dprintf(("OSLibAddWin32Event failed to open queue - rc %d",rc));
645 goto fail;
646 }
647
648 // copy data to our buffer
649 lpde_copy = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
650 memcpy(lpde_copy,lpde,sizeof(DEBUG_EVENT));
651 rc = DosWriteQueue(WinQueueHandle, 0, sizeof(DEBUG_EVENT), lpde_copy, 0);
652 if (rc !=0 )
653 {
654 dprintf(("OSLibAddWin32Event failed to write to queue - rc %d",rc));
655 goto fail;
656 }
657
658 // and post notification
659 rc = DosPostEventSem(hevSem);
660 if (rc != 0)
661 {
662 dprintf(("OSLibAddWin32Event failed to trigger semaphore - rc %d",rc));
663 goto fail;
664 }
665 _interrupt(3);
666 free(lpde_copy);
667 DosCloseEventSem(hevSem);
668 DosCloseQueue(WinQueueHandle);
669 SetFS(sel);
670 return TRUE;
671fail:
672 if (lpde_copy) free(lpde_copy);
673 DosCloseEventSem(hevSem);
674 DosCloseQueue(WinQueueHandle);
675 SetFS(sel);
676 return FALSE;
677}
Note: See TracBrowser for help on using the repository browser.