uprobes Usage
Linux sysadmins often need to trace user-space applications for performance analysis or debugging. Unlike kernel probes (kprobes), ** uprobes** are designed to trace functions in user-space programs and shared libraries with minimal overhead. By leveraging eBPF (Extended Berkeley Packet Filter), uprobes allow you to instrument arbitrary user-space code, such as C libraries or custom binaries, without modifying the source or recompiling. This makes them ideal for monitoring application behavior in production environments.
Key Concepts¶
Uprobes work by attaching to specific memory addresses in user-space programs. These addresses can correspond to function symbols (e.g., main, strcpy) or raw memory offsets. When a probe is triggered, eBPF programs execute to collect data, such as function arguments, return values, or timestamps. The key advantages include:
- Low overhead: Uprobes avoid the need for kernel module loading or invasive instrumentation.
- Flexibility: Trace any function in user-space binaries or shared libraries.
- Precision: Capture detailed context (e.g., stack traces, arguments) with minimal performance impact.
Setting Up BCC for Uprobe Tracing¶
The BCC (BPF Compiler Collection) toolkit provides utilities like bpftrace and trace to manage uprobes. Ensure BCC is installed on your system:
To trace a user-space function, use the uprobe keyword in a BPF program. For example, to trace the main function of a binary:
Replace /usr/bin/myapp with the full path to your target binary. The function name must match exactly (case-sensitive).
Tracing User-space Functions¶
Example 1: Trace a Specific Function¶
To trace the strdup function from glibc:
Example 2: Capture Return Values¶
Use uretprobe to trace return values. For example, to log the length of a string copied by strcpy:
sudo bpftrace -e '
uprobe:/usr/bin/myapp:strcpy { arg1 = str(arg1); }
uretprobe:/usr/bin/myapp:strcpy { printf("Copied %s (len=%d)\n", arg1, __arg1); }
'
Example 3: Trace Dynamic Libraries¶
For shared libraries, specify the full path to the .so file:
sudo bpftrace -e 'uprobe:/usr/lib/x86_64-linux-gnu/libcurl.so.4:curl_easy_perform { printf("curl_easy_perform called\n"); }'
Handling Shared Libraries and Symbol Resolution¶
If the target binary is stripped of symbols, you may need to use memory addresses instead of function names. For example:
Use tools like readelf or nm to find symbol addresses in unstripped binaries. For shared libraries, ensure the path is correct and the library is loaded at runtime.
Troubleshooting¶
- Function not found: Verify the binary path and function name. Use
nmorobjdumpto check symbols. - Permissions: Ensure the tracer has access to the target binary (e.g., run with
sudo). - Stripped binaries: Use memory addresses or attach to shared libraries with known paths.
Key takeaways¶
- Uprobes enable low-overhead tracing of user-space functions and shared libraries.
- Use BCC tools like
bpftraceto attach probes to specific functions or memory addresses. - Combine
uprobewithuretprobeto capture function arguments and return values. - Handle stripped binaries by using memory offsets or tracing shared libraries.
- Always validate paths and symbols to avoid probe failures.