Go to main content

Oracle® Solaris 11.4 DTrace (Dynamic Tracing) Guide

Exit Print View

Updated: September 2020
 
 

Processing Traced Data in DTrace

This section describes the processing of traced data. The dtrace_recdesc_t structure describes a record that contains data stored by DTrace.

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;

For simple values, the size of the type is stored in the dtrd_size member. If you have a pointer to the ECB data and a pointer to the record description, you can extract the value for the dtrace_recdesc_t record, as shown in the following example:

uint64_t val;
        /* _base_ is a pointer to the ECB data */
        /* _rdp_ is a pointer to the record description */

	void *record = _base_+_rdp_->dtrd_offset;  
	switch (rdp->dtrd_size) {
	case sizeof (uint64_t):
		val = *((uint64_t *)(record));
		break;
	case sizeof (uint32_t):
		val = *((uint32_t *)(record));
		break;
	case sizeof (uint16_t):
		val = *((uint16_t *)(record));
		break;
	case sizeof (uint8_t):
		val = *((uint8_t *)(record));
		break;
	default:
		break;
	}

The values for some actions might require further processing. If dtrd_action is either DTRACEACT_SYM or DTRACEACT_MOD, the 64-bit value represents an address in kernel space that needs to be resolved to a symbol or module by using the dtrace_lookup_by_addr() function.

Strings in DTrace

In DTrace, strings are stored as fixed-length character arrays. You can use the dtrace_getopt() function to determine the string size. The strsize option specifies the value of the size.


Note -  In DTrace, a string is not necessarily a null terminated value. If one of the characters in the array is a NUL, the array can be treated as a C-style string. If the character array is not null terminated, the consumer must create a null terminated string.

DTrace Compound Data

A single record stores the data of various actions. This section discusses the formats of these data types.

stack() Function

The stack() action stores a sequence of kernel addresses that represents the kernel stack. These addresses are stored as an array of 64-bit or 32-bit values.

dtrd_action == DTRACEACT_STACK

The length of this array is stored in the dtrd_arg member of the dtrace_recdesc_t structure. The length of the array represents the depth of the stack. To calculate the size of the individual stored address, divide the value of dtrd_size by the value of dtrd_arg.

The first element of this array is the program counter (PC) in the function that executes when the DTrace probe is fired. Similarly, the next element is the PC of the calling function.


Note -  Some of the PCs might be NULL. When a NULL PC is encountered, the bottom of the stack has been reached.

Figure 5  Data Format for the stack() Action

image:Graphic shows data format for the stack action

ustack() and jstack() Functions

The ustack() and jstack() actions store an array of 64-bit values regardless of whether the process is a 32-bit or 64-bit process. The first element of this array is the PID of the process. The remaining elements of the array are the PCs in the process that represent the user stack.

dtrd_action == DTRACEACT_USTACK
dtrd_action == DTRACEACT_JSTACK

The length of this array is stored in the lower 32-bits of the dtrd_arg member of the dtrace_recdesc_t structure.

Figure 6  Data Format for the ustack() and jstack() Actions

image:Graphic shows data format for the ustack and jstack actions

tracemem() Function

The tracemem() action stores an array of bytes intended to be treated as raw values. The number of bytes in this buffer is given by the dtrd_size member of the dtrace_recdesc_t structure.

dtrd_action == DTRACEACT_TRACEMEM

The tracemem() action takes an optional third argument, the number of bytes to display. If a third argument is specified, the dtrd_arg member of the dtrace_recdesc_t structure contains the DTRACE_TRACEMEM_DYNAMIC value. In this case, the subsequent data record is also a DTRACEACT_TRACEMEM record. The dtrd_arg value for this subsequent record is either DTRACE_TRACEMEM_SIZE or DTRACE_TRACEMEM_SSIZE, and the value contained in the data for this subsequent record is the number of bytes displayed.

if (rec->dtrd_arg == DTRACE_TRACEMEM_STATIC)
	process rec->dtrd_size bytes of data
else if (rec->dtrd_arg == DTRACE_TRACEMEM_DYNAMIC)
	nrec = next record
	if nrec->dtrd_arg == DTRACE_TRACEMEM_SIZE
		extract display size from nrec's data as unsigned value
	else if nrec->dtrd_arg == DTRACE_TRACEMEM_SSIZE
		extract display size from nrec's data as signed value
	process data based on values of rec->dtrd_size and display size

umod(), usym(), and uaddr() Functions

The umod(), usym(), and uaddr() actions store two 64-bit values. The first value is the PID of the process and the second value is a user address within the process.

Typically, the second value is the address that was passed to the action. However, if the action was used as a key in an aggregation then the address may have been modified.

dtrd_action == DTRACEACT_UMOD
dtrd_action == DTRACEACT_USYM
dtrd_action == DTRACEACT_UADDR

Figure 7  Data Format for the umod() Action

image:Graphic shows data format for the umod action