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

Last change on this file since 8504 was 8504, checked in by sandervl, 23 years ago

PF: Debugger updates

File size: 21.7 KB
Line 
1/* $Id: oslibdebug.cpp,v 1.7 2002-05-28 09:53:34 sandervl 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 dprintf(("DebugThread Win32 Event %s",GetDebugMsgText(lpde2->dwDebugEventCode)));
256 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde2, 0);
257 //Stay stopped
258 }
259 dprintf(("DebugThread - waiting for continue signal"));
260 DosWaitEventSem(hevSem, SEM_INDEFINITE_WAIT);
261 DosResetEventSem(hevSem,&ulNumCalled);
262 DbgBuf.Cmd = DBG_C_ReadReg;
263 rc = DosDebug(&DbgBuf);
264 if (rc != 0)
265 dprintf(("DosDebug error: rc = %d", rc));
266 DbgBuf.EIP++;
267 DbgBuf.Cmd = DBG_C_WriteReg;
268 rc = DosDebug(&DbgBuf);
269 if (rc != 0)
270 dprintf(("DosDebug error: rc = %d", rc));
271 DbgBuf.Cmd = DBG_C_Continue;
272 DbgBuf.Value = XCPT_CONTINUE_EXECUTION;
273 goto DebugApi;
274 }
275 DbgBuf.Cmd = DBG_C_Continue;
276 DbgBuf.Value = XCPT_CONTINUE_SEARCH;
277 goto DebugApi;
278
279 case DBG_N_ModuleLoad:
280 DosQueryModuleName(DbgBuf.Value, CCHMAXPATH, path);
281 dprintf(("DosDebug: module loaded [%s]", path));
282
283 winmod = Win32DllBase::findModule(path);
284 // only odin32(win32) modules, hide OS/2 ones
285 if(!winmod)
286 {
287 dprintf(("DosDebug: os/2 module [%s], suppress", path));
288 goto DosDebug_GO;
289 }
290 dprintf(("DosDebug: win32 module [%s], inform", path));
291 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
292 lpde->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT_W;
293 lpde->dwProcessId = *pid;
294 lpde->dwThreadId = 0;
295 lpde->u.LoadDll.hFile = 0;
296 // TODO: make a pe fakeheader in our DLL's (kernel32,...)
297 lpde->u.LoadDll.lpBaseOfDll = (PVOID)winmod->getInstanceHandle();
298 lpde->u.LoadDll.dwDebugInfoFileOffset = 0;
299 lpde->u.LoadDll.nDebugInfoSize = 0;
300 lpde->u.LoadDll.lpImageName = path;
301 lpde->u.LoadDll.fUnicode = FALSE;
302 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
303 break;
304
305 case DBG_N_CoError:
306 dprintf(("DosDebug: Coprocessor Error"));
307 // TODO: create an exception ?
308 goto DosDebug_GO;
309 break;
310
311 case DBG_N_ThreadTerm:
312 dprintf(("DosDebug: Thread %d terminated with rc %d", DbgBuf.Tid,DbgBuf.Value));
313 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
314 lpde->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT_W;
315 lpde->dwProcessId = *pid;
316 lpde->dwThreadId = DbgBuf.Tid;
317 lpde->u.ExitThread.dwExitCode = DbgBuf.Value;
318 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
319 break;
320
321 case DBG_N_AsyncStop:
322 dprintf(("DosDebug: Async stop"));
323 goto DosDebug_GO;
324 break;
325
326 case DBG_N_NewProc:
327 dprintf(("DosDebug: Debuggee started new Pid %d",DbgBuf.Value));
328 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
329 lpde->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT_W;
330 lpde->dwProcessId = *pid;
331 lpde->dwThreadId = 0;
332 //TODO: fill union
333 lpde->u.CreateProcessInfo.hFile = 0;
334 lpde->u.CreateProcessInfo.hProcess = 0;
335 lpde->u.CreateProcessInfo.hThread = 0;
336 lpde->u.CreateProcessInfo.lpBaseOfImage = NULL;
337 lpde->u.CreateProcessInfo.dwDebugInfoFileOffset = 0;
338 lpde->u.CreateProcessInfo.nDebugInfoSize = 0;
339 lpde->u.CreateProcessInfo.lpThreadLocalBase = NULL;
340 lpde->u.CreateProcessInfo.lpStartAddress = NULL;
341 lpde->u.CreateProcessInfo.lpImageName = NULL;
342 lpde->u.CreateProcessInfo.fUnicode = FALSE;
343 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
344 break;
345
346 case DBG_N_AliasFree:
347 dprintf(("DosDebug: AliasFree"));
348 goto DosDebug_GO;
349 break;
350
351 case DBG_N_Watchpoint:
352 dprintf(("DosDebug: WatchPoint"));
353 goto DosDebug_GO;
354 break;
355
356 case DBG_N_ThreadCreate:
357 // Note: Win32 debuggers expect a process creation event first!
358 dprintf(("DosDebug: Thread %d created",DbgBuf.Tid));
359
360 if (DbgBuf.Tid == 1) { // Is this the first thread of a process?
361 // If so, fake a process creation event
362 dprintf(("DosDebug: Faking process creation event"));
363 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
364 lpde->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT_W;
365 lpde->dwProcessId = *pid;
366 lpde->dwThreadId = 0;
367 //TODO: fill union
368 lpde->u.CreateProcessInfo.hFile = 0;
369 lpde->u.CreateProcessInfo.hProcess = 0;
370 lpde->u.CreateProcessInfo.hThread = 10;
371 lpde->u.CreateProcessInfo.lpBaseOfImage = NULL;
372 lpde->u.CreateProcessInfo.dwDebugInfoFileOffset = 0;
373 lpde->u.CreateProcessInfo.nDebugInfoSize = 0;
374 lpde->u.CreateProcessInfo.lpThreadLocalBase = NULL;
375 lpde->u.CreateProcessInfo.lpStartAddress = NULL;
376 lpde->u.CreateProcessInfo.lpImageName = NULL;
377 lpde->u.CreateProcessInfo.fUnicode = FALSE;
378 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
379 }
380 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
381 lpde->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT_W;
382 lpde->dwProcessId = *pid;
383 lpde->dwThreadId = DbgBuf.Tid;
384 //TODO: fill union
385 lpde->u.CreateThread.hThread = 0;
386 lpde->u.CreateThread.lpThreadLocalBase = NULL;
387 lpde->u.CreateThread.lpStartAddress = NULL;
388 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
389 break;
390
391 case DBG_N_ModuleFree:
392 DosQueryModuleName(DbgBuf.Value, CCHMAXPATH, path);
393 dprintf(("DosDebug: ModuleFree [%s]", path));
394 winmod = Win32DllBase::findModule(path);
395 // only odin32(win32) modules, hide OS/2 ones
396 if(!winmod)
397 {
398 dprintf(("DosDebug: os/2 module [%s], suppress", path));
399 goto DosDebug_GO;
400 }
401 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
402 lpde->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT_W;
403 lpde->dwProcessId = *pid;
404 lpde->dwThreadId = 0;
405 lpde->u.UnloadDll.lpBaseOfDll = (PVOID)winmod->getInstanceHandle();
406 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
407 break;
408
409 case DBG_N_RangeStep:
410 dprintf(("DosDebug: RangeStep"));
411 goto DosDebug_GO;
412 break;
413
414 default:
415 dprintf(("DosDebug: Unkown Notify %d", DbgBuf.Cmd));
416 goto DosDebug_GO;
417 break;
418 }
419 }
420
421 dprintf(("DosDebug - ending the service thread"));
422 DosCloseQueue(QueueHandle);
423 DosCloseQueue(WinQueueHandle);
424 DosCloseEventSem(hevSem);
425 DosCloseEventSem(hevQSem);
426// *pid = 0; No can do - for some reason *pid is invalid by now
427}
428
429//******************************************************************************
430//******************************************************************************
431BOOL OSLibWaitForDebugEvent(LPDEBUG_EVENT lpde, DWORD dwTimeout)
432{
433 CHAR QueueName[30]=DEBUG_QUEUENAME;
434 CHAR SemName[30]=DEBUG_QSEMNAME;
435 LPDEBUG_EVENT lpde_queue;
436 int rc, req;
437 PID pidOwner;
438 HQUEUE QueueHandle=0;
439 REQUESTDATA Request = {0};
440 ULONG len;
441 BYTE prio;
442 HEV hevQSem=0;
443 char tmp[12];
444 USHORT sel = RestoreOS2FS();
445
446 strcat(SemName, itoa(superpid,tmp, 10));
447 rc = DosOpenEventSem(SemName, &hevQSem);
448 if(rc != 0)
449 goto fail;
450
451 // get a DebugEvent from our DebugThread
452 strcat(QueueName, itoa(superpid, tmp, 10));
453 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
454 Request.pid = pidOwner;
455 rc = DosReadQueue(QueueHandle, &Request, &len, (PPVOID) &lpde_queue, 0, DCWW_NOWAIT,
456 &prio, hevQSem);
457 if(rc == ERROR_QUE_EMPTY)
458 {
459 if(DosWaitEventSem(hevQSem, dwTimeout) == 0)
460 rc = DosReadQueue(QueueHandle, &Request, &len, (PPVOID) &lpde_queue, 0, DCWW_NOWAIT,
461 &prio, hevQSem);
462 }
463 if(rc != 0)
464 goto fail;
465
466 // copy DebugEvent to user space and free queue pointer
467 memcpy(lpde, lpde_queue, len);
468 // free our lpd
469 free(lpde_queue);
470 // DosCloseEventSem(hevSem);
471 SetFS(sel);
472 return TRUE;
473
474fail:
475 // DosCloseEventSem(hevSem);
476 SetFS(sel);
477 return FALSE;
478}
479//******************************************************************************
480//******************************************************************************
481BOOL OSLibContinueDebugEvent(DWORD dwProcessId, DWORD dwThreadId, DWORD dwContinueStatus)
482{
483 CHAR SemName[30]=DEBUG_SEMNAME;
484 CHAR QueueName[30]=DEBUG_QUEUENAME;
485 PID pidOwner;
486 HQUEUE QueueHandle=0;
487 HEV hev=0;
488 int rc;
489 char tmp[12];
490 ULONG QEntries=0;
491 USHORT sel = RestoreOS2FS();
492
493 // only continue DebugThread, if queue is empty
494 strcat(QueueName, itoa(superpid, tmp, 10));
495 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
496 rc = DosQueryQueue(QueueHandle, &QEntries);
497 if(QEntries > 0) {
498 SetFS(sel);
499 return TRUE;
500 }
501 // continue DebugThread
502 strcat(SemName, itoa(superpid, tmp, 10));
503 rc = DosOpenEventSem(SemName, &hev);
504 if (rc != 0)
505 {
506 dprintf(("OSLibContinueDebugEvent: Failed to open even semaphore rc:%d",rc));
507 return FALSE;
508 }
509 rc = DosPostEventSem(hev);
510 if (rc != 0)
511 {
512 dprintf(("OSLibContinueDebugEvent: Failed to trigger semaphore rc:%d",rc));
513 return FALSE;
514 }
515 // DosCloseEventSem(hev);
516 SetFS(sel);
517 return TRUE;
518}
519//******************************************************************************
520//******************************************************************************
521BOOL OSLibAddModuleDebugEvent(char *name, BOOL fLoad)
522{
523 Win32DllBase *winmod;
524 LPDEBUG_EVENT lpde;
525 int rc;
526 CHAR QueueName[30]=DEBUG_QUEUENAME;
527 PID pidOwner;
528 HQUEUE QueueHandle=0;
529 char tmp[12];
530 USHORT sel = RestoreOS2FS();
531
532 winmod = Win32DllBase::findModule(name);
533 if(!winmod)
534 {
535 dprintf(("OSLibAddModuleDebugEvent: ERROR could not find module [%s]", name));
536 SetFS(sel);
537 return FALSE;
538 }
539
540// strcat(QueueName, itoa(getDebuggerPID(), tmp, 10));
541 rc = DosOpenQueue(&pidOwner, &QueueHandle, QueueName);
542
543 if(fLoad == TRUE)
544 {
545 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
546 lpde->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT_W;
547 lpde->dwProcessId = getpid(); // debuggee pid
548 lpde->dwThreadId = 0;
549 lpde->u.LoadDll.hFile = 0;
550 lpde->u.LoadDll.lpBaseOfDll = (PVOID)winmod->getInstanceHandle();
551 lpde->u.LoadDll.dwDebugInfoFileOffset = 0;
552 lpde->u.LoadDll.nDebugInfoSize = 0;
553 lpde->u.LoadDll.lpImageName = name;
554 lpde->u.LoadDll.fUnicode = FALSE;
555 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
556 }
557 else
558 {
559 lpde = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
560 lpde->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT_W;
561 lpde->dwProcessId = getpid(); // debuggee pid
562 lpde->dwThreadId = 0;
563 lpde->u.UnloadDll.lpBaseOfDll = (PVOID)winmod->getInstanceHandle();
564 DosWriteQueue(QueueHandle, 0, sizeof(DEBUG_EVENT), lpde, 0);
565 }
566 SetFS(sel);
567 return TRUE;
568}
569//******************************************************************************
570//******************************************************************************
571VOID OSLibStartDebugger(ULONG *pid)
572{
573 USHORT sel = RestoreOS2FS();
574 TID tid;
575
576 tid = _beginthread(DebugThread, NULL, 1024, (PVOID) pid);
577 superpid = *pid;
578 if (tid == 0)
579 {
580 dprintf(("OSLibStartDebugger: Could not create debug thread!"));
581 SetFS(sel);
582 return;
583 }
584 DosSleep(128);
585 SetFS(sel);
586}
587//******************************************************************************
588//******************************************************************************
589VOID OSLibDebugReadMemory(LPCVOID lpBaseAddress,LPVOID lpBuffer, DWORD cbRead, LPDWORD lpNumberOfBytesRead)
590{
591 uDB_t DbgBuf = {0};
592 USHORT sel = RestoreOS2FS();
593 APIRET rc;
594 dprintf(("OSLibDebugReadMemory - reading from pid %d",superpid));
595 DbgBuf.Pid = superpid;
596 DbgBuf.Cmd = DBG_C_ReadMemBuf;
597 DbgBuf.Addr = (ULONG)lpBaseAddress;
598 DbgBuf.Buffer = (ULONG)lpBuffer;
599 DbgBuf.Len = cbRead;
600 rc = DosDebug(&DbgBuf);
601 if (rc != 0)
602 {
603 dprintf(("OSLibDebugReadMemory(DosDebug) error: rc = %d error:%d", rc, DbgBuf.Value));
604 SetFS(sel);
605 return;
606 }
607 if (lpNumberOfBytesRead)
608 *lpNumberOfBytesRead = cbRead;
609 SetFS(sel);
610 return;
611}
612//******************************************************************************
613//******************************************************************************
614BOOL OSLibAddWin32Event(LPDEBUG_EVENT lpde)
615{
616 uDB_t DbgBuf = {0};
617 USHORT sel = RestoreOS2FS();
618 APIRET rc;
619 CHAR WinQueueName[30] = DEBUG_WINQUEUENAME;
620 CHAR SemName[30] = DEBUG_SEMNAME;
621 HEV hevSem = 0;
622 HANDLE WinQueueHandle;
623 LPDEBUG_EVENT lpde_copy = NULL;
624 char tmp[12];
625 PID pidOwner;
626
627 dprintf(("OSLibAddWin32Event"));
628 // open main debug semaphore
629 strcat(SemName, itoa(getpid(),tmp, 10));
630 rc = DosOpenEventSem(SemName, &hevSem);
631 if(rc != 0)
632 {
633 dprintf(("OSLibAddWin32Event failed to open semaphore %s - rc %d",SemName, rc));
634 goto fail;
635 }
636
637 // open Queues
638 strcat(WinQueueName, itoa(getpid(), tmp, 10));
639 rc = DosOpenQueue(&pidOwner, &WinQueueHandle, WinQueueName);
640 if (rc != 0)
641 {
642 dprintf(("OSLibAddWin32Event failed to open queue - rc %d",rc));
643 goto fail;
644 }
645
646 // copy data to our buffer
647 lpde_copy = (LPDEBUG_EVENT) malloc(sizeof(DEBUG_EVENT));
648 memcpy(lpde_copy,lpde,sizeof(DEBUG_EVENT));
649 rc = DosWriteQueue(WinQueueHandle, 0, sizeof(DEBUG_EVENT), lpde_copy, 0);
650 if (rc !=0 )
651 {
652 dprintf(("OSLibAddWin32Event failed to write to queue - rc %d",rc));
653 goto fail;
654 }
655
656 // and post notification
657 rc = DosPostEventSem(hevSem);
658 if (rc != 0)
659 {
660 dprintf(("OSLibAddWin32Event failed to trigger semaphore - rc %d",rc));
661 goto fail;
662 }
663 _interrupt(3);
664 free(lpde_copy);
665 DosCloseEventSem(hevSem);
666 DosCloseQueue(WinQueueHandle);
667 SetFS(sel);
668 return TRUE;
669fail:
670 if (lpde_copy) free(lpde_copy);
671 DosCloseEventSem(hevSem);
672 DosCloseQueue(WinQueueHandle);
673 SetFS(sel);
674 return FALSE;
675}
Note: See TracBrowser for help on using the repository browser.