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

Last change on this file since 4387 was 4387, checked in by sandervl, 25 years ago

fixes for FS macro changes

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