Skip to content
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

BTF support for tracepoints defined in modules #2479

Merged
merged 2 commits into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,10 @@ jobs:
run: >
docker load --input /tmp/docker-save/i.tar
- name: Load kernel modules
# nf_tables is necessary for testing kernel modules BTF support
run: sudo modprobe nf_tables
# nf_tables and xfs are necessary for testing kernel modules BTF support
run: |
sudo modprobe nf_tables
sudo modprobe xfs
- name: Build and test
env: ${{matrix.env}}
run: >
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ and this project adheres to
- [#2505](https://github.com/iovisor/bpftrace/pull/2505)
- Support printing entire structs
- [#2557](https://github.com/iovisor/bpftrace/pull/2557)
- BTF support for tracepoints defined in modules
- [#2479](https://github.com/iovisor/bpftrace/pull/2479)
#### Changed
#### Deprecated
#### Removed
Expand Down
11 changes: 9 additions & 2 deletions src/btf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,16 @@ std::string BTF::c_def(const std::unordered_set<std::string> &set) const
if (!has_data())
return std::string("");

// Definition dumping from modules would require to resolve type conflicts,
// so we dump from vmlinux only for now.
// Definition dumping from multiple modules would require to resolve type
// conflicts, so we allow dumping from a single module or from vmlinux only.
std::unordered_set<std::string> to_dump(set);
if (btf_objects.size() == 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like if bpf_objects.size() > 2, then only vmlinux btf is dumped. And user will get an ambiguous error about incomplete/missing definitions. Do we want to have a more explicit error check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. It'll happen only if probes from multiple modules are used at once, but adding the error message should be relatively easy.

{
auto *mod_btf = btf_objects[0].btf == vmlinux_btf ? btf_objects[1].btf
: btf_objects[0].btf;
return dump_defs_from_btf(mod_btf, to_dump);
}

return dump_defs_from_btf(vmlinux_btf, to_dump);
}

Expand Down
5 changes: 5 additions & 0 deletions src/btf.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "types.h"
#include <cstddef>
#include <linux/types.h>
#include <map>
#include <optional>
Expand Down Expand Up @@ -51,6 +52,10 @@ class BTF
~BTF();

bool has_data(void) const;
size_t objects_cnt() const
{
return btf_objects.size();
}
std::string c_def(const std::unordered_set<std::string>& set) const;
std::string type_of(const std::string& name, const std::string& field);
std::string type_of(const BTFId& type_id, const std::string& field);
Expand Down
7 changes: 7 additions & 0 deletions src/clang_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,13 @@ bool ClangParser::parse(ast::Program *program, BPFtrace &bpftrace, std::vector<s
{
LOG(ERROR) << "Include headers with missing type definitions or install "
"BTF information to your system.";
if (bpftrace.btf_->objects_cnt() > 2)
{
LOG(WARNING)
<< "Trying to dump BTF from multiple kernel modules at once. "
<< "This is currently not possible, use probes from a single module"
<< " (and/or vmlinux) only.";
}
}
return false;
}
Expand Down
12 changes: 10 additions & 2 deletions src/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ void Driver::error(const std::string &m)
failed_ = true;
}

// Retrieves the list of kernel modules for all attached-to functions.
// Currently modules are only important for k(ret)func probes.
// Retrieves the list of kernel modules for all attachpoints. Will be used to
// identify modules whose BTF we need to parse.
// Currently, this is useful for k(ret)func and tracepoint probes.
std::set<std::string> Driver::list_modules() const
{
std::set<std::string> modules;
Expand All @@ -102,6 +103,13 @@ std::set<std::string> Driver::list_modules() const
else
modules.insert(ap->target);
}
else if (probe_type == ProbeType::tracepoint)
{
// For now, we support this for a single target only since tracepoints
// need dumping of C definitions BTF and that is not available for
// multiple modules at once.
modules.insert(ap->target);
}
}
}
return modules;
Expand Down
7 changes: 7 additions & 0 deletions tests/runtime/btf
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ REQUIRES lsmod | grep '^nf_tables'
REQUIRES /usr/sbin/nft --help
AFTER nft delete table bpftrace

NAME kernel_module_tracepoint
PROG tracepoint:xfs:xfs_setfilesize { print(args->offset) } i:ms:1 { exit(); }
EXPECT Attaching 2 probes...
TIMEOUT 5
REQUIRES_FEATURE btf
REQUIRES lsmod | grep "^xfs"

# args->ctxt has type 'struct x86_emulate_ctxt' which is forward-defined in
# 'vmlinux' BTF and fully defined in 'kvm' BTF.
# This tests checks that the correct BTF definition is pulled from 'kvm'.
Expand Down