source: trunk/src/kernel32/exceptstackdump.cpp@ 8401

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

hard disk access updates & fixes

File size: 10.6 KB
Line 
1/* $Id: exceptstackdump.cpp,v 1.5 2002-05-10 14:55:11 sandervl Exp $ */
2/*
3 * Stack dump code
4 *
5 * Based on XFolder's stack dumping facility:
6 * Copyright (C) 1992-99 Ulrich M”ller,
7 * Kim Rasmussen,
8 * Marc Fiammante,
9 * John Currier,
10 * Anthony Cruise.
11 *
12 */
13
14#define INCL_MISC
15#define INCL_BASE
16#include <os2.h> //No wrappers needed
17#include <stdio.h>
18#include <string.h>
19#include <misc.h>
20#include "exceptstackdump.h"
21#include "exceptutil.h"
22#include "asmutil.h"
23#include "oslibmisc.h"
24#include "winexebase.h"
25#include "windllbase.h"
26
27#define DBG_LOCALLOG DBG_exceptstackdump
28#include "dbglocal.h"
29
30int SYSTEM EXPORT WriteLogNoEOL(char *tekst, ...);
31
32#undef dprintf
33#define dprintf(a) if(DbgEnabledKERNEL32[DBG_LOCALLOG] == 1) WriteLogNoEOL a
34
35/* ******************************************************************
36 * *
37 * PART 3: ANALYZE SYMBOL (.SYM) FILE *
38 * *
39 ********************************************************************/
40
41/*
42 *@@ dbgPrintSYMInfo:
43 * this gets called by dbgPrintStack to check if a SYM
44 * file with the same filename exists and try to
45 * get the info from there.
46 *
47 * This gets called for every line of the stack
48 * walk, but only if getting the information from
49 * the debug code failed, e.g. because no debug code
50 * was available.
51 * The file pointer is in the "Source file" column
52 * every time.
53 *
54 * New with V0.84.
55 */
56
57BOOL dbgPrintSYMInfo(CHAR * SymFileName, ULONG Object, ULONG TrapOffset)
58{
59 static FILE *SymFile;
60 static MAPDEF MapDef;
61 static SEGDEF SegDef;
62 static SEGDEF *pSegDef;
63 static SYMDEF32 SymDef32;
64 static SYMDEF16 SymDef16;
65 static char Buffer[256];
66 static int SegNum, SymNum, LastVal;
67 static unsigned long int SegOffset,
68 SymOffset, SymPtrOffset;
69 int rc = FALSE;
70
71 // open .SYM file
72 SymFile = fopen(SymFileName, "rb");
73 if (SymFile == 0)
74 {
75// dprintf(("Could not open symbol file %s", SymFileName));
76 goto endofprintsym;
77 } // endif
78
79 // read in first map definition
80 fread(&MapDef, sizeof(MAPDEF), 1, SymFile);
81
82 SegOffset = SEGDEFOFFSET(MapDef);
83
84 // go thru all segments
85 for (SegNum = 0; SegNum < MapDef.cSegs; SegNum++)
86 {
87 // printf("Scanning segment #%d Offset %4.4hX",SegNum+1,SegOffset);
88 if (fseek(SymFile, SegOffset, SEEK_SET))
89 {
90 dprintf(("Seek error."));
91 goto endofprintsym;
92 }
93
94 // read in segment definition
95 fread(&SegDef, sizeof(SEGDEF), 1, SymFile);
96 if (SegNum == Object)
97 {
98 // stack object found:
99 Buffer[0] = 0x00;
100 LastVal = 0;
101
102 // go thru all symbols in this object
103 for (SymNum = 0; SymNum < SegDef.cSymbols; SymNum++)
104 {
105 // read in symbol offset USHORT
106 SymPtrOffset = SYMDEFOFFSET(SegOffset, SegDef, SymNum);
107 fseek(SymFile, SymPtrOffset, SEEK_SET);
108 fread(&SymOffset, sizeof(unsigned short int), 1, SymFile);
109
110 // go to symbol definition
111 fseek(SymFile, SymOffset + SegOffset, SEEK_SET);
112
113 if (SegDef.bFlags & 0x01)
114 {
115 // 32-bit symbol:
116 fread(&SymDef32, sizeof(SYMDEF32), 1, SymFile);
117#if 0
118 if (SymDef32.wSymVal == TrapOffset)
119 {
120 Buffer[0] = SymDef32.achSymName[0];
121 fread(&Buffer[1], 1, SymDef32.cbSymName, SymFile);
122 Buffer[SymDef32.cbSymName] = 0x00;
123 dprintf(("%s\n", Buffer));
124 rc = TRUE;
125 break;
126 }
127#endif
128 //SvL: If it's an exact match, then the app put a procedure
129 // address on the stack; ignore that
130 if (LastVal == TrapOffset) {
131 break;
132 }
133 if (SymDef32.wSymVal > TrapOffset)
134 {
135 // symbol found
136 dprintf(("between %s + 0x%X", Buffer, TrapOffset - LastVal));
137 }
138 LastVal = SymDef32.wSymVal;
139 Buffer[0] = SymDef32.achSymName[0];
140 fread(&Buffer[1], 1, SymDef32.cbSymName, SymFile);
141 Buffer[SymDef32.cbSymName] = 0x00;
142
143 if (SymDef32.wSymVal > TrapOffset)
144 {
145 // symbol found, as above
146 dprintf((" and %s - 0x%X\n", Buffer, LastVal - TrapOffset));
147 rc = TRUE;
148 break;
149 }
150 /*printf("32 Bit Symbol <%s> Address %p",Buffer,SymDef32.wSymVal); */
151 }
152 else
153 {
154 // 16-bit symbol:
155 fread(&SymDef16, sizeof(SYMDEF16), 1, SymFile);
156
157 //SvL: If it's an exact match, then the app put a procedure
158 // address on the stack; ignore that
159 if (LastVal == TrapOffset) {
160 break;
161 }
162
163 if (SymDef16.wSymVal > TrapOffset)
164 {
165 dprintf(("between %s + %X", Buffer, TrapOffset - LastVal));
166 }
167 LastVal = SymDef16.wSymVal;
168 Buffer[0] = SymDef16.achSymName[0];
169 fread(&Buffer[1], 1, SymDef16.cbSymName, SymFile);
170 Buffer[SymDef16.cbSymName] = 0x00;
171 if (SymDef16.wSymVal > TrapOffset)
172 {
173 dprintf((" and %s - %X\n", Buffer, LastVal - TrapOffset));
174 rc = TRUE;
175 break;
176 }
177 /*printf("16 Bit Symbol <%s> Address %p",Buffer,SymDef16.wSymVal); */
178 } // endif
179 }
180 break;
181 } // endif
182 SegOffset = NEXTSEGDEFOFFSET(SegDef);
183 } // endwhile
184endofprintsym:
185 if(SymFile) fclose(SymFile);
186 if(rc == FALSE) dprintf(("\n"));
187 return rc;
188}
189//******************************************************************************
190//******************************************************************************
191void dbgPrintStack(PEXCEPTIONREPORTRECORD pERepRec,
192 PEXCEPTIONREGISTRATIONRECORD pERegRec,
193 PCONTEXTRECORD pCtxRec,
194 PVOID p)
195{
196 ULONG Size, Attr, hMod, ObjNum, Offset, addr;
197 APIRET rc;
198 PTIB ptib = NULL;
199 PPIB ppib = NULL;
200 CHAR Name[CCHMAXPATH] = "unknown";
201 ULONG *stacktop, *stackbase;
202 UCHAR instr;
203 static BOOL fEntered = FALSE;
204
205 if(DosGetInfoBlocks(&ptib, &ppib) || ptib == NULL) {
206 return;
207 }
208 if(fEntered == TRUE) {
209 return;
210 }
211
212 fEntered = TRUE;
213
214 stacktop = (ULONG *)ptib->tib_pstacklimit - 4;
215 stackbase = (ULONG *)ptib->tib_pstack;
216 if(pCtxRec->ctx_RegEsp < (ULONG)stacktop && pCtxRec->ctx_RegEsp > (ULONG)stackbase)
217 {
218 stackbase = (ULONG *)pCtxRec->ctx_RegEsp;
219 }
220 else
221 if(pCtxRec->ctx_RegEbp < (ULONG)stacktop && pCtxRec->ctx_RegEbp > (ULONG)stackbase)
222 {
223 stackbase = (ULONG *)pCtxRec->ctx_RegEbp;
224 }
225 else stackbase = (ULONG *)getESP();
226
227 dprintf(("** BEGIN STACK DUMP **\n"));
228 while(stacktop > stackbase)
229 {
230 Size = 10;
231 rc = DosQueryMem((PVOID) (stacktop), &Size, &Attr);
232 if(rc != NO_ERROR || !(Attr & PAG_COMMIT) || (Size < 4))
233 {
234 break;
235 }
236
237 addr = *stacktop;
238 Size = 16;
239 rc = DosQueryMem((PVOID) (*stacktop-16), &Size, &Attr);
240 if(rc != NO_ERROR || ((Attr & (PAG_EXECUTE|PAG_READ|PAG_COMMIT)) != (PAG_EXECUTE|PAG_READ|PAG_COMMIT)) || (Size < 16)) {
241// dprintf(("skiploop %x (rc %x, Attr %x Size %d)\n", *stacktop, rc, Attr, Size));
242 if(WinExe && WinExe->insideModule(addr) && WinExe->insideModuleCode(addr)) {
243 sprintf(Name, "%s", WinExe->getModuleName());
244 dprintf(("%-13s at 0x%08x\n", Name, addr));
245 }
246 else {
247 Win32DllBase *dll = Win32DllBase::findModuleByAddr(addr);
248 if(dll && dll->insideModuleCode(addr)) {
249 sprintf(Name, "%s", dll->getModuleName());
250 dprintf(("%-13s at 0x%08x\n", Name, addr));
251 }
252 }
253
254 goto skiploop;
255 }
256#if 0
257 instr = *(UCHAR *)(((ULONG)*stacktop) - 5);
258 if(instr == 0xE8) {//call with displacement
259 addr = *(ULONG *)(((ULONG)*stacktop)-4);
260 addr+= (((ULONG)*stacktop)-5);
261 }
262// else {
263// if(*(UCHAR *)(((ULONG)*stacktop) - 6) == 0xff) {
264// modrm = *(UCHAR *)(((ULONG)*stacktop) - 5);
265// }
266 else
267#endif
268 addr = *stacktop;
269
270 rc = DosQueryModFromEIP(&hMod, &ObjNum, sizeof(Name),
271 Name, &Offset, addr);
272 if(rc == NO_ERROR && ObjNum != -1)
273 {
274 DosQueryModuleName(hMod, sizeof(Name), Name);
275
276 int namelen = strlen(Name);
277 if(namelen > 3)
278 {
279 if(addr > (ULONG)ptib->tib_pstacklimit || addr < (ULONG)ptib->tib_pstack) {
280 // print module and object
281 dprintf(("%-13s %04X at 0x%08x ", OSLibStripPath(Name), ObjNum + 1, addr));
282
283 strcpy(Name + namelen - 3, "SYM");
284 dbgPrintSYMInfo(Name, ObjNum, Offset);
285 }
286 }
287 else
288 {
289 dprintf(("*Unknown* at %x\n", addr));
290 }
291 }
292 else {
293 if(WinExe && WinExe->insideModule(addr) && WinExe->insideModuleCode(addr)) {
294 sprintf(Name, "%s", WinExe->getModuleName());
295 dprintf(("%-13s at 0x%08x\n", Name, addr));
296 }
297 else {
298 Win32DllBase *dll = Win32DllBase::findModuleByAddr(addr);
299 if(dll && dll->insideModuleCode(addr)) {
300 sprintf(Name, "%s", dll->getModuleName());
301 dprintf(("%-13s at 0x%08x\n", Name, addr));
302 }
303 }
304// dprintf(("unknown %x at 0x%x\n", stacktop, addr));
305 }
306skiploop:
307 stacktop -= 1;
308 } //while
309
310 addr = pCtxRec->ctx_RegEip;
311 if(WinExe && WinExe->insideModule(addr) && WinExe->insideModuleCode(addr)) {
312 sprintf(Name, "%s", WinExe->getModuleName());
313 dprintf(("%-13s at 0x%08x\n", Name, addr));
314 }
315 else {
316 Win32DllBase *dll = Win32DllBase::findModuleByAddr(addr);
317 if(dll && dll->insideModuleCode(addr)) {
318 sprintf(Name, "%s", dll->getModuleName());
319 dprintf(("%-13s at 0x%08x\n", Name, addr));
320 }
321 }
322
323 dprintf(("** END OF STACK DUMP **\n"));
324 fEntered = FALSE;
325}
326//******************************************************************************
327//******************************************************************************
Note: See TracBrowser for help on using the repository browser.