Skip to content

Commit

Permalink
Fix LLVM 5 tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ajor committed May 19, 2019
1 parent 371c7cf commit 938e79b
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 16 deletions.
14 changes: 6 additions & 8 deletions .travis.yml
Expand Up @@ -8,10 +8,14 @@ services:

matrix:
include:
# Certain tests are disabled on our LLVM 5 builds because they are flaky
# when bpftrace is compiled with musl libc. They should still be capable
# of passing occasionally.
# String comparisons are the exception - they are just broken in debug builds.
- name: "Static LLVM 5 Debug"
env: LLVM_VERSION=5.0 BASE=alpine TYPE=Debug STATIC_LINKING=ON TEST_ARGS="--gtest_filter=-codegen.string_equal_comparison:codegen.string_not_equal_comparison"
env: LLVM_VERSION=5.0 BASE=alpine TYPE=Debug STATIC_LINKING=ON TEST_ARGS="--gtest_filter=codegen.*:-codegen.call_ntop_char4:codegen.call_ntop_char16:codegen.call_printf:codegen.enum_declaration:codegen.macro_definition:codegen.struct_*:codegen.string_equal_comparison:codegen.string_not_equal_comparison"
- name: "Static LLVM 5 Release"
env: LLVM_VERSION=5.0 BASE=alpine TYPE=Release STATIC_LINKING=ON
env: LLVM_VERSION=5.0 BASE=alpine TYPE=Release STATIC_LINKING=ON TEST_ARGS="--gtest_filter=codegen.*:-codegen.call_ntop_char4:codegen.call_ntop_char16:codegen.call_printf:codegen.enum_declaration:codegen.macro_definition:codegen.struct_*"

- name: "LLVM 6 Debug"
env: LLVM_VERSION=6.0 BASE=bionic TYPE=Debug
Expand All @@ -28,12 +32,6 @@ matrix:
- name: "LLVM 8 Release"
env: LLVM_VERSION=8 BASE=bionic TYPE=Release

allow_failures:
- name: "Static LLVM 5 Debug"
env: LLVM_VERSION=5.0 BASE=alpine TYPE=Debug STATIC_LINKING=ON TEST_ARGS="--gtest_filter=-codegen.string_equal_comparison:codegen.string_not_equal_comparison"
- name: "Static LLVM 5 Release"
env: LLVM_VERSION=5.0 BASE=alpine TYPE=Release STATIC_LINKING=ON

