File: general.cpp

package info (click to toggle)
bpftrace 0.24.1-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,496 kB
  • sloc: cpp: 60,982; ansic: 10,952; python: 953; yacc: 665; sh: 536; lex: 295; makefile: 22
file content (122 lines) | stat: -rw-r--r-- 3,422 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "ast/ast.h"
#include "ast/context.h"
#include "common.h"

namespace bpftrace::test::codegen {

using ::testing::_;

class MockBPFtrace : public BPFtrace {
public:
#pragma GCC diagnostic push
#ifdef __clang__
#pragma GCC diagnostic ignored "-Winconsistent-missing-override"
#endif
  MOCK_METHOD5(add_probe,
               int(const ast::AttachPoint &,
                   const ast::Probe &,
                   ast::ExpansionType,
                   std::set<std::string>,
                   int));
#pragma GCC diagnostic pop

  int resolve_uname(const std::string &name,
                    struct symbol *sym,
                    const std::string &path) const override
  {
    (void)path;
    sym->name = name;
    sym->address = 12345;
    sym->size = 4;
    return 0;
  }

  bool is_traceable_func(
      const std::string &__attribute__((unused)) /*func_name*/) const override
  {
    return true;
  }

  bool has_kprobe_multi()
  {
    return feature_->has_kprobe_multi();
  }
};

TEST(codegen, printf_offsets)
{
  ast::ASTContext ast("stdin", R"(
struct Foo { char c; int i; char str[10]; }
kprobe:f
{
  $foo = (struct Foo*)arg0;
  printf("%c %u %s %p\n", $foo->c, $foo->i, $foo->str, 0)
})");
  auto bpftrace = get_mock_bpftrace();
  auto ok = ast::PassManager()
                .put(ast)
                .put<BPFtrace>(*bpftrace)
                .add(ast::AllParsePasses())
                .add(ast::CreateLLVMInitPass())
                .add(ast::CreateClangBuildPass())
                .add(ast::CreateTypeSystemPass())
                .add(ast::CreateSemanticPass())
                .add(ast::CreateResourcePass())
                .add(ast::AllCompilePasses())
                .run();
  ASSERT_TRUE(ok && ast.diagnostics().ok());

  EXPECT_EQ(bpftrace->resources.printf_args.size(), 1U);
  auto fmt = std::get<0>(bpftrace->resources.printf_args[0]).str();
  auto &args = std::get<1>(bpftrace->resources.printf_args[0]);

  EXPECT_EQ(fmt, "%c %u %s %p\n");

  EXPECT_EQ(args.size(), 4U);

  EXPECT_TRUE(args[0].type.IsIntTy());
  EXPECT_EQ(args[0].type.GetSize(), 1U);
  EXPECT_EQ(args[0].offset, 0);

  EXPECT_TRUE(args[1].type.IsIntTy());
  EXPECT_EQ(args[1].type.GetSize(), 4U);
  EXPECT_EQ(args[1].offset, 4);

  // Note that the string type has size + 1 in order to signal well-formedness.
  // See clang_parser.cpp for this logic.
  EXPECT_TRUE(args[2].type.IsStringTy());
  EXPECT_EQ(args[2].type.GetSize(), 10U + 1U);
  EXPECT_EQ(args[2].offset, 8);

  EXPECT_TRUE(args[3].type.IsIntTy());
  EXPECT_EQ(args[3].type.GetSize(), 8U);
  EXPECT_EQ(args[3].offset, 24);
}

TEST(codegen, probe_count)
{
  ast::ASTContext ast("stdin", R"(
kprobe:f { 1; } kprobe:d { 1; }
)");
  MockBPFtrace bpftrace;
  EXPECT_CALL(bpftrace, add_probe(_, _, _, _, _)).Times(2);

  // Override to mockbpffeature.
  bpftrace.feature_ = std::make_unique<MockBPFfeature>(true);

  auto ok = ast::PassManager()
                .put(ast)
                .put<BPFtrace>(bpftrace)
                .add(ast::AllParsePasses())
                .add(ast::CreateLLVMInitPass())
                .add(ast::CreateClangBuildPass())
                .add(ast::CreateTypeSystemPass())
                .add(ast::CreateSemanticPass())
                .add(ast::AllCompilePasses())
                .run();
  ASSERT_TRUE(ok && ast.diagnostics().ok());
}
} // namespace bpftrace::test::codegen