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