DTrace Consumer Functions

When a consumer is invoked, it performs the following activities using a few DTrace consumer functions:

  • Compile a D program

  • Pass the resulting object to the DTrace framework

  • Set any options to allow the program to run

  • Run the program

  • Generate output

Example 20-1 Embedding DTrace in a Consumer

The example shows a consumer that runs an embedded D program to perform kernel stack profiling.

#include <dtrace.h>
#include <stdarg.h>
#include <stdlib.h>
#include <strings.h>
static char *g_prog = ""
"profile-997"
"/arg0 && curthread->t_pri != -1/"
"{"
"       @c[stack()] = count();"
"}";
static dtrace_hdl_t *g_dtp;

static void
fatal(const char *fmt, ...)
{  
        va_list ap;  
        va_start(ap, fmt);

        (void) vfprintf(stderr, fmt, ap);

        if (fmt[strlen(fmt) - 1] != '\n')
                (void) fprintf(stderr, ": %s\n",
                    dtrace_errmsg(g_dtp, dtrace_errno(g_dtp)));
        exit(EXIT_FAILURE);
}

static int
chewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec,
    void *arg)
{ 
        return (DTRACE_CONSUME_THIS);
}

static int
chew(const dtrace_probedata_t *data, void *arg)
{
        return (DTRACE_CONSUME_THIS);
}

int
main()
{
        dtrace_prog_t *prog;
        dtrace_proginfo_t info; 
        dtrace_optval_t statustime;
        int err;

        if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL)
                fatal("cannot open dtrace library: %s\n",
                    dtrace_errmsg(NULL, err));

        if ((prog = dtrace_program_strcompile(g_dtp, g_prog,
             DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL)
                 fatal("invalid program");

        if (dtrace_program_exec(g_dtp, prog, &info) == -1)
                fatal("failed to enable probes");

        if (dtrace_setopt(g_dtp, "aggsize", "512k") == -1)
                fatal("failed to set aggsize");

        if (dtrace_go(g_dtp) != 0)
                fatal("dtrace_go()");

        for (int i = 0; i < 10; i++) {
       
                dtrace_sleep(g_dtp);
                switch (dtrace_work(g_dtp, stdout, chew, chewrec, NULL)) {
                case DTRACE_WORKSTATUS_DONE:
                        break;
                case DTRACE_WORKSTATUS_OKAY:
                        break;
                default:
                        fatal("processing aborted");
                }
         }
         
         if (dtrace_stop(g_dtp) == -1)
                 fatal("dtrace_stop()");

         if (dtrace_aggregate_print(g_dtp, stdout, NULL) == -1)
                 fatal("failed to print aggregation");

         dtrace_close(g_dtp);
         return (0);
}