script:
- docker build --build-arg LLVM_VERSION=$LLVM_VERSION -t bpftrace-builder-$BASE-llvm-$LLVM_VERSION -f docker/Dockerfile.$BASE docker/
- sudo docker run --privileged --rm -it -v $(pwd):$(pwd) -v /sys/kernel/debug:/sys/kernel/debug:rw -e STATIC_LINKING=$STATIC_LINKING -e TEST_ARGS=$TEST_ARGS bpftrace-builder-$BASE-llvm-$LLVM_VERSION $(pwd)/build-$TYPE-$BASE $TYPE -j`getconf _NPROCESSORS_ONLN`
12 changes: 11 additions & 1 deletion tests/codegen/builtin_func_wild.cpp
Expand Up @@ -4,9 +4,19 @@ namespace bpftrace {
namespace test {
namespace codegen {

using ::testing::Return;

TEST(codegen, builtin_func_wild)
{
test("tracepoint:syscalls:sys_enter_nanoslee* { @x = func }",
std::set<std::string> wildcard_matches = {
"sys_enter_nanosleep"
};
MockBPFtrace bpftrace;
ON_CALL(bpftrace, find_wildcard_matches(_, _, _))
.WillByDefault(Return(wildcard_matches));

test(bpftrace,
"tracepoint:syscalls:sys_enter_nanoslee* { @x = func }",

R"EXPECTED(; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
Expand Down
12 changes: 11 additions & 1 deletion tests/codegen/builtin_probe_wild.cpp
Expand Up @@ -4,9 +4,19 @@ namespace bpftrace {
namespace test {
namespace codegen {

using ::testing::Return;

TEST(codegen, builtin_probe_wild)
{
test("tracepoint:syscalls:sys_enter_nanoslee* { @x = probe }",
std::set<std::string> wildcard_matches = {
"sys_enter_nanosleep"
};
MockBPFtrace bpftrace;
ON_CALL(bpftrace, find_wildcard_matches(_, _, _))
.WillByDefault(Return(wildcard_matches));

test(bpftrace,
"tracepoint:syscalls:sys_enter_nanoslee* { @x = probe }",

R"EXPECTED(; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
Expand Down
64 changes: 63 additions & 1 deletion tests/codegen/call_ntop_char16.cpp
Expand Up @@ -70,7 +70,7 @@ declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
)EXPECTED");
#else
#elif LLVM_VERSION_MAJOR == 6
R"EXPECTED(; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
Expand Down Expand Up @@ -129,6 +129,68 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture r
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
)EXPECTED");
#else
R"EXPECTED(; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
define i64 @"kprobe:f"(i8* nocapture readnone) local_unnamed_addr section "s_kprobe:f_1" {
entry:
%"@x_val" = alloca i64, align 8
%inet2 = alloca [20 x i8], align 4
%"@x_key1" = alloca [20 x i8], align 1
%inet = alloca [20 x i8], align 4
%"@x_key" = alloca [20 x i8], align 1
%1 = getelementptr inbounds [20 x i8], [20 x i8]* %"@x_key", i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
%2 = getelementptr inbounds [20 x i8], [20 x i8]* %inet, i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %2)
store i32 10, [20 x i8]* %inet, align 4
%3 = getelementptr inbounds [20 x i8], [20 x i8]* %inet, i64 0, i64 4
%probe_read = call i64 inttoptr (i64 4 to i64 (i8*, i64, i8*)*)(i8* %3, i64 16, i64 0)
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %1, i8* nonnull %2, i64 20, i32 1, i1 false)
%pseudo = call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%lookup_elem = call i8* inttoptr (i64 1 to i8* (i8*, i8*)*)(i64 %pseudo, [20 x i8]* nonnull %"@x_key")
%map_lookup_cond = icmp eq i8* %lookup_elem, null
br i1 %map_lookup_cond, label %lookup_merge, label %lookup_success
lookup_success: ; preds = %entry
%4 = load i64, i8* %lookup_elem, align 8
%phitmp = add i64 %4, 1
br label %lookup_merge
lookup_merge: ; preds = %entry, %lookup_success
%lookup_elem_val.0 = phi i64 [ %phitmp, %lookup_success ], [ 1, %entry ]
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %1)
%5 = getelementptr inbounds [20 x i8], [20 x i8]* %"@x_key1", i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %5)
%6 = getelementptr inbounds [20 x i8], [20 x i8]* %inet2, i64 0, i64 0
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %6)
store i32 10, [20 x i8]* %inet2, align 4
%7 = getelementptr inbounds [20 x i8], [20 x i8]* %inet2, i64 0, i64 4
%probe_read3 = call i64 inttoptr (i64 4 to i64 (i8*, i64, i8*)*)(i8* %7, i64 16, i64 0)
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %5, i8* nonnull %6, i64 20, i32 1, i1 false)
%8 = bitcast i64* %"@x_val" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %8)
store i64 %lookup_elem_val.0, i64* %"@x_val", align 8
%pseudo4 = call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%update_elem = call i64 inttoptr (i64 2 to i64 (i8*, i8*, i8*, i64)*)(i64 %pseudo4, [20 x i8]* nonnull %"@x_key1", i64* nonnull %"@x_val", i64 0)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %5)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %8)
ret i64 0
}
; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #1
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
)EXPECTED");
Expand Down
69 changes: 68 additions & 1 deletion tests/codegen/call_ntop_char4.cpp
Expand Up @@ -8,7 +8,8 @@ TEST(codegen, call_ntop_char4)
{
test("struct inet { unsigned char addr[4] } kprobe:f { @x[ntop(((inet*)0)->addr)]++}",

R"EXPECTED(; Function Attrs: nounwind
#if LLVM_VERSION_MAJOR > 5
R"EXPECTED(; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
; Function Attrs: argmemonly nounwind
Expand Down Expand Up @@ -72,6 +73,72 @@ declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
)EXPECTED");
#else
R"EXPECTED(; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
define i64 @"kprobe:f"(i8* nocapture readnone) local_unnamed_addr section "s_kprobe:f_1" {
entry:
%"@x_val" = alloca i64, align 8
%inet2 = alloca i64, align 8
%tmpcast7 = bitcast i64* %inet2 to [8 x i8]*
%"@x_key1" = alloca i64, align 8
%tmpcast6 = bitcast i64* %"@x_key1" to [8 x i8]*
%inet = alloca i64, align 8
%tmpcast5 = bitcast i64* %inet to [8 x i8]*
%"@x_key" = alloca i64, align 8
%tmpcast = bitcast i64* %"@x_key" to [8 x i8]*
%1 = bitcast i64* %"@x_key" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1)
%2 = bitcast i64* %inet to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %2)
store i32 2, [8 x i8]* %tmpcast5, align 8
%3 = getelementptr inbounds [8 x i8], [8 x i8]* %tmpcast5, i64 0, i64 4
%probe_read = call i64 inttoptr (i64 4 to i64 (i8*, i64, i8*)*)(i8* %3, i64 4, i64 0)
%4 = load i64, i64* %inet, align 8
store i64 %4, i64* %"@x_key", align 8
%pseudo = call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%lookup_elem = call i8* inttoptr (i64 1 to i8* (i8*, i8*)*)(i64 %pseudo, [8 x i8]* nonnull %tmpcast)
%map_lookup_cond = icmp eq i8* %lookup_elem, null
br i1 %map_lookup_cond, label %lookup_merge, label %lookup_success
lookup_success: ; preds = %entry
%5 = load i64, i8* %lookup_elem, align 8
%phitmp = add i64 %5, 1
br label %lookup_merge
lookup_merge: ; preds = %entry, %lookup_success
%lookup_elem_val.0 = phi i64 [ %phitmp, %lookup_success ], [ 1, %entry ]
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %1)
%6 = bitcast i64* %"@x_key1" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %6)
%7 = bitcast i64* %inet2 to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %7)
store i32 2, [8 x i8]* %tmpcast7, align 8
%8 = getelementptr inbounds [8 x i8], [8 x i8]* %tmpcast7, i64 0, i64 4
%probe_read3 = call i64 inttoptr (i64 4 to i64 (i8*, i64, i8*)*)(i8* %8, i64 4, i64 0)
%9 = load i64, i64* %inet2, align 8
store i64 %9, i64* %"@x_key1", align 8
%10 = bitcast i64* %"@x_val" to i8*
call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %10)
store i64 %lookup_elem_val.0, i64* %"@x_val", align 8
%pseudo4 = call i64 @llvm.bpf.pseudo(i64 1, i64 1)
%update_elem = call i64 inttoptr (i64 2 to i64 (i8*, i8*, i8*, i64)*)(i64 %pseudo4, [8 x i8]* nonnull %tmpcast6, i64* nonnull %"@x_val", i64 0)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %6)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %10)
ret i64 0
}
; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
attributes #0 = { nounwind }
attributes #1 = { argmemonly nounwind }
)EXPECTED");
#endif
}

} // namespace codegen
Expand Down
16 changes: 12 additions & 4 deletions tests/codegen/common.h
Expand Up @@ -22,12 +22,10 @@ target triple = "bpf-pc-linux"
)HEAD";

static void test(
BPFtrace &bpftrace,
const std::string &input,
const std::string expected_output,
bool safe_mode = true)
const std::string &expected_output)
{
BPFtrace bpftrace;
bpftrace.safe_mode = safe_mode;
Driver driver(bpftrace);
FakeMap::next_mapfd_ = 1;

Expand All @@ -50,6 +48,16 @@ static void test(
EXPECT_EQ(full_expected_output, out.str());
}

static void test(
const std::string &input,
const std::string &expected_output,
bool safe_mode = true)
{
BPFtrace bpftrace;
bpftrace.safe_mode = safe_mode;
test(bpftrace, input, expected_output);
}

} // namespace codegen
} // namespace test
} // namespace bpftrace
4 changes: 4 additions & 0 deletions tests/codegen/general.cpp
Expand Up @@ -17,6 +17,10 @@ using ::testing::_;
class MockBPFtrace : public BPFtrace {
public:
MOCK_METHOD1(add_probe, int(ast::Probe &p));
MOCK_METHOD3(find_wildcard_matches, std::set<std::string>(
const std::string &prefix,
const std::string &func,
const std::string &file_name));
};

TEST(codegen, populate_sections)
Expand Down

0 comments on commit 938e79b

Please sign in to comment.