102 iList.Append(dllptr); |
102 iList.Append(dllptr); |
103 } |
103 } |
104 } |
104 } |
105 |
105 |
106 _LIT(KFormatStackInfo,"Stack %08x-%08x (? %d?), sp=%08x\r"); |
106 _LIT(KFormatStackInfo,"Stack %08x-%08x (? %d?), sp=%08x\r"); |
107 //_LIT(KGrabStack,"Capture stack data"); |
|
108 //_LIT(KNoStack,"Don't risk it"); |
|
109 |
107 |
110 HBufC8* GrabStack(const TDesC& /*aLine1*/, TThreadId aId, TUint aSp, TInt& aStackBase, TInt& aStackSize) |
108 HBufC8* GrabStack(const TDesC& /*aLine1*/, TThreadId aId, TUint aSp, TInt& aStackBase, TInt& aStackSize) |
111 { |
109 { |
112 TInt err=KErrNone; |
110 TInt err=KErrNone; |
113 #if 0 |
111 #if 0 |
146 |
144 |
147 // Ask the user if we want to risk grabbing the stack... |
145 // Ask the user if we want to risk grabbing the stack... |
148 |
146 |
149 TBuf<0x100> line2; |
147 TBuf<0x100> line2; |
150 line2.Format(KFormatStackInfo, aStackBase, aStackBase+aStackSize-1, aStackSize, aSp); |
148 line2.Format(KFormatStackInfo, aStackBase, aStackBase+aStackSize-1, aStackSize, aSp); |
151 //Don't ask the user just do it for WSERV |
149 |
152 /*RNotifier ask; |
|
153 if (ask.Connect() != KErrNone) |
|
154 return 0; |
|
155 TRequestStatus status; |
|
156 TInt buttonval=1; |
|
157 ask.Notify(aLine1,line2,KGrabStack,KNoStack,buttonval,status); |
|
158 User::WaitForRequest(status); |
|
159 ask.Close(); |
|
160 if (status.Int()!=KErrNone || buttonval != 0) |
|
161 return 0;*/ |
|
162 |
|
163 // OK - let stack grabbing commence |
150 // OK - let stack grabbing commence |
164 HBufC8* stackbuf = HBufC8::New(aStackSize); |
151 HBufC8* stackbuf = HBufC8::New(aStackSize); |
165 if (stackbuf==0) |
152 if (stackbuf==0) |
166 return 0; |
153 return 0; |
167 |
154 |
191 { |
178 { |
192 TBuf<0x100> line1; |
179 TBuf<0x100> line1; |
193 TBuf<0x100> line2; |
180 TBuf<0x100> line2; |
194 SDebugInfo info; |
181 SDebugInfo info; |
195 struct SRegisterInfo reginfo; |
182 struct SRegisterInfo reginfo; |
196 TUint pc; |
183 TUint pc = 0; |
197 TUint regs[16]; |
184 TUint regs[16]; |
198 const TDll* faultDll; |
185 const TDll* faultDll = NULL; |
199 |
186 |
200 _LIT(KInfo1, "D_EXC started"); |
187 _LIT(KInfo1, "D_EXC started"); |
201 User::InfoPrint(KInfo1); |
188 User::InfoPrint(KInfo1); |
202 |
189 |
203 TRequestStatus stat(0); |
190 TRequestStatus stat(0); |
204 // FOREVER |
191 // FOREVER |
205 for (TInt rep=0; rep<2; rep++) // die after two exceptions |
192 for (TInt rep=0; rep<2; rep++) // die after two exceptions |
206 { |
193 { |
207 TInt err; |
194 TInt err = KErrNone; |
208 // wait for any thread to panic... |
195 // wait for any thread to panic... |
209 |
196 |
210 |
197 |
211 err=RDebug::GetException(info,stat); |
198 err=RDebug::GetException(info,stat); |
212 if (err!=KErrNone) |
199 if (err!=KErrNone) |
255 err = RDebug::RegisterInfo(reginfo); |
242 err = RDebug::RegisterInfo(reginfo); |
256 if (!err) |
243 if (!err) |
257 { |
244 { |
258 RDebug::GetRegister(info.iId,reginfo.iNumberOfPcRegister, pc); |
245 RDebug::GetRegister(info.iId,reginfo.iNumberOfPcRegister, pc); |
259 for (int i=0; i<16; i++) |
246 for (int i=0; i<16; i++) |
|
247 { |
260 RDebug::GetRegister(info.iId, i, regs[i]); |
248 RDebug::GetRegister(info.iId, i, regs[i]); |
|
249 } |
261 } |
250 } |
262 |
251 |
263 TDllList::FindDlls(); |
252 TDllList::FindDlls(); |
264 |
253 |
265 stack=GrabStack(line1, info.iId, regs[KStackPointerReg], stackbase, stacksize); |
254 stack=GrabStack(line1, info.iId, regs[KStackPointerReg], stackbase, stacksize); |
266 |
255 |
267 //RDebug::KillThread(info.iId); |
|
268 RDebug::Close(); |
256 RDebug::Close(); |
269 } |
257 } |
270 |
258 |
271 |
259 |
272 _LIT(KFormatEXE, "pc=%08x, .map equivalent %08x\r"); |
260 _LIT(KFormatEXE, "pc=%08x, .map equivalent %08x\r"); |
273 _LIT(KFormatROM, "pc=%08x, in ROM\r"); |
261 _LIT(KFormatROM, "pc=%08x, in ROM\r"); |
274 _LIT(KFormatDll, "pc=%08x, in DLL %S, .map equivalent %08x\r"); |
262 _LIT(KFormatDll, "pc=%08x, in DLL %S, .map equivalent %08x\r"); |
275 _LIT(KFormatOther, "pc=%08x, iCodeAddr=%08x\r"); |
263 _LIT(KFormatOther, "pc=%08x, iCodeAddr=%08x\r"); |
276 _LIT(KFormatError, "(Unable to determine pc)\r"); |
264 _LIT(KFormatError, "(Unable to determine pc)\r"); |
277 |
265 |
|
266 |
278 if ((pc&3) == 0) |
267 if ((pc&3) == 0) |
279 { |
268 { |
280 if (pc >= 0x20000000 && pc < 0x30000000) |
269 if (pc >= 0x20000000 && pc < 0x30000000) |
|
270 { |
281 line2.Format(KFormatEXE, pc, pc-0x20000000+0x400010); |
271 line2.Format(KFormatEXE, pc, pc-0x20000000+0x400010); |
|
272 } |
|
273 else if (pc >= 0x50000000 && pc < 0x60000000) |
|
274 { |
|
275 line2.Format(KFormatROM, pc); |
|
276 } |
|
277 else if (TDllList::Match(pc, faultDll)==KErrNone) |
|
278 { |
|
279 line2.Format(KFormatDll, pc, &faultDll->iName, pc-(faultDll->iBase)+0x10000010); |
|
280 } |
282 else |
281 else |
283 if (pc >= 0x50000000 && pc < 0x60000000) |
282 { |
284 line2.Format(KFormatROM, pc); |
|
285 else |
|
286 if (TDllList::Match(pc, faultDll)==KErrNone) |
|
287 line2.Format(KFormatDll, pc, &faultDll->iName, pc-(faultDll->iBase)+0x10000010); |
|
288 |
|
289 else |
|
290 line2.Format(KFormatOther, pc, info.iCodeAddr); |
283 line2.Format(KFormatOther, pc, info.iCodeAddr); |
291 |
284 } |
292 } |
285 } |
293 else |
286 else |
|
287 { |
294 line2.Copy(KFormatError); |
288 line2.Copy(KFormatError); |
295 |
289 } |
|
290 |
296 RFs fs; |
291 RFs fs; |
297 err = fs.Connect(); |
292 err = fs.Connect(); |
298 if (err!=KErrNone) |
293 if (err!=KErrNone) |
|
294 { |
299 break; |
295 break; |
|
296 } |
300 |
297 |
301 _LIT(KFormatFilename,"d:\\d_exc_%d.txt"); |
298 _LIT(KFormatFilename,"d:\\d_exc_%d.txt"); |
302 _LIT(KFormatStackname,"d:\\d_exc_%d.stk"); |
299 _LIT(KFormatStackname,"d:\\d_exc_%d.stk"); |
303 |
300 |
304 // Report the basic information about registers, DLLs etc |
301 // Report the basic information about registers, DLLs etc |