• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/trace_processor/importers/syscalls/syscall_tracker.h"
18 
19 #include "src/trace_processor/importers/common/slice_tracker.h"
20 #include "test/gtest_and_gmock.h"
21 
22 namespace perfetto {
23 namespace trace_processor {
24 namespace {
25 
26 using ::testing::_;
27 using ::testing::DoAll;
28 using ::testing::Return;
29 using ::testing::SaveArg;
30 
31 class MockSliceTracker : public SliceTracker {
32  public:
MockSliceTracker(TraceProcessorContext * context)33   MockSliceTracker(TraceProcessorContext* context) : SliceTracker(context) {}
34   ~MockSliceTracker() override = default;
35 
36   MOCK_METHOD(std::optional<SliceId>,
37               Begin,
38               (int64_t timestamp,
39                TrackId track_id,
40                StringId cat,
41                StringId name,
42                SetArgsCallback args_callback),
43               (override));
44   MOCK_METHOD(std::optional<SliceId>,
45               End,
46               (int64_t timestamp,
47                TrackId track_id,
48                StringId cat,
49                StringId name,
50                SetArgsCallback args_callback),
51               (override));
52   MOCK_METHOD(std::optional<SliceId>,
53               Scoped,
54               (int64_t timestamp,
55                TrackId track_id,
56                StringId cat,
57                StringId name,
58                int64_t duration,
59                SetArgsCallback args_callback),
60               (override));
61 };
62 
63 class SyscallTrackerTest : public ::testing::Test {
64  public:
SyscallTrackerTest()65   SyscallTrackerTest() {
66     context.storage.reset(new TraceStorage());
67     track_tracker = new TrackTracker(&context);
68     context.track_tracker.reset(track_tracker);
69     slice_tracker = new MockSliceTracker(&context);
70     context.slice_tracker.reset(slice_tracker);
71   }
72 
73  protected:
74   TraceProcessorContext context;
75   MockSliceTracker* slice_tracker;
76   TrackTracker* track_tracker;
77 };
78 
TEST_F(SyscallTrackerTest,ReportUnknownSyscalls)79 TEST_F(SyscallTrackerTest, ReportUnknownSyscalls) {
80   constexpr TrackId track{0u};
81   StringId begin_name = kNullStringId;
82   StringId end_name = kNullStringId;
83   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
84       .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
85   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
86       .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
87 
88   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
89   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 57 /*sys_read*/);
90   syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 57 /*sys_read*/);
91   EXPECT_EQ(context.storage->GetString(begin_name), "sys_57");
92   EXPECT_EQ(context.storage->GetString(end_name), "sys_57");
93 }
94 
TEST_F(SyscallTrackerTest,ReportSysreturn)95 TEST_F(SyscallTrackerTest, ReportSysreturn) {
96   EXPECT_CALL(*slice_tracker, Scoped(_, _, _, _, _, _)).Times(1);
97 
98   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
99   syscall_tracker->SetArchitecture(Architecture::kArm64);
100   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 139);
101 }
102 
TEST_F(SyscallTrackerTest,Arm64)103 TEST_F(SyscallTrackerTest, Arm64) {
104   constexpr TrackId track{0u};
105   StringId begin_name = kNullStringId;
106   StringId end_name = kNullStringId;
107   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
108       .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
109   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
110       .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
111 
112   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
113   syscall_tracker->SetArchitecture(Architecture::kArm64);
114   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 63 /*sys_read*/);
115   syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 63 /*sys_read*/);
116   EXPECT_EQ(context.storage->GetString(begin_name), "sys_read");
117   EXPECT_EQ(context.storage->GetString(end_name), "sys_read");
118 }
119 
TEST_F(SyscallTrackerTest,x8664)120 TEST_F(SyscallTrackerTest, x8664) {
121   constexpr TrackId track{0u};
122   StringId begin_name = kNullStringId;
123   StringId end_name = kNullStringId;
124   EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
125       .WillOnce(DoAll(SaveArg<3>(&begin_name), Return(std::nullopt)));
126   EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
127       .WillOnce(DoAll(SaveArg<3>(&end_name), Return(std::nullopt)));
128 
129   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
130   syscall_tracker->SetArchitecture(Architecture::kX86_64);
131   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 0 /*sys_read*/);
132   syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 0 /*sys_read*/);
133   EXPECT_EQ(context.storage->GetString(begin_name), "sys_read");
134   EXPECT_EQ(context.storage->GetString(end_name), "sys_read");
135 }
136 
TEST_F(SyscallTrackerTest,SyscallNumberTooLarge)137 TEST_F(SyscallTrackerTest, SyscallNumberTooLarge) {
138   EXPECT_CALL(*slice_tracker, Begin(_, _, _, _, _)).Times(0);
139   EXPECT_CALL(*slice_tracker, End(_, _, _, _, _)).Times(0);
140 
141   SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(&context);
142   syscall_tracker->SetArchitecture(Architecture::kArm64);
143   syscall_tracker->Enter(100 /*ts*/, 42 /*utid*/, 9999);
144   syscall_tracker->Exit(110 /*ts*/, 42 /*utid*/, 9999);
145 }
146 
147 }  // namespace
148 }  // namespace trace_processor
149 }  // namespace perfetto
150