-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attach BTF to generated BPF programs #2804
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems reasonable. I'm not very familiar with llvm debuginfo interface though
45c290f
to
000ff11
Compare
@ajor do you want to review this, too? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, mainly just some nits. I'll do some testing myself to check out the createFile
thing.
src/ast/dibuilderbpf.cpp
Outdated
|
||
DIBuilderBPF::DIBuilderBPF(Module &module) : DIBuilder(module) | ||
{ | ||
file = createFile("bpftrace", "."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit unsure about this line but I'm not familiar enough with createFile
to be certain.
Does this actually create a file? Does "." mean current working directory? Can this result in permission errors if bpftrace is run from a non-writable directory?
Will do a bit of testing myself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it creates an actual file. I quickly skimmed the code of createFile
and IIUC, it should just create a debug info entry which is required to produce correct debug info for a function. We just need to provide a directory and a file name strings to create it, so we give the current directory and ”bpftrace” for the file name. I think that the strings themselves don't mean anything, we could provide anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran bpftrace through strace and can confirm it doesn't create a file at this location. If we print debug output ("-d") then it does attempt to read this file though:
openat(AT_FDCWD, "./bpftrace", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
I can make bpftrace read arbitrary data by manually creating a file at the expected location. It's not necessarily a problem but feels a bit dodgy to me.
How about we do createFile("", "")
? This seems to work and ensures that there can be no real file associated with our DIFile
object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran bpftrace through strace and can confirm it doesn't create a file at this location. If we print debug output ("-d") then it does attempt to read this file though:
openat(AT_FDCWD, "./bpftrace", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
Interesting, it's probably trying to open the file when dumping LLVM IR, I've no idea why.
How about we do
createFile("", "")
? This seems to work and ensures that there can be no real file associated with ourDIFile
object.
Sure, makes sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, unfortunately, we must pass a valid filename, otherwise LLVM IR verification (which we run in codegen tests) complains. I reverted it to the original version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran a few more tests and discovered that LLVM dump tries to open the file and either read it (if it's a text file) or mmap it to memory (if it's an ELF). While this shouldn't be harmful, it's certainly an unnecessary operation.
Using ./bpftrace
is therefore not ideal as it will exist when running ./bpftrace -e ...
and will do an unnecessary mmap of the bpftrace binary. So, I changed it to bpftrace.bpf.o
which is less likely to exist.
0, | ||
StringRef(), | ||
DICompileUnit::DebugEmissionKind::LineTablesOnly); | ||
module_->addModuleFlag(llvm::Module::Warning, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any idea what this is for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is required by DWARF.
01ee3be
to
daab7f9
Compare
82fff69
to
9aa23a6
Compare
In order for bpftrace to adapt to libbpf style loading of programs and to support subprograms, it first needs to produce BTF information for BPF programs. In order for it to produce BTF, it first needs to produce any debugging info, so that LLVM can convert it into BTF/BTF.ext sections. This commit emits subprogram entries for probe definitions. This does not use any line info but should be sufficient to create func infos down the road. Since we're going to generate more and more debug info in future, introduce a dedicated class DIBuilderBPF for encapsulating related logic and methods. DIBuilderBPF inherits from llvm::DIBuilder, the relationship is analogous to the one between IRBuilderBPF and llvm::IRBuilder.
BTF is not used for any purpose at the moment but it will be used in future and this way we can at least check that libbpf accepts our produced BTF.
9aa23a6
to
1dc0c60
Compare
I rebased to the current master to run tests with the CI libbpf. I'll wait 24 hours and then merge this, unless there are objections. |
Modern BPF programs loaded through libbpf should include BTF information describing their structure and data. This is required for some BPF features such as subprograms or kernel functions (kfuncs) to work. It is also a necessary prerequisite for #2334.
This PR is the first step for doing this in bpftrace. We produce standard (DWARF) debug info for our probes which LLVM then converts into proper BTF sections. These are then passed to libbpf upon
bpf_prog_load
. At the moment, this doesn't add any value but we at least check that libbpf doesn't reject our produced BTF info.This is the second part of #2710 posted separately to simplify reviewing.
Checklist
man/adoc/bpftrace.adoc
and if needed indocs/reference_guide.md
CHANGELOG.md