Attached is a patch to the same source as before. The original function is now preserved, MessageBoxW() calls have been added right before most printf statements.
The dialogs have the benefit - in my opinion - that the user sees them.
Feedback ?
Danny
On Fri, 2007-04-20 at 21:27 +0200, Danny Backx wrote:
> I've done some more experiments.
>
> 1. I didn't get an exception from division by 0.
> Inspection of the assembly code reveals that there's indeed no
> division instruction being generated (probably this means ARM doesn't
> do integer division?). The function called is divdf3, which comes from
> dp-bit.c in gcc. That code explicitly checks for a 0 divider, it
> doesn't appear to cause strangeness like an exception.
>
> 2. Pedro asked why I used a dialog, wouldn't a printf statement be
> better, he mentioned console applications.
> I've tried to build a "console" version of my follow-a-null-pointer
> application using the old voxware compiler. I used that toolchain
> because I don't think ours can handle a console application that
> can be launched from the rlogin session.
>
> The console application died as expected, showing messages that appear
> to come from the _eh_handler_ :
>
> # np.exe
> Exception: Code:c0000005 Flags:0 Addr:11060 SP:2009fb44 LR:11054 R0:0
> R1:29150 R2:2 R3:0 R4:2009fb64 R5:2009fc7c R12:1 FP:2009fb4c
> Exception: Code:c0000005 Flags:0 Addr:11060 SP:2009fb44 LR:16194
> R0:ffffffff R1:0 R2:24be49ba R3:0 R4:c0000005 R5:0 R12:1 FP:2009fb4c
> Exception: Code:80000002 Flags:0 Addr:16198 SP:2009fb44 LR:16194
> R0:ffffffff R1:0 R2:24be49ba R3:86 R4:c0000005 R5:ffffffff R12:1
> FP:2009fb4c
> #
>
> Interestingly, the divide-by-zero application (which pops up a dialog
> after the division by 0) shows a dialog on my PDA's screen, even
> though it was launched as a console application (from the rlogin
> session).
>
> Note that the exceptions above mean :
> #define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)
> #define STATUS_DATATYPE_MISALIGNMENT ((DWORD)0x80000002L)
>
> 3. An application run without my modified _eh_handler_ prints messages
> like these in /temp/wcetrace*.log.
>
> 4. I have an application that mysteriously dies when you ask it too
> much. I was hoping to get some info from this handler, but I have yet
> to find any error message.
>
> When I run it under gdb, all that happens is :
> Program received signal SIGSEGV, Segmentation fault.
> 0x01758f58 in ?? ()
> (gdb) where
> #0 0x01758f58 in ?? ()
> (gdb)
>
> Danny
--
Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info
Index: startup.c
===================================================================
--- startup.c (revision 915)
+++ startup.c (working copy)
@@ -36,24 +36,25 @@
DWORD exception;
int signal;
const char* str;
+ const wchar_t *wstr;
};
/* from pocket console */
struct exception_map_t __exception_map[] =
{
- { STATUS_ACCESS_VIOLATION, SIGSEGV, "Access Violation" },
- { STATUS_ILLEGAL_INSTRUCTION, SIGILL, "Illegal Instruction"},
- { STATUS_PRIVILEGED_INSTRUCTION, SIGILL, "Privileged Instruction" },
+ { STATUS_ACCESS_VIOLATION, SIGSEGV, "Access Violation", L"Access Violation"},
+ { STATUS_ILLEGAL_INSTRUCTION, SIGILL, "Illegal Instruction", L"Illegal Instruction"},
+ { STATUS_PRIVILEGED_INSTRUCTION, SIGILL, "Privileged Instruction", L"Privileged Instruction"},
/* { (unsigned long)STATUS_NONCONTINUABLE_EXCEPTION, NOSIG, SIG_DIE }, */
/* { (unsigned long)STATUS_INVALID_DISPOSITION, NOSIG, SIG_DIE }, */
- { STATUS_INTEGER_DIVIDE_BY_ZERO, SIGFPE, "Integer divide by zero" },
- { STATUS_FLOAT_DENORMAL_OPERAND, SIGFPE, "Float denormal operand" },
- { STATUS_FLOAT_DIVIDE_BY_ZERO, SIGFPE, "Float divide by zero" },
- { STATUS_FLOAT_INEXACT_RESULT, SIGFPE, "Float inexact result" },
- { STATUS_FLOAT_INVALID_OPERATION, SIGFPE, "Float invalid operation" },
- { STATUS_FLOAT_OVERFLOW, SIGFPE, "Float overflow" },
- { STATUS_FLOAT_STACK_CHECK, SIGFPE, "Float stack check" },
- { STATUS_FLOAT_UNDERFLOW, SIGFPE, "Float underflow" },
+ { STATUS_INTEGER_DIVIDE_BY_ZERO, SIGFPE, "Integer divide by zero", L"Integer divide by zero"},
+ { STATUS_FLOAT_DENORMAL_OPERAND, SIGFPE, "Float denormal operand", L"Float denormal operand"},
+ { STATUS_FLOAT_DIVIDE_BY_ZERO, SIGFPE, "Float divide by zero", L"Float divide by zero"},
+ { STATUS_FLOAT_INEXACT_RESULT, SIGFPE, "Float inexact result", L"Float inexact result"},
+ { STATUS_FLOAT_INVALID_OPERATION, SIGFPE, "Float invalid operation", L"Float invalid operation"},
+ { STATUS_FLOAT_OVERFLOW, SIGFPE, "Float overflow", L"Float overflow"},
+ { STATUS_FLOAT_STACK_CHECK, SIGFPE, "Float stack check", L"Float stack check"},
+ { STATUS_FLOAT_UNDERFLOW, SIGFPE, "Float underflow", L"Float underflow"},
/* { (unsigned long)STATUS_INTEGER_DIVIDE_BY_ZERO, NOSIG }, */
/* { (unsigned long)STATUS_STACK_OVERFLOW, NOSIG } */
};
@@ -103,6 +104,9 @@
{
// ### What is this needed for?
static int NestedException=0;
+ wchar_t msg[256];
+ int unhandled = 0;
+
if(NestedException)
{
printf("nested exception\n");
@@ -116,7 +120,22 @@
DWORD Cmd;
DWORD DataAddr;
-#if 0
+ wsprintf(msg, L"Flags:%x Addr:%x\r\nSP:%x LR:%x R0:%x R1:%x R2:%x R3:%x\r\nR4:%x R5:%x R12:%x FP:%x\n",
+ ExceptionRecord->ExceptionFlags,
+ ExceptionRecord->ExceptionAddress,
+ ContextRecord->Sp,
+ ContextRecord->Lr,
+ ContextRecord->R0,
+ ContextRecord->R1,
+ ContextRecord->R2,
+ ContextRecord->R3,
+ ContextRecord->R4,
+ ContextRecord->R5,
+ ContextRecord->R12,
+ EstablisherFrame
+ );
+ MessageBoxW(0, msg, L"Datatype Misalignment Exception", 0);
+
printf("Trying to handle EXCEPTION_DATATYPE_MISALIGNMENT Flags:%x Addr:%x "
"SP:%x LR:%x R0:%x R1:%x R2:%x R3:%x R4:%x R5:%x R12:%x FP:%x\n",
ExceptionRecord->ExceptionFlags,
@@ -132,7 +151,6 @@
ContextRecord->R12,
EstablisherFrame
);
-#endif
Cmd=*(DWORD*)(ExceptionRecord->ExceptionAddress); // this may cause other exception
@@ -171,8 +189,31 @@
return ExceptionContinueExecution;
Cont:
printf("Unhandled ");
+ unhandled++;
}
Nest:
+#if 0
+ /*
+ * Disabled this; there's a call with textual explanation for the end user below.
+ */
+ wsprintf(msg, L"%sCode:%x Flags:%x Addr:%x\r\nSP:%x LR:%x R0:%x R1:%x R2:%x R3:%x\r\nR4:%x R5:%x R12:%x FP:%x\n",
+ (unhandled ? L"Unhandled\r\n" : L""),
+ ExceptionRecord->ExceptionCode,
+ ExceptionRecord->ExceptionFlags,
+ ExceptionRecord->ExceptionAddress,
+ ContextRecord->Sp,
+ ContextRecord->Lr,
+ ContextRecord->R0,
+ ContextRecord->R1,
+ ContextRecord->R2,
+ ContextRecord->R3,
+ ContextRecord->R4,
+ ContextRecord->R5,
+ ContextRecord->R12,
+ EstablisherFrame
+ );
+ MessageBoxW(0, msg, L"WinCE Exception a", 0);
+#endif
printf("Exception: Code:%x Flags:%x Addr:%x "
"SP:%x LR:%x R0:%x R1:%x R2:%x R3:%x R4:%x R5:%x R12:%x FP:%x\n",
ExceptionRecord->ExceptionCode,
@@ -217,9 +258,22 @@
struct exception_map_t* expt = get_exception_map_for(ExceptionRecord->ExceptionCode);
if (!expt)
{
+ wsprintf(msg, L"%x", ExceptionRecord->ExceptionCode);
+ MessageBoxW(0, msg, L"Unhandled kernel exception", 0);
printf("Unhandled kernel exception %x\n", ExceptionRecord->ExceptionCode);
exit(-1);
}
+
+ /*
+ * Show readable text explaining what went wrong, with a limited amount of detail.
+ */
+ wsprintf(msg, L"%s\r\nCode:%x Flags:%x Addr:%x SP:%x",
+ expt->wstr,
+ ExceptionRecord->ExceptionCode,
+ ExceptionRecord->ExceptionFlags,
+ ExceptionRecord->ExceptionAddress,
+ ContextRecord->Sp);
+ MessageBoxW(0, msg, L"WinCE Exception", 0);
printf("%s\n", expt->str);
ContextRecord->R0 = expt->signal;
signature.asc
Description: This is a digitally signed message part
------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/
_______________________________________________ Cegcc-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/cegcc-devel
