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

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

EB's debug support added

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