|
| 1 | + |
| 2 | +# Stapsdt Provider |
| 3 | + |
| 4 | +The `stapsdt` provider allows DTrace to read ELF notes for binaries, using |
| 5 | +`/proc/` maps associated with processes, and parse them to retrieve `uprobe` |
| 6 | +addresses and argument-related information to create the associated `uprobe`. |
| 7 | +That is, the provider allows DTrace to probe programs and libraries that |
| 8 | +contain static probes that were added via `stapsdt` ELF notes. |
| 9 | + |
| 10 | +Note that `stapsdt` probes do not dynamically register themselves with DTrace, |
| 11 | +making them less powerful than DTrace-based USDT probes. |
| 12 | + |
| 13 | +**Parent topic:**[DTrace Provider Reference](../reference/dtrace_providers.md) |
| 14 | + |
| 15 | +## stapsdt Probes <a id="dt_ref_stapsdtprobes_prov"> |
| 16 | + |
| 17 | +You may not be interested in inserting probes into source code yourself, |
| 18 | +but simply taking advantage of static probes inserted into the ELF notes |
| 19 | +of binaries and libraries by other developers. For example, probes for DTrace |
| 20 | +and SystemTap were added to Python as far back as Python 3.6 provided |
| 21 | +Python is built with [`--with-dtrace`](https://docs.python.org/3/howto/instrumentation.html). |
| 22 | + |
| 23 | +Alternatively, you can insert your own probe into application or library |
| 24 | +source code as follows: |
| 25 | + |
| 26 | +``` |
| 27 | +#define _SDT_HAS_SEMAPHORES 1 |
| 28 | +#include <sys/sdt.h> |
| 29 | +
|
| 30 | +unsigned short myprovider_myprobe_semaphore = 0; |
| 31 | +
|
| 32 | + if (myprovider_myprobe_semaphore) { |
| 33 | + STAP_PROBEn(myprovider, myprobe, ...); |
| 34 | + } |
| 35 | +``` |
| 36 | + |
| 37 | +The *semaphore* portions are only needed if you want to test at run time |
| 38 | +whether the probe is enabled; this can reduce run-time overheads for cases |
| 39 | +where a probe is not enabled. The `...` indicate the probe arguments; note that |
| 40 | +`STAP_PROBEn` should be replaced by `STAP_PROBE`, `STAP_PROBE1`, `STAP_PROBE2`, |
| 41 | +`STAP_PROBE3`, etc., depending on how many probe arguments there are. |
| 42 | + |
| 43 | +The `stapsdt` provider also supports probes created dynamically via `libstapsdt`. |
| 44 | +See [https://github.com/linux-usdt/libstapsdt](https://github.com/linux-usdt/libstapsdt). |
| 45 | + |
| 46 | +In your D scripts, the provider name must have the pid for your process |
| 47 | +appended. For the provider shown above, you might have `myprovider12345` |
| 48 | +for pid 12345. No wildcard may be used, but a symbolic value like `$target` may. |
| 49 | + |
| 50 | +In your D scripts, the `stapsdt` module name may be `a.out` just as one can |
| 51 | +with the [`pid` provider](dtrace_providers_pid.md#dt_ref_pidprobes_prov). |
| 52 | + |
| 53 | +## stapsdt Examples <a id="dt_ref_stapsdtexamples_prov"> |
| 54 | + |
| 55 | +For example, consider this sample source code, which could represent the instrumentation one |
| 56 | +might place in application or library source code: |
| 57 | + |
| 58 | +``` |
| 59 | +#include <stdio.h> |
| 60 | +#define _SDT_HAS_SEMAPHORES 1 |
| 61 | +#include <sys/sdt.h> |
| 62 | +
|
| 63 | +unsigned short myprovider_myprobe_semaphore = 0; |
| 64 | +
|
| 65 | +int |
| 66 | +main(int argc, char **argv) |
| 67 | +{ |
| 68 | + STAP_PROBE3(myprovider, myprobe, argc, argv[0], 18); |
| 69 | + if (myprovider_myprobe_semaphore) |
| 70 | + printf("the probe is enabled\n"); |
| 71 | + else |
| 72 | + printf("the probe is not enabled\n"); |
| 73 | +
|
| 74 | + return 0; |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +Assuming it is called `test.c`, compile with `gcc test.c`. |
| 79 | + |
| 80 | +We can then run `dtrace -l` to list the available probes, |
| 81 | +assuming we specify the pid-specific provider (in this case using |
| 82 | +the `$target` symbolic name): |
| 83 | + |
| 84 | +``` |
| 85 | +$ sudo /usr/sbin/dtrace -c ./a.out -lvP 'myprovider$target' |
| 86 | + ID PROVIDER MODULE FUNCTION NAME |
| 87 | + 5067 myprovider2623420 a.out main myprobe |
| 88 | + [...] |
| 89 | + Argument Types |
| 90 | + args[0]: int32_t |
| 91 | + args[1]: uint64_t |
| 92 | + args[2]: int32_t |
| 93 | +``` |
| 94 | + |
| 95 | +Since we list the arguments with `-v`, we get information on the argument |
| 96 | +types: the first and last arguments are 4-byte integers, while the middle argument |
| 97 | +is 8 bytes (a `char *`). |
| 98 | + |
| 99 | +We can run the program without `dtrace` to confirm that the probe is |
| 100 | +not enabled by default: |
| 101 | + |
| 102 | +``` |
| 103 | +$ ./a.out |
| 104 | +the probe is not enabled |
| 105 | +``` |
| 106 | + |
| 107 | +Next, we run with `dtrace` and see that the probe *is* enabled and |
| 108 | +that the probe arguments are `argc, argv[0], 18`, as indicated in |
| 109 | +the `test.c` source code: |
| 110 | + |
| 111 | +``` |
| 112 | +$ sudo /usr/sbin/dtrace -c ./a.out -qn ' |
| 113 | +myprovider$target:::myprobe |
| 114 | +{ |
| 115 | + printf("%li, %s, %li\n", arg0, copyinstr(arg1), arg2); |
| 116 | +}' |
| 117 | +the probe is enabled |
| 118 | +1, ./a.out, 18 |
| 119 | +``` |
| 120 | + |
| 121 | +Adventurous readers can use `readelf` to explore the ELF notes |
| 122 | +more directly: |
| 123 | + |
| 124 | +``` |
| 125 | +$ readelf --notes a.out |
| 126 | +[...] |
| 127 | +Displaying notes found in: .note.stapsdt |
| 128 | + Owner Data size Description |
| 129 | + stapsdt 0x00000045 NT_STAPSDT (SystemTap probe descriptors) |
| 130 | + Provider: myprovider |
| 131 | + Name: myprobe |
| 132 | + Location: 0x000000000040113c, Base: 0x000000000040203e, Semaphore: 0x0000000000404026 |
| 133 | + Arguments: -4@-4(%rbp) 8@%rax -4@$18 |
| 134 | +``` |
| 135 | + |
| 136 | +Notice that the instrumented source code includes the header file |
| 137 | +`<sys/sdt.h>`. On Oracle Linux, this file is installed |
| 138 | +by the RPM package `systemtap-sdt-devel`, but the package also |
| 139 | +installs `/usr/bin/dtrace`. So be sure to have `/usr/sbin` |
| 140 | +in front of `/usr/bin` in your path, or explicitly specify |
| 141 | +`/usr/sbin/dtrace` whenever you want to use `dtrace`. |
| 142 | + |
| 143 | +## stapsdt Stability <a id="dt_ref_stapsdtstab_prov"> |
| 144 | + |
| 145 | +The `stapsdt` provider uses DTrace's stability mechanism to describe its stabilities. |
| 146 | +These values are listed in the following table. |
| 147 | + |
| 148 | +| Element | Name Stability | Data Stability | Dependency Class | |
| 149 | +| :--- | :--- | :--- | :--- | |
| 150 | +| Provider | Evolving | Evolving | ISA | |
| 151 | +| Module | Private | Private | Unknown | |
| 152 | +| Function | Private | Private | Unknown | |
| 153 | +| Name | Evolving | Evolving | ISA | |
| 154 | +| Arguments | Private | Private | Unknown | |
0 commit comments