Exception message format
From OC Systems Wiki!
Exception Message Formatting
You can create a probe to register callback with Probe to be called for each exception throw/raise in an application. Use this interface found in aprobe.h:
/* The kinds of exceptions supported by Aprobe. */
typedef enum
{
ap_NoException,
ap_CppException,
ap_WinNTVCppException,
ap_GnatAdaException,
ap_WinNTSEHException,
ap_AixCppException,
ap_Pa4AdaException
} ap_ExceptionKindT;
/* This is the information concerning an exception. */
/* The ExceptionData and Flags fields are internal to Aprobe. */
typedef struct
{
ap_ExceptionKindT Kind;
ap_NameT ExceptionName;
void *ExceptionData;
int Flags;
} ap_ExceptionT;
/* When an exception is raised, a handler can be called to log and / or */
/* print the exception. The following is the definition of the handler */
/* (note that Location is the location for the routine which raised the */
/* exception): */
typedef void ap_ExceptionHandlerProcT (ap_ExceptionT *Exception,
ap_LocationT Location);
/* Register the routine to be called when an exception occurs */
extern void ap_RegisterExceptionHandler (ap_ThreadContextPtrT ThreadContext,
ap_ExceptionHandlerProcT Handler);
The exception handler is passed the current exception and the location who exception was thrown/raised. The ExceptionName is the Ada exception name or the name of the C++ object thrown. The ExceptionData is generally the exception object or occurrence, but that is not guaranteed.
You can get the message associated with the Ada or C++ exception using:
/* Get the exception message (if any) for the given exception. The returned */
/* string must be freed by the caller. ap_NoName will be returned if there */
/* is no message for the exception. Note that it is expected that you call */
/* this within the exception handler procedure or immediately after calling */
/* ap_CurrentException. Any other usage has undefined behavior. */
extern ap_NameT ap_GetExceptionMessage (ap_ExceptionT *Exception);
Example
Putting it all together in some examples:
void HandlerRoutine (ap_ExceptionT *Exception,
ap_LocationT Location)
{
int FmtLen = ap_FormatAddressSize(Location.CurrentAddress);
char *Buffer = (char *)alloca(FmtLen);
ap_FormatAddress(Buffer, Location.CurrentAddress);
printf("Exception kind: %d\nException name: %s\nException msg: %s\nException loc: %s\n",
Exception->Kind,
Exception->ExceptionName,
ap_GetExceptionMessage(Exception),
Buffer);
}
probe thread
{
on_entry
{
ap_RegisterExceptionHandler(ap_ThreadContextPtr, &HandlerRoutine);
}
}
Produces this output for a C++ exception derived from std::exception using G++:
Exception kind: 1 Exception name: typeinfo for ooops Exception msg: Ooops! Exception loc: extern:"::work(void)" at line 17 (throwexc.cpp) <nowiki> And this output for a C++ exception derived from std::exception using xlC: <nowiki> Exception kind: 5 Exception name: 5ooops:0,Q2_3std9exception:0 Exception msg: Ooops! Exception loc: extern:"::work(void)" at line 17 (throwexc.cpp) <nowiki> And this output for an Ada Exception_Ocurrence using Gnat: <nowiki> Exception kind: 3 Exception name: CONSTRAINT_ERROR Exception msg: t.adb:8 range check failed Exception loc: "t.adb":"t.q[4031]" at line 8 (t.adb)
And this for an Ada Exception using PowerAda:
Exception kind: 6 Exception name: CONSTRAINT_ERROR Exception msg: Value vs. Range Constraint (LRM 5.2:11) Exception loc: extern:"t.t.q[1b]" at line 8 (sec.t)