Exception message format

From OC Systems Wiki!
Jump to: navigation, search

You can create a probe to register a callback with Aprobe to be called for each exception thrown/raised in an application. Use this interface found in aprobe.h:

/* The kinds of exceptions supported by Aprobe. */
typedef enum
} 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 at which the 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);

Note that you can use exceptions.ual to log exception occurrences. This UAL will record the exception kind, name, message, and traceback.


Putting it all together in some examples, this probe:

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",
probe thread
      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)

And this output for a C++ exception derived from std::exception using xlC:

Exception kind: 5
Exception name: 5ooops:0,Q2_3std9exception:0
Exception  msg: Ooops!
Exception  loc: extern:"::work(void)" at line 17 (throwexc.cpp)

And this output for an Ada Exception_Ocurrence using Gnat:

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)