Error Handler

The libdtrace library enables you to install an error handler similar to the drop handler. Errors can be events such as a process attempting to access an invalid pointer or attempting to divide by zero. The default behavior for errors is to terminate the process, which is the same behavior as for drops. You can see this behavior if you run the Embedding DTrace in a Consumer with the following D program:

BEGIN
{
     trace(strlen(0));
}
syscall:::entry
{
     @c[probefunc] = count();
}

When you run this program, the following output is displayed:

# ./consumer-no-errhandler
processing aborted: Abort due to error
#

The dtrace_handle_err() interface provided by the libdtrace library specifies an error handler. The arguments to the dtrace_handle_err() function are:

  • DTrace handle

  • Pointer to a function to handle the error

  • Pointer to a private argument to be passed to the error handler

The error handler function takes two arguments: a pointer to the dtrace_errdata data structure and a pointer to the private argument originally passed to the dtrace_handle_err() function. It returns one of the two values, DTRACE_HANDLE_ABORT or DTRACE_HANDLE_OK.

The dtrace_errdata data structure contains information about the error that occurred.

typedef struct dtrace_errdata {
       dtrace_hdl_t *dteda_handle;                 /* handle to DTrace library */
       dtrace_eprobedesc_t *dteda_edesc;           /* enabled probe inducing err */
       dtrace_probedesc_t *dteda_pdesc;            /* probe inducing error */
       processorid_t dteda_cpu;                    /* CPU of error */
       int dteda_action;                           /* action inducing error */
       int dteda_offset;                           /* offset in DIFO of error */
       int dteda_fault;                            /* specific fault */
       uint64_t dteda_addr;                        /* address of fault, if any */
       const char *dteda_msg;                      /* preconstructed message */
} dtrace_errdata_t;

Aside from the self-evident members of this structure, the dteda_pdesc probe description contains the names of the provider, module, function, and name, and predefined error message. The simplest error handler returns DTRACE_HANDLE_OK to ignore any errors. A more sophisticated error handler also prints the predefined error message.

static int
errhandler(const dtrace_errdata_t *data, void *arg)
{ 
        fprintf(stderr, "%s", data->dteda_msg);
        return(DTRACE_HANDLE_OK);
}

The error handler used in Embedding DTrace in a Consumer displays output similar to the following example:

# ./consumer-errhandler
error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): invalid address (0x0) in
action #1 at DIF offset 28
  fstat64                              1
  mmap                                 1 
  schedctl                             1
  sendto                               1
  pset                                 3
  sysconfig                            3
  brk                                  6  
  gtime                                6
  write                               11
  lwp_park                            13
  setitimer                           16
  read                                18
  p_online                           256
  pollsys                            315
  lwp_sigmask                        570
  ioctl                             1410
#

A more sophisticated error handler might choose to terminate processing under certain conditions. A consumer might choose to terminate in the following conditions:

  • Number of errors exceeds a threshold within a certain period.

  • Total number of errors exceeds a certain threshold, only upon seeing the errors from a particular CPU, or only upon seeing certain types of errors.

For example, a process might terminate on a division by zero but not on accessing an invalid address.