Go to main content

man pages section 3: Extended Library Functions, Volume 2

Exit Print View

Updated: Wednesday, July 27, 2022
 
 

dtrace_consume (3DTRACE)

Name

dtrace_consume, dtrace_status - DTrace data consumption interface

Synopsis

     cc [ flag... ] file... -ldtrace [ library... ]
     #include <dtrace.h>

     typedef int dtrace_consume_probe_f(const dtrace_probedata_t *, void *);

     typedef int dtrace_consume_rec_f(const dtrace_probedata_t *,
	const dtrace_recdesc_t *, void *);

     int dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
	dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg)

     int dtrace_status(dtrace_hdl_t *dtp)

Description

The dtrace_consume() function is called to consume data from the principal buffers. This function takes the following arguments:

dtp

DTrace handle returned by the dtrace_open(3DTRACE) function.

fp

File pointer where output is written.

pf

Pointer to a function that processes an enabling control block (ECB). An ECB is a clause from a D program associated with the enabled probe.

rf

Pointer to a function that processes individual records from the ECB.

arg

User-defined argument to be passed to the pf and rf pointers. See the Usage section for more information on these two callback functions.

The dtrace_status() function is called to determine the status of the running DTrace instance. This function takes the following argument:

dtp

DTrace handle returned by the dtrace_open(3DTRACE) function.

Return Values

The dtrace_consume() function returns 0.

On successful completion, the dtrace_status() function returns one of the following values:

DTRACE_STATUS_NONE

No status; not yet time

DTRACE_STATUS_OKAY

Status okay

DTRACE_STATUS_EXITED

exit() function was called; tracing stopped

DTRACE_STATUS_FILLED

Fill buffer filled; tracing stopped

DTRACE_STATUS_STOPPED

Tracing already stopped

Otherwise the functions return -1 and set the DTrace error number to indicate the reason for the failure. See the dtrace_errno(3DTRACE) man page for more information.

Errors

The dtrace_consume() function will fail if:

EINVAL

The dtp argument is NULL.

EFAULT

The system is unable to copy data out of the kernel.

EBUSY

If the buffer policy is ring, the dtrace_consume() function was called before the D program exited.

EDT_NOTACTIVE

The DTrace handle is not active because the dtrace_go(3DTRACE) function has not been called yet.

EDT_NOMEM

The system is unable to allocate memory to hold the data being copied out of the kernel.

EDT_DIRABORT

The pf or rf pointer returned DTRACE_CONSUME_ABORT. See the Usage section for more information.

EDT_BADRVAL

The pf or rf pointer returned a value other than DTRACE_CONSUME_THIS, DTRACE_CONSUME_NEXT, or DTRACE_CONSUME_ABORT.

EDT_NOBUFFERED

The fp argument is NULL, and the libdtrace(3LIB) probe and record processing routines are being used, which means that pf and rf are returning DTRACE_CONSUME_THIS.

The dtrace_status() function will fail if:

EINVAL

dtp is NULL.

EFAULT

The system encountered an error in copying the status out of the kernel.

Usage

The callback function pf processes the data from an enabling control block (ECB). An ECB is a clause from a D program associated with the enabled probe. The information pertaining to this ECB is contained in the dtrace_probedata_t data structure. The dtpda_data member of this structure points to the raw data for the probe firing, while the dtpda_edesc member describes the probe firing.

The dtrace_probedata_t data type is as follows:
    typedef struct dtrace_probedata {
        dtrace_hdl_t *dtpda_handle;             /* handle to DTrace library */
        dtrace_eprobedesc_t *dtpda_edesc;       /* enabled probe description */
        dtrace_probedesc_t *dtpda_pdesc;        /* probe description */
        processorid_t dtpda_cpu;                /* CPU for data */
        caddr_t dtpda_data;                     /* pointer to raw data */
        dtrace_flowkind_t dtpda_flow;           /* flow kind */
        const char *dtpda_prefix;               /* recommended flow prefix */
        int dtpda_indent;                       /* recommended flow indent */
    } dtrace_probedata_t;
The dtrace_eprobedesc_t data type is as follows:
    typedef struct dtrace_eprobedesc {
        dtrace_epid_t dtepd_epid;               /* enabled probe ID */
        dtrace_id_t dtepd_probeid;              /* probe ID */
        uint64_t dtepd_uarg;                    /* library argument */
        uint32_t dtepd_size;                    /* total size */
        int dtepd_nrecs;                        /* number of records */
        dtrace_recdesc_t dtepd_rec[1];          /* records themselves */
    } dtrace_eprobedesc_t;

