DTrace Topics C
From Siwiki
Contents |
[edit] DTrace Topics: C
This article is about DTracing C, 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. C is an procedural programming language that is extensively used throughout the OS and in many applications.
Completion
Difficulty
Audience Most DTrace users, especially C developers and sysadmins
[edit] C and DTrace
[edit] user-level
DTrace provides excellent observability of user-level compiled C code execution through the pid provider, which can trace:
| Can Trace | Examples |
| function entry events | tracing fopen() being called |
| function arguments | tracing the arguments to fopen() and printing the filename and mode |
| function return events | tracing the return of fopen() to see whether a FILE object was returned or NULL |
| function instructions | tracing the CPU instructions as fopen() executes |
Sometimes when debugging C software, printf or debug statements are placed at the beginning of functions to confirm what is entered and with which arguments (have you ever done that?); DTrace can dynamically collect this data from any function, without even stopping the application.
The key advantage of using DTrace for analysis is the power to trace events across the entire software stack,
| Layer | Tracing with DTrace | Example Events | Example Probe |
| user functions | with the pid provider. | main(), ... | pid$target:a.out:main:entry |
| library functions | with the pid provider. | Functions from libc, libnet, ... eg, fopen(), .... | pid$target:libc:fopen:entry |
| syscalls | with the syscall provider. | read(), write(), fork(), exec(), ... | syscall::write:entry |
| kernel functions | with io and sched, or the unstable fbt provider. | bdev_strategy(), biodone(), ... | fbt:genunix:bdev_strategy:entry |
If you are trying to find a problem in the code from traditional debuggers, your visibility ends with the syscall layer. DTrace provides the power to identify and measure problems no matter where they are in the software stack.
[edit] kernel
For kernel compiled C code, DTrace can trace function entries, returns and arguments, and other points of interest where probes have been placed. Function instruction flow must be deduced from other probe activity as it cannot be traced directly.
The providers that examine kernel operation are,
- The raw and unstable fbt provider (function boundary tracing), which provides visibility of almost all kernel function events.
- Higher level stable providers, such as io and proc, which provide probes for meaningful events.
[edit] Quick Reference
The following is a quick reference for DTracing the C programming language.
[edit] Providers
| Provider | Relavence |
| pid | Tracing user-level C functions including library functions, and CPU instructions |
| profile | Sampling stack traces |
| syscall | Tracing system calls by user-level code |
| fbt | Tracing kernel C functions (an unstable interface; check if stable versions exist for your events) |
| io | Tracing physical io events |
[edit] Probes
| Probe | Description |
| pid$target:[segment]:[function]:entry | A user-level function is entered |
| pid$target:[segment]:[function]:return | A user-level function completes |
| pid$target:[segment]:[function]:0x### | A user-level instruction fires |
| fbt:[module]:[function]:entry | A kernel function is entered |
| fbt:[module]:[function]:return | A kernel function completes |
[edit] Capabilities: user-land
| Capability | Exists | Format | Example |
| Function entries | yes | Probe: pidPID:[segment]:[function]:entry | dtrace -n 'pid$target:a.out:main:entry' -p PID |
| Function entry arguments | yes | Variables: arg0, arg1 .. argN, int64_t | dtrace -n 'pid$target:libc:close:entry { printf("%d", arg0); }' -p PID |
| Function returns | yes | Probe: pidPID:[segment]:[function]:return | dtrace -n 'pid$target:libc:fopen:return' -p PID |
| Function return value | yes | Variable: arg1, int64_t | dtrace -n 'pid$target:libc:fclose:return { trace(arg1); }' -p PID |
| Function instructions | yes | Probe: pidPID:[segment]:[function]:[offset] | dtrace -n 'pid$target:libc:strlen:' -c date |
| Stack traces | yes | Action: ustack() | dtrace -n 'pid$target:libc:fopen:entry { ustack() }' -p PID |
[edit] Capabilities: kernel
| Capability | Exists | Format | Example |
| Function entries | yes | Probe: fbt:[module]:[function]:entry | dtrace -n 'fbt:genunix:bdev_strategy:entry' |
| Function entry arguments | yes | Variables: args[0], args[1] .. args[N], casted | dtrace -n 'fbt::bdev_strategy:entry { trace(args[0]->b_bcount); }' |
| Function returns | yes | Probe: fbt:[module]:[function]:return | dtrace -n 'fbt:genunix:bdev_strategy:entry' |
| Function return value | yes | Variable: arg1, int64_t | dtrace -n 'fbt::bdev_strategy:return { trace(arg1); }' |
| Function instructions | no[1] | ||
| Stack traces | yes | Action: stack() | dtrace -n 'fbt:genunix:bdev_strategy:entry { stack() }' |
[1] not directly, although many indirect methods exist. See Limitations.
