import bpftrace-0.9-2.el8
This commit is contained in:
commit
8f45bdb80c
1
.bpftrace.metadata
Normal file
1
.bpftrace.metadata
Normal file
@ -0,0 +1 @@
|
||||
a6409319efe13b553b05b8343077e2976b03a951 SOURCES/bpftrace-0.9.tar.gz
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
SOURCES/bpftrace-0.9.tar.gz
|
43
SOURCES/bpftrace-0.9-RHEL-8-fixes.patch
Normal file
43
SOURCES/bpftrace-0.9-RHEL-8-fixes.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 1dce61acfec57712f84cfdf2a8f4c69d27744b04 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 11 Jun 2019 16:41:59 +0200
|
||||
Subject: RHEL 8 fixes
|
||||
|
||||
Fixes the following RHEL 8 specific issues:
|
||||
- library path in gethostlatency
|
||||
|
||||
---
|
||||
tools/gethostlatency.bt | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/gethostlatency.bt b/tools/gethostlatency.bt
|
||||
index a1ac1b2..ade1005 100755
|
||||
--- a/tools/gethostlatency.bt
|
||||
+++ b/tools/gethostlatency.bt
|
||||
@@ -26,17 +26,17 @@ BEGIN
|
||||
"HOST");
|
||||
}
|
||||
|
||||
-uprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo,
|
||||
-uprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname,
|
||||
-uprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname2
|
||||
+uprobe:/lib64/libc.so.6:getaddrinfo,
|
||||
+uprobe:/lib64/libc.so.6:gethostbyname,
|
||||
+uprobe:/lib64/libc.so.6:gethostbyname2
|
||||
{
|
||||
@start[tid] = nsecs;
|
||||
@name[tid] = arg0;
|
||||
}
|
||||
|
||||
-uretprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo,
|
||||
-uretprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname,
|
||||
-uretprobe:/lib/x86_64-linux-gnu/libc.so.6:gethostbyname2
|
||||
+uretprobe:/lib64/libc.so.6:getaddrinfo,
|
||||
+uretprobe:/lib64/libc.so.6:gethostbyname,
|
||||
+uretprobe:/lib64/libc.so.6:gethostbyname2
|
||||
/@start[tid]/
|
||||
{
|
||||
$latms = (nsecs - @start[tid]) / 1000000;
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,255 @@
|
||||
From acb0ee316d5ed776253b6d7bfccfb21e0005919b Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Thu, 16 May 2019 14:56:50 +0200
|
||||
Subject: [PATCH] fix clang_parser for LLVM 8+
|
||||
|
||||
LLVM changed the behavior of clang_Cursor_isAnonymous in [1]. The old
|
||||
behavior would returned false for direct-acccess anonymous structs
|
||||
within other structs, whereas LLVM 8 returns true. To circumvent this
|
||||
behavior change among LLVM versions, we keep track of all structs
|
||||
defined within a struct. We don't parse the substruct recursively (if we
|
||||
do it might be parsed multiple times, and since we don't know yet if
|
||||
this is a direct or indirect strucutre, we might parse it incorrectly),
|
||||
instead we keep the cursor saved in a map. If this substruct is later
|
||||
declared as an attribute of the supersctruct, that means we have a
|
||||
direct-accessible struct. We remove it from our map, and we parse
|
||||
recursively (parsing recursively the cursor pointing to the declaration
|
||||
will effectively parse the struct definition).
|
||||
|
||||
After the first parse, any struct left in our map is an indirect struct.
|
||||
Since we skipped the parsing stage for those, we need to run
|
||||
`clang_visitChildren` again for each struct cursor we have saved. We
|
||||
repeat this until there's no unvisited structs in the map. Keep in mind
|
||||
that while visiting a new struct we might find more indirect structs.
|
||||
|
||||
Also add Travis jobs to test against LLVM and clang 8 on Ubuntu.
|
||||
|
||||
[1]: llvm/llvm-project@c05e6f4
|
||||
---
|
||||
.travis.yml | 4 ++
|
||||
docker/Dockerfile.bionic-llvm8 | 36 ++++++++++++++
|
||||
src/bpforc.h | 9 ++++
|
||||
src/clang_parser.cpp | 87 +++++++++++++++++++++++-----------
|
||||
4 files changed, 108 insertions(+), 28 deletions(-)
|
||||
create mode 100644 docker/Dockerfile.bionic-llvm8
|
||||
|
||||
diff --git a/.travis.yml b/.travis.yml
|
||||
index 7fbff63..b539868 100644
|
||||
--- a/.travis.yml
|
||||
+++ b/.travis.yml
|
||||
@@ -20,6 +20,10 @@ sudo: required
|
||||
env: BASE=fedora29 TYPE=Debug
|
||||
- name: "LLVM 7 Release"
|
||||
env: BASE=fedora29 TYPE=Release
|
||||
+ - name: "LLVM 8 Debug"
|
||||
+ env: BASE=bionic-llvm8 TYPE=Debug
|
||||
+ - name: "LLVM 8 Release"
|
||||
+ env: BASE=bionic-llvm8 TYPE=Release
|
||||
allow_failures:
|
||||
- name: "Static LLVM 5 Debug"
|
||||
env: BASE=alpine TYPE=Debug STATIC_LINKING=ON TEST_ARGS="--gtest_filter=-codegen.string_equal_comparison:codegen.string_not_equal_comparison"
|
||||
diff --git a/docker/Dockerfile.bionic-llvm8 b/docker/Dockerfile.bionic-llvm8
|
||||
new file mode 100644
|
||||
index 0000000..ebf10d3
|
||||
--- /dev/null
|
||||
+++ b/docker/Dockerfile.bionic-llvm8
|
||||
@@ -0,0 +1,36 @@
|
||||
+FROM ubuntu:bionic
|
||||
+
|
||||
+ENV llvmVersion=8
|
||||
+
|
||||
+RUN apt-get update && apt-get install -y curl gnupg &&\
|
||||
+ llvmRepository='\n\
|
||||
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main\n\
|
||||
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic main\n\
|
||||
+# 8\n\
|
||||
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main\n\
|
||||
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main' && \
|
||||
+ echo $llvmRepository >> /etc/apt/sources.list && \
|
||||
+ curl -L https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \
|
||||
+ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD && \
|
||||
+ echo "deb https://repo.iovisor.org/apt/bionic bionic main" | tee /etc/apt/sources.list.d/iovisor.list
|
||||
+
|
||||
+RUN apt-get update && apt-get install -y \
|
||||
+ bison \
|
||||
+ cmake \
|
||||
+ flex \
|
||||
+ g++ \
|
||||
+ git \
|
||||
+ libelf-dev \
|
||||
+ zlib1g-dev \
|
||||
+ libbcc \
|
||||
+ clang-${llvmVersion} \
|
||||
+ libclang-${llvmVersion}-dev \
|
||||
+ libclang-common-${llvmVersion}-dev \
|
||||
+ libclang1-${llvmVersion} \
|
||||
+ llvm-${llvmVersion} \
|
||||
+ llvm-${llvmVersion}-dev \
|
||||
+ llvm-${llvmVersion}-runtime \
|
||||
+ libllvm${llvmVersion}
|
||||
+
|
||||
+COPY build.sh /build.sh
|
||||
+ENTRYPOINT ["bash", "/build.sh"]
|
||||
diff --git a/src/bpforc.h b/src/bpforc.h
|
||||
index 1c134d0..8eede31 100644
|
||||
--- a/src/bpforc.h
|
||||
+++ b/src/bpforc.h
|
||||
@@ -80,8 +80,13 @@ class BpfOrc
|
||||
ExecutionSession ES;
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
std::shared_ptr<SymbolResolver> Resolver;
|
||||
+#if LLVM_VERSION_MAJOR >= 8
|
||||
+ LegacyRTDyldObjectLinkingLayer ObjectLayer;
|
||||
+ LegacyIRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
|
||||
+#else
|
||||
RTDyldObjectLinkingLayer ObjectLayer;
|
||||
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
|
||||
+#endif
|
||||
|
||||
public:
|
||||
std::map<std::string, std::tuple<uint8_t *, uintptr_t>> sections_;
|
||||
@@ -91,7 +96,11 @@ class BpfOrc
|
||||
Resolver(createLegacyLookupResolver(ES,
|
||||
[](const std::string &Name __attribute__((unused))) -> JITSymbol { return nullptr; },
|
||||
[](Error Err) { cantFail(std::move(Err), "lookup failed"); })),
|
||||
+#if LLVM_VERSION_MAJOR >= 8
|
||||
+ ObjectLayer(ES, [this](VModuleKey) { return LegacyRTDyldObjectLinkingLayer::Resources{std::make_shared<MemoryManager>(sections_), Resolver}; }),
|
||||
+#else
|
||||
ObjectLayer(ES, [this](VModuleKey) { return RTDyldObjectLinkingLayer::Resources{std::make_shared<MemoryManager>(sections_), Resolver}; }),
|
||||
+#endif
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {}
|
||||
|
||||
void compileModule(std::unique_ptr<Module> M) {
|
||||
diff --git a/src/clang_parser.cpp b/src/clang_parser.cpp
|
||||
index 4bb8f87..7bb8d6a 100644
|
||||
--- a/src/clang_parser.cpp
|
||||
+++ b/src/clang_parser.cpp
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <clang-c/Index.h>
|
||||
#include <iostream>
|
||||
+#include <unordered_map>
|
||||
+#include <unordered_set>
|
||||
#include <string.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -13,6 +15,9 @@
|
||||
|
||||
namespace bpftrace {
|
||||
|
||||
+std::unordered_map<std::string, CXCursor> indirect_structs;
|
||||
+std::unordered_set<std::string> unvisited_indirect_structs;
|
||||
+
|
||||
static std::string get_clang_string(CXString string)
|
||||
{
|
||||
std::string str = clang_getCString(string);
|
||||
@@ -30,8 +35,9 @@ static CXCursor get_indirect_field_parent_struct(CXCursor c)
|
||||
{
|
||||
CXCursor parent = clang_getCursorSemanticParent(c);
|
||||
|
||||
- while (!clang_Cursor_isNull(parent) && clang_Cursor_isAnonymous(parent))
|
||||
- parent = clang_getCursorSemanticParent(parent);
|
||||
+ while (!clang_Cursor_isNull(parent) && indirect_structs.count(get_clang_string(clang_getTypeSpelling(clang_getCanonicalType(clang_getCursorType(parent))))) > 0) {
|
||||
+ parent = clang_getCursorSemanticParent(parent);
|
||||
+ }
|
||||
|
||||
return parent;
|
||||
}
|
||||
@@ -253,44 +259,69 @@ void ClangParser::parse(ast::Program *program, BPFtrace &bpftrace)
|
||||
std::cerr << "Input (" << input.size() << "): " << input << std::endl;
|
||||
}
|
||||
|
||||
- CXCursor cursor = clang_getTranslationUnitCursor(translation_unit);
|
||||
+ indirect_structs.clear();
|
||||
+ unvisited_indirect_structs.clear();
|
||||
|
||||
- clang_visitChildren(
|
||||
- cursor,
|
||||
- [](CXCursor c, CXCursor parent, CXClientData client_data)
|
||||
- {
|
||||
+ CXCursor cursor = clang_getTranslationUnitCursor(translation_unit);
|
||||
|
||||
- if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
|
||||
- clang_getCursorKind(parent) != CXCursor_UnionDecl)
|
||||
- return CXChildVisit_Recurse;
|
||||
+ bool iterate = true;
|
||||
|
||||
- if (clang_getCursorKind(c) == CXCursor_FieldDecl)
|
||||
+ do {
|
||||
+ clang_visitChildren(
|
||||
+ cursor,
|
||||
+ [](CXCursor c, CXCursor parent, CXClientData client_data)
|
||||
{
|
||||
- auto &structs = static_cast<BPFtrace*>(client_data)->structs_;
|
||||
- auto struct_name = get_parent_struct_name(c);
|
||||
- auto ident = get_clang_string(clang_getCursorSpelling(c));
|
||||
- auto offset = clang_Cursor_getOffsetOfField(c) / 8;
|
||||
- auto type = clang_getCanonicalType(clang_getCursorType(c));
|
||||
+ if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
|
||||
+ clang_getCursorKind(parent) != CXCursor_UnionDecl)
|
||||
+ return CXChildVisit_Recurse;
|
||||
|
||||
auto ptype = clang_getCanonicalType(clang_getCursorType(parent));
|
||||
auto ptypestr = get_clang_string(clang_getTypeSpelling(ptype));
|
||||
auto ptypesize = clang_Type_getSizeOf(ptype);
|
||||
|
||||
- if(clang_Cursor_isAnonymous(parent))
|
||||
- offset = get_indirect_field_offset(c);
|
||||
+ if (clang_getCursorKind(c) == CXCursor_StructDecl ||
|
||||
+ clang_getCursorKind(c) == CXCursor_UnionDecl) {
|
||||
+ auto struct_name = get_clang_string(clang_getTypeSpelling(clang_getCanonicalType(clang_getCursorType(c))));
|
||||
+ indirect_structs[struct_name] = c;
|
||||
+ unvisited_indirect_structs.insert(struct_name);
|
||||
|
||||
- if (struct_name == "")
|
||||
- struct_name = ptypestr;
|
||||
- remove_struct_prefix(struct_name);
|
||||
+ return CXChildVisit_Continue;
|
||||
+ }
|
||||
|
||||
- structs[struct_name].fields[ident].offset = offset;
|
||||
- structs[struct_name].fields[ident].type = get_sized_type(type);
|
||||
- structs[struct_name].size = ptypesize;
|
||||
- }
|
||||
+ if (clang_getCursorKind(c) == CXCursor_FieldDecl)
|
||||
+ {
|
||||
+ auto &structs = static_cast<BPFtrace*>(client_data)->structs_;
|
||||
+ auto struct_name = get_parent_struct_name(c);
|
||||
+ auto ident = get_clang_string(clang_getCursorSpelling(c));
|
||||
+ auto offset = clang_Cursor_getOffsetOfField(c) / 8;
|
||||
+ auto type = clang_getCanonicalType(clang_getCursorType(c));
|
||||
+ auto typestr = get_clang_string(clang_getTypeSpelling(type));
|
||||
|
||||
- return CXChildVisit_Recurse;
|
||||
- },
|
||||
- &bpftrace);
|
||||
+ if (indirect_structs.count(typestr))
|
||||
+ indirect_structs.erase(typestr);
|
||||
+
|
||||
+ if(indirect_structs.count(ptypestr))
|
||||
+ offset = get_indirect_field_offset(c);
|
||||
+
|
||||
+ if (struct_name == "")
|
||||
+ struct_name = ptypestr;
|
||||
+ remove_struct_prefix(struct_name);
|
||||
+
|
||||
+ structs[struct_name].fields[ident].offset = offset;
|
||||
+ structs[struct_name].fields[ident].type = get_sized_type(type);
|
||||
+ structs[struct_name].size = ptypesize;
|
||||
+ }
|
||||
+
|
||||
+ return CXChildVisit_Recurse;
|
||||
+ },
|
||||
+ &bpftrace);
|
||||
+ if (unvisited_indirect_structs.size()) {
|
||||
+ cursor = indirect_structs[*unvisited_indirect_structs.begin()];
|
||||
+ unvisited_indirect_structs.erase(unvisited_indirect_structs.begin());
|
||||
+ } else {
|
||||
+ iterate = false;
|
||||
+ }
|
||||
+ } while (iterate);
|
||||
|
||||
clang_disposeTranslationUnit(translation_unit);
|
||||
clang_disposeIndex(index);
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,356 @@
|
||||
From 5143209e8744d242431229972d9affa32ba3cc1a Mon Sep 17 00:00:00 2001
|
||||
From: Matheus Marchini <mat@mmarchini.me>
|
||||
Date: Fri, 12 Apr 2019 16:27:51 -0700
|
||||
Subject: [PATCH 1/3] [clang_parser] pass BPFtrace as arg instead of StructMap
|
||||
|
||||
---
|
||||
src/clang_parser.cpp | 6 +--
|
||||
src/clang_parser.h | 3 +-
|
||||
src/main.cpp | 2 +-
|
||||
tests/clang_parser.cpp | 71 +++++++++++++++++++++++------------
|
||||
tests/codegen/call_kstack.cpp | 4 +-
|
||||
tests/codegen/call_ustack.cpp | 4 +-
|
||||
tests/codegen/common.h | 2 +-
|
||||
tests/codegen/general.cpp | 2 +-
|
||||
tests/probe.cpp | 2 +-
|
||||
tests/semantic_analyser.cpp | 2 +-
|
||||
10 files changed, 61 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/src/clang_parser.cpp b/src/clang_parser.cpp
|
||||
index b1db8ff..4bb8f87 100644
|
||||
--- a/src/clang_parser.cpp
|
||||
+++ b/src/clang_parser.cpp
|
||||
@@ -172,7 +172,7 @@ static std::tuple<std::string, std::string> get_kernel_dirs(const struct utsname
|
||||
return std::make_tuple(ksrc, kobj);
|
||||
}
|
||||
|
||||
-void ClangParser::parse(ast::Program *program, StructMap &structs)
|
||||
+void ClangParser::parse(ast::Program *program, BPFtrace &bpftrace)
|
||||
{
|
||||
auto input = program->c_definitions;
|
||||
if (input.size() == 0)
|
||||
@@ -259,7 +259,6 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
|
||||
cursor,
|
||||
[](CXCursor c, CXCursor parent, CXClientData client_data)
|
||||
{
|
||||
- auto &structs = *static_cast<StructMap*>(client_data);
|
||||
|
||||
if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
|
||||
clang_getCursorKind(parent) != CXCursor_UnionDecl)
|
||||
@@ -267,6 +266,7 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
|
||||
|
||||
if (clang_getCursorKind(c) == CXCursor_FieldDecl)
|
||||
{
|
||||
+ auto &structs = static_cast<BPFtrace*>(client_data)->structs_;
|
||||
auto struct_name = get_parent_struct_name(c);
|
||||
auto ident = get_clang_string(clang_getCursorSpelling(c));
|
||||
auto offset = clang_Cursor_getOffsetOfField(c) / 8;
|
||||
@@ -290,7 +290,7 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
|
||||
|
||||
return CXChildVisit_Recurse;
|
||||
},
|
||||
- &structs);
|
||||
+ &bpftrace);
|
||||
|
||||
clang_disposeTranslationUnit(translation_unit);
|
||||
clang_disposeIndex(index);
|
||||
diff --git a/src/clang_parser.h b/src/clang_parser.h
|
||||
index d2ada5d..4289796 100644
|
||||
--- a/src/clang_parser.h
|
||||
+++ b/src/clang_parser.h
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "struct.h"
|
||||
+#include "bpftrace.h"
|
||||
|
||||
namespace bpftrace {
|
||||
|
||||
@@ -11,7 +12,7 @@ using StructMap = std::map<std::string, Struct>;
|
||||
class ClangParser
|
||||
{
|
||||
public:
|
||||
- void parse(ast::Program *program, StructMap &structs);
|
||||
+ void parse(ast::Program *program, BPFtrace &bpftrace);
|
||||
};
|
||||
|
||||
} // namespace bpftrace
|
||||
diff --git a/src/main.cpp b/src/main.cpp
|
||||
index ec3882d..f6659bf 100644
|
||||
--- a/src/main.cpp
|
||||
+++ b/src/main.cpp
|
||||
@@ -272,7 +272,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace);
|
||||
err = semantics.analyse();
|
||||
diff --git a/tests/clang_parser.cpp b/tests/clang_parser.cpp
|
||||
index f12a5e4..0c1ca31 100644
|
||||
--- a/tests/clang_parser.cpp
|
||||
+++ b/tests/clang_parser.cpp
|
||||
@@ -1,25 +1,28 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "clang_parser.h"
|
||||
#include "driver.h"
|
||||
+#include "bpftrace.h"
|
||||
|
||||
namespace bpftrace {
|
||||
namespace test {
|
||||
namespace clang_parser {
|
||||
|
||||
-void parse(const std::string &input, StructMap &structs)
|
||||
+void parse(const std::string &input, BPFtrace &bpftrace)
|
||||
{
|
||||
auto extended_input = input + "kprobe:sys_read { 1 }";
|
||||
Driver driver;
|
||||
ASSERT_EQ(driver.parse_str(extended_input), 0);
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, structs);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
}
|
||||
|
||||
TEST(clang_parser, integers)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Foo { int x; int y, z; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Foo { int x; int y, z; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.size(), 1U);
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
@@ -45,8 +48,10 @@ TEST(clang_parser, integers)
|
||||
|
||||
TEST(clang_parser, c_union)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("union Foo { char c; short s; int i; long l; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("union Foo { char c; short s; int i; long l; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.size(), 1U);
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
@@ -77,8 +82,10 @@ TEST(clang_parser, c_union)
|
||||
|
||||
TEST(clang_parser, integer_ptr)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Foo { int *x; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Foo { int *x; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.size(), 1U);
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
@@ -96,8 +103,10 @@ TEST(clang_parser, integer_ptr)
|
||||
|
||||
TEST(clang_parser, string_ptr)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Foo { char *str; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Foo { char *str; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.size(), 1U);
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
@@ -115,8 +124,10 @@ TEST(clang_parser, string_ptr)
|
||||
|
||||
TEST(clang_parser, string_array)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Foo { char str[32]; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Foo { char str[32]; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.size(), 1U);
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
@@ -132,8 +143,10 @@ TEST(clang_parser, string_array)
|
||||
|
||||
TEST(clang_parser, nested_struct_named)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Bar { int x; } struct Foo { struct Bar bar; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Bar { int x; } struct Foo { struct Bar bar; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.size(), 2U);
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
@@ -151,8 +164,10 @@ TEST(clang_parser, nested_struct_named)
|
||||
|
||||
TEST(clang_parser, nested_struct_ptr_named)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Bar { int x; } struct Foo { struct Bar *bar; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Bar { int x; } struct Foo { struct Bar *bar; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.size(), 2U);
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
@@ -172,8 +187,10 @@ TEST(clang_parser, nested_struct_ptr_named)
|
||||
|
||||
TEST(clang_parser, nested_struct_anon)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Foo { struct { int x; } bar; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Foo { struct { int x; } bar; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.size(), 2U);
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
@@ -190,8 +207,10 @@ TEST(clang_parser, nested_struct_anon)
|
||||
|
||||
TEST(clang_parser, nested_struct_indirect_fields)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Foo { struct { int x; int y;}; int a; struct { int z; }; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Foo { struct { int x; int y;}; int a; struct { int z; }; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs["Foo"].fields.size(), 4U);
|
||||
EXPECT_EQ(structs["Foo"].fields["x"].offset, 0);
|
||||
@@ -206,8 +225,10 @@ TEST(clang_parser, nested_struct_indirect_fields)
|
||||
|
||||
TEST(clang_parser, nested_struct_anon_union_struct)
|
||||
{
|
||||
- StructMap structs;
|
||||
- parse("struct Foo { union { long long _xy; struct { int x; int y;}; }; int a; struct { int z; }; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("struct Foo { union { long long _xy; struct { int x; int y;}; }; int a; struct { int z; }; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs["Foo"].fields.size(), 5U);
|
||||
EXPECT_EQ(structs["Foo"].fields["_xy"].offset, 0);
|
||||
@@ -225,8 +246,10 @@ TEST(clang_parser, nested_struct_anon_union_struct)
|
||||
TEST(clang_parser, builtin_headers)
|
||||
{
|
||||
// size_t is definied in stddef.h
|
||||
- StructMap structs;
|
||||
- parse("#include <stddef.h>\nstruct Foo { size_t x, y, z; }", structs);
|
||||
+ BPFtrace bpftrace;
|
||||
+ parse("#include <stddef.h>\nstruct Foo { size_t x, y, z; }", bpftrace);
|
||||
+
|
||||
+ StructMap &structs = bpftrace.structs_;
|
||||
|
||||
ASSERT_EQ(structs.count("Foo"), 1U);
|
||||
|
||||
diff --git a/tests/codegen/call_kstack.cpp b/tests/codegen/call_kstack.cpp
|
||||
index a184af2..e64d498 100644
|
||||
--- a/tests/codegen/call_kstack.cpp
|
||||
+++ b/tests/codegen/call_kstack.cpp
|
||||
@@ -68,7 +68,7 @@ TEST(codegen, call_kstack_mapids)
|
||||
ASSERT_EQ(driver.parse_str("kprobe:f { @x = kstack(5); @y = kstack(6); @z = kstack(6) }"), 0);
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace);
|
||||
ASSERT_EQ(semantics.analyse(), 0);
|
||||
@@ -96,7 +96,7 @@ TEST(codegen, call_kstack_modes_mapids)
|
||||
ASSERT_EQ(driver.parse_str("kprobe:f { @x = kstack(perf); @y = kstack(bpftrace); @z = kstack() }"), 0);
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace);
|
||||
ASSERT_EQ(semantics.analyse(), 0);
|
||||
diff --git a/tests/codegen/call_ustack.cpp b/tests/codegen/call_ustack.cpp
|
||||
index 8e80558..1941d36 100644
|
||||
--- a/tests/codegen/call_ustack.cpp
|
||||
+++ b/tests/codegen/call_ustack.cpp
|
||||
@@ -74,7 +74,7 @@ TEST(codegen, call_ustack_mapids)
|
||||
ASSERT_EQ(driver.parse_str("kprobe:f { @x = ustack(5); @y = ustack(6); @z = ustack(6) }"), 0);
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace);
|
||||
ASSERT_EQ(semantics.analyse(), 0);
|
||||
@@ -102,7 +102,7 @@ TEST(codegen, call_ustack_modes_mapids)
|
||||
ASSERT_EQ(driver.parse_str("kprobe:f { @x = ustack(perf); @y = ustack(bpftrace); @z = ustack() }"), 0);
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace);
|
||||
ASSERT_EQ(semantics.analyse(), 0);
|
||||
diff --git a/tests/codegen/common.h b/tests/codegen/common.h
|
||||
index 32f8bc8..bdf733a 100644
|
||||
--- a/tests/codegen/common.h
|
||||
+++ b/tests/codegen/common.h
|
||||
@@ -30,7 +30,7 @@ static void test(const std::string &input, const std::string expected_output)
|
||||
ASSERT_EQ(driver.parse_str(input), 0);
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace);
|
||||
ASSERT_EQ(semantics.analyse(), 0);
|
||||
diff --git a/tests/codegen/general.cpp b/tests/codegen/general.cpp
|
||||
index e7e7439..e67ae10 100644
|
||||
--- a/tests/codegen/general.cpp
|
||||
+++ b/tests/codegen/general.cpp
|
||||
@@ -45,7 +45,7 @@ TEST(codegen, printf_offsets)
|
||||
// TODO (mmarchini): also test printf with a string argument
|
||||
ASSERT_EQ(driver.parse_str("struct Foo { char c; int i; } kprobe:f { $foo = (Foo*)0; printf(\"%c %u\\n\", $foo->c, $foo->i) }"), 0);
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace);
|
||||
ASSERT_EQ(semantics.analyse(), 0);
|
||||
ASSERT_EQ(semantics.create_maps(true), 0);
|
||||
diff --git a/tests/probe.cpp b/tests/probe.cpp
|
||||
index e030830..cb9b765 100644
|
||||
--- a/tests/probe.cpp
|
||||
+++ b/tests/probe.cpp
|
||||
@@ -28,7 +28,7 @@ void gen_bytecode(const std::string &input, std::stringstream &out)
|
||||
ASSERT_EQ(driver.parse_str(input), 0);
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace);
|
||||
ASSERT_EQ(semantics.analyse(), 0);
|
||||
diff --git a/tests/semantic_analyser.cpp b/tests/semantic_analyser.cpp
|
||||
index 2067ed9..4e2485b 100644
|
||||
--- a/tests/semantic_analyser.cpp
|
||||
+++ b/tests/semantic_analyser.cpp
|
||||
@@ -16,7 +16,7 @@ void test(BPFtrace &bpftrace, Driver &driver, const std::string &input, int expe
|
||||
ASSERT_EQ(driver.parse_str(input), 0);
|
||||
|
||||
ClangParser clang;
|
||||
- clang.parse(driver.root_, bpftrace.structs_);
|
||||
+ clang.parse(driver.root_, bpftrace);
|
||||
|
||||
std::stringstream out;
|
||||
ast::SemanticAnalyser semantics(driver.root_, bpftrace, out);
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 151351ea22c855e4e605b8fd2058c19dc4ae5ed6 Mon Sep 17 00:00:00 2001
|
||||
From: Matheus Marchini <mat@mmarchini.me>
|
||||
Date: Tue, 16 Apr 2019 12:06:01 -0700
|
||||
Subject: [PATCH 2/2] fix struct definition from headers
|
||||
|
||||
Regression caused by iovisor/bpftrace@80ce138c7. With the changes on how
|
||||
we identify the parent struct, we ended up with our parent cursor in the
|
||||
header file sometimes instead of a valid cursor. This PR checks if the
|
||||
parent cursor is a struct, otherwise returns an empty string and let the
|
||||
caller handle the situation (which is similar to the previous behavior).
|
||||
---
|
||||
src/clang_parser.cpp | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/clang_parser.cpp b/src/clang_parser.cpp
|
||||
index b1db8ff..b787b67 100644
|
||||
--- a/src/clang_parser.cpp
|
||||
+++ b/src/clang_parser.cpp
|
||||
@@ -40,6 +40,10 @@ static std::string get_parent_struct_name(CXCursor c)
|
||||
{
|
||||
CXCursor parent = get_indirect_field_parent_struct(c);
|
||||
|
||||
+ if (clang_getCursorKind(parent) != CXCursor_StructDecl &&
|
||||
+ clang_getCursorKind(parent) != CXCursor_UnionDecl)
|
||||
+ return "";
|
||||
+
|
||||
return get_clang_string(clang_getCursorSpelling(parent));
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
111
SPECS/bpftrace.spec
Normal file
111
SPECS/bpftrace.spec
Normal file
@ -0,0 +1,111 @@
|
||||
%bcond_without llvm_static
|
||||
|
||||
Name: bpftrace
|
||||
Version: 0.9
|
||||
Release: 2%{?dist}
|
||||
Summary: High-level tracing language for Linux eBPF
|
||||
License: ASL 2.0
|
||||
|
||||
URL: https://github.com/iovisor/bpftrace
|
||||
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
|
||||
Patch0: %{name}-%{version}-clang_parser-pass-BPFtrace-as-arg-instead-of-StructM.patch
|
||||
Patch1: %{name}-%{version}-clang_parser-fix-clang_parser-for-LLVM-8.patch
|
||||
Patch2: %{name}-%{version}-fix-struct-definition-from-headers.patch
|
||||
Patch3: %{name}-%{version}-RHEL-8-fixes.patch
|
||||
|
||||
# Arches will be included as upstream support is added and dependencies are
|
||||
# satisfied in the respective arches
|
||||
ExclusiveArch: x86_64 %{power64} aarch64 s390x
|
||||
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: bison
|
||||
BuildRequires: flex
|
||||
BuildRequires: cmake
|
||||
BuildRequires: elfutils-libelf-devel
|
||||
BuildRequires: zlib-devel
|
||||
BuildRequires: llvm-devel
|
||||
BuildRequires: clang-devel
|
||||
BuildRequires: bcc-devel
|
||||
|
||||
%if %{with llvm_static}
|
||||
BuildRequires: llvm-static
|
||||
%endif
|
||||
|
||||
%description
|
||||
BPFtrace is a high-level tracing language for Linux enhanced Berkeley Packet
|
||||
Filter (eBPF) available in recent Linux kernels (4.x). BPFtrace uses LLVM as a
|
||||
backend to compile scripts to BPF-bytecode and makes use of BCC for
|
||||
interacting with the Linux BPF system, as well as existing Linux tracing
|
||||
capabilities: kernel dynamic tracing (kprobes), user-level dynamic tracing
|
||||
(uprobes), and tracepoints. The BPFtrace language is inspired by awk and C,
|
||||
and predecessor tracers such as DTrace and SystemTap
|
||||
|
||||
|
||||
%prep
|
||||
%autosetup -p1
|
||||
|
||||
|
||||
%build
|
||||
%cmake . \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DBUILD_TESTING:BOOL=OFF \
|
||||
-DBUILD_SHARED_LIBS:BOOL=OFF \
|
||||
-DLLVM_DIR=/usr/lib64/llvm7.0/lib/cmake/llvm/
|
||||
%make_build
|
||||
|
||||
|
||||
%install
|
||||
%make_install
|
||||
|
||||
# Fix shebangs (https://fedoraproject.org/wiki/Packaging:Guidelines#Shebang_lines)
|
||||
find %{buildroot}%{_datadir}/%{name}/tools -type f -exec \
|
||||
sed -i -e '1s=^#!/usr/bin/env %{name}\([0-9.]\+\)\?$=#!%{_bindir}/%{name}=' {} \;
|
||||
|
||||
# Move man pages to the right location
|
||||
mkdir -p %{buildroot}%{_mandir}
|
||||
mv %{buildroot}%{_prefix}/man/* %{buildroot}%{_mandir}/
|
||||
|
||||
|
||||
%files
|
||||
%doc README.md CONTRIBUTING-TOOLS.md
|
||||
%doc docs/reference_guide.md docs/tutorial_one_liners.md
|
||||
%license LICENSE
|
||||
%dir %{_datadir}/%{name}
|
||||
%dir %{_datadir}/%{name}/tools
|
||||
%dir %{_datadir}/%{name}/tools/doc
|
||||
%{_bindir}/%{name}
|
||||
%{_mandir}/man8/*
|
||||
%attr(0755,-,-) %{_datadir}/%{name}/tools/*.bt
|
||||
%{_datadir}/%{name}/tools/doc/*.txt
|
||||
|
||||
|
||||
%changelog
|
||||
* Wed Jun 12 2019 Jerome Marchand <jmarchan@redhat.com> - 0.9.2
|
||||
- Fixes gethostlatency
|
||||
- Fixes a struct definition issue that made several tools fail
|
||||
- Add CI gating
|
||||
|
||||
* Wed May 15 2019 Jerome Marchand <jmarchan@redhat.com> - 0.9.1
|
||||
- Original build on RHEL 8
|
||||
|
||||
* Thu Apr 25 2019 Augusto Caringi <acaringi@redhat.com> - 0.9-3
|
||||
- Rebuilt for bcc 0.9.0
|
||||
|
||||
* Mon Apr 22 2019 Neal Gompa <ngompa@datto.com> - 0.9-2
|
||||
- Fix Source0 reference
|
||||
- Use make_build macro for calling make
|
||||
|
||||
* Mon Apr 1 2019 Peter Robinson <pbrobinson@fedoraproject.org> 0.9-1
|
||||
- Build on aarch64 and s390x
|
||||
|
||||
* Mon Mar 25 2019 Augusto Caringi <acaringi@redhat.com> - 0.9-0
|
||||
- Updated to version 0.9
|
||||
|
||||
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.0-2.20181210gitc49b333
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||
|
||||
* Mon Dec 10 2018 Augusto Caringi <acaringi@redhat.com> - 0.0-1.20181210gitc49b333
|
||||
- Updated to latest upstream (c49b333c034a6d29a7ce90f565e27da1061af971)
|
||||
|
||||
* Wed Nov 07 2018 Augusto Caringi <acaringi@redhat.com> - 0.0-1.20181107git029717b
|
||||
- Initial import
|
Loading…
Reference in New Issue
Block a user