The dtepd_rec array contains descriptions of the records in this ECB. The dtrace_recdesc_t structure describes each individual record in the dtepd_rec array.

The dtrace_recdesc_t data type is as follows:
    typedef struct dtrace_recdesc {
        dtrace_actkind_t dtrd_action;           /* kind of action */
        uint32_t dtrd_size;                     /* size of record */
        uint32_t dtrd_offset;                   /* offset in ECB's data */
        uint16_t dtrd_alignment;                /* required alignment */
        uint16_t dtrd_format;                   /* format, if any */
        uint64_t dtrd_arg;                      /* action argument */
        uint64_t dtrd_uarg;                     /* user argument */
    } dtrace_recdesc_t;

Note -  dtrd_offset is with respect to the dtpda_data member of the dtrace_probedata_t structure described at the beginning of this Usage section.

The callback function rf processes the data from an individual record. The arguments to rf include both the dtrace_probedata_t and the dtrace_recdesc_t data types for this individual record.

The callback functions pf and rf return one of the following values:

DTRACE_CONSUME_ERROR

Error while processing

DTRACE_CONSUME_THIS

Consume this probe or record

DTRACE_CONSUME_NEXT

Advance to next probe or record

DTRACE_CONSUME_ABORT

Abort consumption

If the callback function returns the value, DTRACE_CONSUME_THIS, the libdtrace(3LIB) function processes the ECB or the record internally. If the callback function returns the value, DTRACE_CONSUME_NEXT, the libdtrace(3LIB) function does not process the ECB or record.

Examples

Example 1 Using the dtrace_consume() and dtrace_status() Functions with the dtrace_consume_rec_f() Callback Function

The following example demonstrates how you can use the dtrace_consume() and dtrace_status() functions, and consume individual records with the dtrace_consume_rec_f() callback function. See the dtrace_printf_create(3DTRACE) man page for an example of consuming an ECB with the dtrace_consume_probe_f() argument.

	#include <dtrace.h>
	#include <stdio.h>
	#include <stdlib.h>

	static dtrace_hdl_t *g_dtp;
	static uint32_t g_status;
	static char *g_prog = ""
	"BEGIN"
	"{"
	"       trace(\"Hello, world!\\n\");"
	"       exit(0);"
	"}";

	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)
	{
	        dtrace_actkind_t act;
	        uintptr_t addr;

	        if (rec == NULL)
	                return (DTRACE_CONSUME_NEXT);

	        act = rec->dtrd_action;
	        addr = (uintptr_t)data->dtpda_data;

	        if (act == DTRACEACT_DIFEXPR) {
	                /*
			 * g_prog only traces a string, so this is not
			 * generic.
			 */
	                printf("%s\n", (char *)addr);
	                return (DTRACE_CONSUME_NEXT);
	        }

	        if (act == DTRACEACT_EXIT) {
	                g_status = *((uint32_t *)addr);
	                return (DTRACE_CONSUME_NEXT);
	        }

	        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;
	        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, "bufsize", "512k") == -1)
	                fatal("failed to set bufsize");

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

		while (1) {
			int done = 0;

			dtrace_sleep(g_dtp);

			switch (dtrace_status(g_dtp)) {
			case DTRACE_STATUS_EXITED:
			case DTRACE_STATUS_FILLED:
			case DTRACE_STATUS_STOPPED:
				done = 1;
				break;

			case DTRACE_STATUS_NONE:
			case DTRACE_STATUS_OKAY:
				break;

			default:
				fatal("processing aborted");
			}

			if (dtrace_consume(g_dtp, stdout, chew, chewrec,
			    NULL) == -1)
				fatal("dtrace_consume()");

			if (done)
			    break;
		}

		if (dtrace_stop(g_dtp) == -1)
			fatal("dtrace_stop()");

		dtrace_close(g_dtp);

		printf("D program exited with status %d\n", g_status);

		return (0);
	}

Attributes

See attributes(7) for descriptions of the following attributes:

ATTRIBUTE TYPE
ATTRIBUTE VALUE
Architecture
all
Availability
system/dtrace
Interface Stability
Committed
MT-Level
Safe

See Also

libdtrace(3LIB), dtrace_errno(3DTRACE), dtrace_sleep(3DTRACE)