Ecco splash sound fix?
[picodrive.git] / platform / uiq3 / engine / debug.cpp
CommitLineData
cc68a136 1\r
2#include <e32svr.h> // RDebug\r
3#include "debug.h"\r
4\r
5#ifdef __WINS__\r
6\r
7void ExceptionHandler(TExcType exc) {}\r
8\r
9#else\r
10\r
11static const wchar_t * const exception_names[] = {\r
12 L"General",\r
13 L"IntegerDivideByZero",\r
14 L"SingleStep",\r
15 L"BreakPoint",\r
16 L"IntegerOverflow",\r
17 L"BoundsCheck",\r
18 L"InvalidOpCode",\r
19 L"DoubleFault",\r
20 L"StackFault",\r
21 L"AccessViolation",\r
22 L"PrivInstruction",\r
23 L"Alignment",\r
24 L"PageFault",\r
25 L"FloatDenormal",\r
26 L"FloatDivideByZero",\r
27 L"FloatInexactResult",\r
28 L"FloatInvalidOperation",\r
29 L"FloatOverflow",\r
30 L"FloatStackCheck",\r
31 L"FloatUnderflow",\r
32 L"Abort",\r
33 L"Kill",\r
34 L"DataAbort",\r
35 L"CodeAbort",\r
36 L"MaxNumber",\r
37 L"InvalidVector",\r
38 L"UserInterrupt",\r
39 L"Unknown"\r
40};\r
41\r
42\r
43static void getASpace(TUint *code_start, TUint *code_end, TUint *stack_start, TUint *stack_end)\r
44{\r
45 TUint pc, sp;\r
46 RChunk chunk;\r
47 TFullName chunkname;\r
48 TFindChunk findChunk(_L("*"));\r
49\r
50 asm volatile ("str pc, %0" : "=m" (pc) );\r
51 asm volatile ("str sp, %0" : "=m" (sp) );\r
52\r
53 while( findChunk.Next(chunkname) != KErrNotFound ) {\r
54 chunk.Open(findChunk);\r
55 if((TUint)chunk.Base()+chunk.Bottom() < pc && pc < (TUint)chunk.Base()+chunk.Top()) {\r
56 if(code_start) *code_start = (TUint)chunk.Base()+chunk.Bottom();\r
57 if(code_end) *code_end = (TUint)chunk.Base()+chunk.Top();\r
58 } else\r
59 if((TUint)chunk.Base()+chunk.Bottom() < sp && sp < (TUint)chunk.Base()+chunk.Top()) {\r
60 if(stack_start) *stack_start = (TUint)chunk.Base()+chunk.Bottom();\r
61 if(stack_end) *stack_end = (TUint)chunk.Base()+chunk.Top();\r
62 }\r
63 chunk.Close();\r
64 }\r
65}\r
66\r
67// tmp\r
68#if defined(__DEBUG_PRINT)\r
69extern "C" char *debugString();\r
70#endif\r
71\r
72// our very own exception handler\r
73void ExceptionHandler(TExcType exc)\r
74{\r
75 TUint lr, sp, i;\r
76 TUint stack_end = 0; // ending address of our stack chunk\r
77 TUint code_start = 0, code_end = 0; // starting and ending addresses of our code chunk\r
78 TUint guessed_address = 0;\r
79\r
80 DEBUGPRINT(_L("ExceptionHandler()")); // this seems to never be called\r
81\r
82 asm volatile ("str lr, %0" : "=m" (lr) );\r
83 asm volatile ("str sp, %0" : "=m" (sp) );\r
84\r
85 // first get some info about the chunks we live in\r
86 getASpace(&code_start, &code_end, 0, &stack_end);\r
87\r
88 // now we begin some black magic tricks\r
89 // we go up our stack until we pass our caller address\r
90 for(; sp < stack_end; sp += 4)\r
91 if(*(TUint *)sp == lr) break;\r
92\r
93 // there might be mirored caller address\r
94 for(i = sp + 4; i < sp + 0x300 && i < stack_end; i += 4)\r
95 if(*(TUint *)i == lr) { sp = i; break; }\r
96\r
97 // aah, it is always 0x9c bytes away from the caller address in my firmware,\r
98 // don't know how to detect it in any other way\r
99 sp += 0x9c;\r
100 guessed_address = *(TUint *)sp;\r
101\r
102 // output the info\r
103 TUint exec_show = exc;\r
104 if(exec_show > 27) exec_show = 27;\r
105 TPtrC ptrExc((TUint16 *) exception_names[exec_show]);\r
106\r
107 RDebug::Print(_L("!!!Exception %i (%S) @ 0x%08x (guessed; relative=0x%08x)"), exc, &ptrExc, guessed_address, guessed_address - code_start);\r
108#ifdef __DEBUG_PRINT_FILE\r
109 DEBUGPRINT( _L("!!!Exception %i (%S) @ 0x%08x (guessed; relative=0x%08x)"), exc, &ptrExc, guessed_address, guessed_address - code_start);\r
110#endif\r
111\r
112 TBuf<148> buff1;\r
113 TBuf<10> buff2;\r
114 buff1.Copy(_L(" guessed stack: "));\r
115\r
116 for(sp += 4, i = 0; i < 5 && sp < stack_end; sp += 4) {\r
117 if((*(TUint *)sp >> 28) == 5) {\r
118 if(i++) buff1.Append(_L(", "));\r
119 buff2.Format(_L("0x%08x"), *(TUint *)sp);\r
120 buff1.Append(buff2);\r
121 }\r
122 else if(code_start < *(TUint *)sp && *(TUint *)sp < code_end) {\r
123 if(i++) buff1.Append(_L(", "));\r
124 buff2.Format(_L("0x%08x"), *(TUint *)sp);\r
125 buff1.Append(buff2);\r
126 buff1.Append(_L(" ("));\r
127 buff2.Format(_L("0x%08x"), *(TUint *)sp - code_start);\r
128 buff1.Append(buff2);\r
129 buff1.Append(_L(")"));\r
130 }\r
131 }\r
132 RDebug::Print(_L("%S"), &buff1);\r
133#ifdef __DEBUG_PRINT_FILE\r
134 DEBUGPRINT(_L("%S"), &buff1);\r
135#endif\r
136\r
137 // tmp\r
138#if defined(__DEBUG_PRINT)\r
139 char *ps, *cstr = debugString();\r
140 for(ps = cstr; *ps; ps++) {\r
141 if(*ps == '\n') {\r
142 *ps = 0;\r
143 dprintf(cstr);\r
144 cstr = ps+1;\r
145 }\r
146 }\r
147#endif\r
148\r
149// RDebug::Print(_L("Stack dump:"));\r
150// asm volatile ("str sp, %0" : "=m" (sp) );\r
151// for(TUint i = sp+0x400; i >= sp-16; i-=4)\r
152// RDebug::Print(_L("%08x: %08x"), i, *(int *)i);\r
153\r
154 // more descriptive replacement of "KERN-EXEC 3" panic\r
155 buff1.Format(_L("K-EX3: %S"), &ptrExc);\r
156 User::Panic(buff1, exc);\r
157}\r
158\r
159#endif // ifdef __WINS__\r
160\r
161\r
162#if defined(__DEBUG_PRINT) || defined(__WINS__)\r
163\r
164#ifndef __DLL__\r
165 // c string dumper for RDebug::Print()\r
166 static TBuf<1024> sTextBuffer;\r
167 TDesC* DO_CONV(const char* s)\r
168 {\r
169 TPtrC8 text8((TUint8*) (s));\r
170 sTextBuffer.Copy(text8);\r
171 return &sTextBuffer;\r
172 }\r
173#endif\r
174\r
175#ifdef __DEBUG_PRINT_C\r
176 #include <stdarg.h> // va_*\r
177 #include <stdio.h> // vsprintf\r
178\r
179 // debug print from c code\r
180 extern "C" void dprintf(char *format, ...)\r
181 {\r
182 va_list args;\r
183 char buffer[512];\r
184\r
185 va_start(args,format);\r
186 vsprintf(buffer,format,args);\r
187 va_end(args);\r
188\r
189 DEBUGPRINT(_L("%S"), DO_CONV(buffer));\r
190 }\r
191#endif\r
192\r
193#ifdef __DEBUG_PRINT_FILE\r
194 #include <f32file.h>\r
195\r
196 //static RFile logFile;\r
197// static TBool logInited = 0;\r
198 RMutex logMutex;\r
199\r
200 static void debugPrintFileInit()\r
201 {\r
202 // try to open\r
203 logMutex.CreateLocal();\r
204 RFs fserv;\r
205 fserv.Connect();\r
206 RFile logFile;\r
207 logFile.Replace(fserv, _L("C:\\logs\\pico.log"), EFileWrite|EFileShareAny);\r
208 logFile.Close();\r
209 fserv.Close();\r
210 }\r
211\r
212 // debug print to file\r
213 void debugPrintFile(TRefByValue<const TDesC> aFmt, ...)\r
214 {\r
215 if (logMutex.Handle() <= 0) debugPrintFileInit();\r
216\r
217 logMutex.Wait();\r
218 RFs fserv;\r
219 fserv.Connect();\r
220\r
221 TTime now; now.UniversalTime();\r
222 TBuf<512> tmpBuff;\r
223 TBuf8<512> tmpBuff8;\r
224 TInt size, res;\r
225\r
226 RThread thisThread;\r
227 RFile logFile;\r
228 res = logFile.Open(fserv, _L("C:\\logs\\pico.log"), EFileWrite|EFileShareAny);\r
229 if(res) goto fail1;\r
230\r
231 logFile.Size(size); logFile.Seek(ESeekStart, size);\r
232\r
233 now.FormatL(tmpBuff, _L("%H:%T:%S.%C: "));\r
234 tmpBuff8.Copy(tmpBuff);\r
235 logFile.Write(tmpBuff8);\r
236\r
237 tmpBuff8.Format(TPtr8((TUint8 *)"%03i: ", 6, 6), (TInt32) thisThread.Id());\r
238 logFile.Write(tmpBuff8);\r
239\r
240 VA_LIST args;\r
241 VA_START(args, aFmt);\r
242 tmpBuff.FormatList(aFmt, args);\r
243 VA_END(args);\r
244 tmpBuff8.Copy(tmpBuff);\r
245 logFile.Write(tmpBuff8);\r
246\r
247 logFile.Write(TPtrC8((TUint8 const *) "\n"));\r
248 logFile.Flush();\r
249 logFile.Close();\r
250 fail1:\r
251 thisThread.Close();\r
252 fserv.Close();\r
253\r
254 logMutex.Signal();\r
255 }\r
256#endif\r
257\r
258#endif\r
259\r