Open gouravkrosx opened 8 months ago
How have you run the Python program with something like LD_PRELOAD=~/.bpftime/libbpftime-agent.so [Your python program]
? What's the output?
See https://github.com/eunomia-bpf/bpftime/tree/master/example/minimal
You can load the LD_PRELOAD=~/.bpftime/libbpftime-syscall-server.so ./time_freezer
first, and execute the LD_PRELOAD=~/.bpftime/libbpftime-agent.so [Your python program]
in another shell.
It can work in my computer. See my experiment code in https://github.com/eunomia-bpf/bpftime/blob/uprobe-python/example/minimal/uprobe-override.bpf.c
If you find any documents making you confused, please tell us or open a PR : )
@yunwei37 Thank you very much for your help, the solution you provided worked perfectly! It turns out I had overlooked starting the client with the command you provided, which was my mistake.
I have two questions that I'm hoping you can help with:
Does a Go-based loader exist for loading and attaching eBPF programs using the bpftime library, similar to what Cilium offers? I'm looking for a way to manage my eBPF programs more efficiently within a Go environment.
How to build binaries in such a way that targeted function symbols are exposed?
Thanks!
For the first question, maybe you can try https://github.com/aquasecurity/libbpfgo, it should be able to work with bpftime.
For the second questions:
To build binaries with targeted function symbols exposed, you generally need to follow a few key steps. This process involves configuring your build system and compiler flags to ensure that the symbols you want are not stripped during the compilation and linking process. Here's a general approach:
For GCC/Clang: Use the -g
flag to include debugging information in the binary, which includes symbol names. Additionally, you can use -fvisibility=default
to ensure that symbols are not hidden by default.
gcc -g -fvisibility=default -o myprogram myprogram.c
For Microsoft Visual Studio (MSVC): Use /DEBUG
to generate debug information and /Zi
or /ZI
for C/C++ source debugging information. Use /EXPORT:symbolname
to explicitly export a symbol.
cl /DEBUG /Zi /EXPORT:functionName file.c /link /OUT:myprogram.exe
Use Attribute Directives: In your code, you can control the visibility of specific functions using attribute directives. For GCC and Clang, you can use __attribute__((visibility("default")))
to a function declaration. This makes the function exported explicitly.
void __attribute__((visibility("default"))) myExportedFunction() {
// Implementation
}
For C++ (GCC/Clang): Use __attribute__
or #pragma GCC visibility push(default)
around declarations to export C++ classes or functions.
#pragma GCC visibility push(default)
class MyClass {
// Class definition
};
#pragma GCC visibility pop
For Windows (MSVC): Use __declspec(dllexport)
in your function or class declaration to export symbols.
__declspec(dllexport) void MyExportedFunction() {
// Implementation
}
Ensure that the linker does not strip away the symbols you want to keep.
For GCC/Clang: Use -Wl,--export-dynamic
to export symbols for dynamic linking.
gcc -g -o myprogram myprogram.c -Wl,--export-dynamic
Avoid Stripping Symbols: Some build systems or packaging scripts may strip symbols from the binary to reduce its size. Ensure that any strip
commands used in the build process are configured not to remove the symbols you wish to keep.
If you are linking against static libraries, ensure that the symbols you need are not removed during the linkage. Sometimes, using shared libraries (.so
or .dll
) might be more straightforward for ensuring symbol visibility across binaries.
After building, you can use tools like nm
(on Unix-like systems) or dumpbin
(on Windows) to verify that your symbols are indeed exposed in the binary.
Unix-like Systems:
nm -C myprogram | grep myExportedFunction
Windows:
dumpbin /EXPORTS myprogram.exe
This approach ensures that your binary exposes the necessary function symbols while maintaining the rest of your codebase as intended. Remember to carefully manage symbol visibility, as exposing too many symbols can lead to larger binary sizes and potentially more complex dependency issues.
From GPT4, seems it's mostly correct
Thanks again for your help.
Could you share an example of using libbpfgo with bpftime? Also, I'm curious if bpftime is compatible with cilium since they seem similar.
On another note, I'm facing difficulties using bpf_override_return
with kernel uretprobes. Any insights on this would be greatly appreciated.
I can see in this article that it is not supported I guess. Any reason why?
On the other hand, Uprobe is currently limited to tracing and cannot modify the execution flow or return values of user-space functions
I'm experimenting with overriding the Python time function and attempted to use Cilium eBPF but faced challenges, leading me to explore this library. Below is my eBPF code:
And here's the userspace code:
The program is run using the following command:
LD_PRELOAD=~/.bpftime/libbpftime-syscall-server.so ./time_freezer
It loads without any errors.I'm quite new to this library and unsure about what I might be doing incorrectly. Could you please provide some guidance?
The Python handler where I attempt to get the time is as follows: