DTrace Topics USDT

From Siwiki

Jump to: navigation, search

Contents

[edit] DTrace Topics: USDT

This article is about DTrace USDT, and is part of the DTrace Topics collection. A general understanding of DTrace is assumed knowledge, which can be studied from the DTrace Topics: Intro section.

DTrace is a dynamic troubleshooting and analysis tool first introduced in the Solaris 10 and OpenSolaris operating systems.

Completion Image:trafficlight_red02.png
Difficulty Image:coffeemug01.png Image:coffeemug01.png Image:coffeemug01.png Image:coffeemug01.png
Audience Developers, DTrace users with source access

[edit] USDT

USDT is User-Level Statically Defined Tracing, and is a framework for placing custom probe points in application code.

For performance analysis and troubleshooting, programmers commonly instrument their applications by placing debug statements throughout the code - which are enabled either at compile time (by using compile flags), or at run time (config files). USDT serves a similar purpose, providing debug macros that can be customized and placed throughout the code.

[edit] USDT Features

  • USDT probes are compiled in and are always available in both development and production code
  • DTrace dynamically activates the USDT probes when required
  • There is negligible CPU overhead from the addition of USDT probes when they are not in use
  • This form of debugging benifits from standard DTrace features, such as,
Rich reporting functionality (aggregations)
Capability to walk memory structures as required

[edit] When to use USDT

USDT can help in many scenarios, but first - check the language of your program in DTrace Topics to see what can already be traced. For example, the pid provider allows all function entries and returns of C programs to be traced, including their arguments. Ever added a debug statement to print "function X began"? Well, pid already does that for you, for every function, dynamically.

Two good uses of USDT are,

  • For tracing activity within a function
  • For creating a high level provider with meaningful and stable probes

[edit] Function Activity

Your function either does either A, B or C, and you want to know which. See Hints for other techniques that may be available besides USDT.

[edit] High Level Provider

Adding a meaningful and stable provider will make life easier for all who need to analyse your application. For example, adding transaction-begin and transaction-end probes to your application server code to allow everyone to perform custom transaction based analysis without digging through the source code themselves.

Existing high level providers that use USDT include:

  • JavaScript
The JavaScript provider uses USDT to instrument the Mozilla JavaScript engine (libmozjs, which is written in C++ and is called "Spider Monkey"). It provides probes for function calls, object creation, garbage collection, and code execution. Users can use this provider to trace the operation of JavaScript code.
  • iSCSI
The iSCSI provider uses USDT to instrument the iSCSI target deamon. This provides high level and stable probes to allow iSCSI events to be traced on the server.
  • Apache
The Apache DTrace module is loaded with Apache and uses USDT to provide stable probes for Apache analysis.

[edit] Getting Started

To get started with USDT, work through the following steps to instrument a "Hello World!" style C program using basic USDT macros. This will demonstrate USDT concepts and compilation steps.

[edit] helloworld.c

[edit] Compiling

[edit] Adding a Probe

[edit] Defining a Provider

[edit] Compiling with USDT

[edit] Testing USDT

[edit] Provider Definition File

[edit] USDT Macros

To instrument C or C++ code, USDT macros are placed where appropriate. Three types can be used:

  • Basic
These are predefined macros that are ready for immediate use.
  • Auto Generated
After creating a provider definition file, the dtrace -h comand generates a header files of macros which contain the provider and probe name.
  • Custom
You can create your own header files with whatever macros are appropriate.

[edit] Basic

Basic USDT macros are defined in uts/common/sys/sdt.h and include,

#define DTRACE_PROBE(provider, name) {                                  \
        extern void __dtrace_##provider##___##name(void);               \
        __dtrace_##provider##___##name();                               \
}

#define DTRACE_PROBE1(provider, name, arg1) {                           \
        extern void __dtrace_##provider##___##name(unsigned long);      \
        __dtrace_##provider##___##name((unsigned long)arg1);            \
} 

#define DTRACE_PROBE2(provider, name, arg1, arg2) {                     \
        extern void __dtrace_##provider##___##name(unsigned long,       \
            unsigned long);                                             \
        __dtrace_##provider##___##name((unsigned long)arg1,             \
            (unsigned long)arg2);                                       \
}
[...]

Don't worry about the contents, we are just interested in the names and arguments for now, such as "DTRACE_PROBE2(provider, name, arg1, arg2)". You can probably guess the style of: DTRACE_PROBEn takes n of the arg probes.

[edit] Arguments

[edit] Examples

Examples of how these may be used,

Example Code Description
DTRACE_PROBE(sshd, login) This could be placed in the sshd code to instrument when a user logs in
DTRACE_PROBE1(sshd, login, username) This could instrument sshd logins, providing the username as the first argument
DTRACE_PROBE2(sshd, login, username, ipaddr) This could instrument sshd logins, providing the username and IP address as arguments

[edit] Auto-Generated

[edit] Custom

[edit] Resources

Solaris Internals
Personal tools
The Books
The Ads