• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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/ftrace/binder_tracker.h"
18 
19 #include <cstdint>
20 #include <optional>
21 
22 #include "src/trace_processor/importers/common/args_tracker.h"
23 #include "src/trace_processor/importers/common/args_translation_table.h"
24 #include "src/trace_processor/importers/common/event_tracker.h"
25 #include "src/trace_processor/importers/common/flow_tracker.h"
26 #include "src/trace_processor/importers/common/global_args_tracker.h"
27 #include "src/trace_processor/importers/common/process_tracker.h"
28 #include "src/trace_processor/importers/common/slice_tracker.h"
29 #include "src/trace_processor/importers/common/slice_translation_table.h"
30 #include "src/trace_processor/importers/common/track_tracker.h"
31 #include "src/trace_processor/storage/trace_storage.h"
32 #include "test/gtest_and_gmock.h"
33 
34 namespace perfetto::trace_processor {
35 namespace {
36 constexpr int kOneWay = 0x01;
37 
38 class BinderTrackerTest : public ::testing::Test {
39  public:
BinderTrackerTest()40   BinderTrackerTest() {
41     context.storage.reset(new TraceStorage());
42     context.global_args_tracker.reset(
43         new GlobalArgsTracker(context.storage.get()));
44     context.args_tracker.reset(new ArgsTracker(&context));
45     context.args_translation_table.reset(
46         new ArgsTranslationTable(context.storage.get()));
47     context.slice_tracker.reset(new SliceTracker(&context));
48     context.slice_translation_table.reset(
49         new SliceTranslationTable(context.storage.get()));
50     context.process_tracker.reset(new ProcessTracker(&context));
51     context.track_tracker.reset(new TrackTracker(&context));
52     context.flow_tracker.reset(new FlowTracker(&context));
53     binder_tracker = BinderTracker::GetOrCreate(&context);
54   }
55 
TidForSlice(uint32_t row) const56   uint32_t TidForSlice(uint32_t row) const {
57     const auto& thread = context.storage->thread_table();
58     const auto& track = context.storage->track_table();
59     const auto& slice = context.storage->slice_table();
60     auto rr = track.FindById(slice[row].track_id());
61     return thread[*rr->utid()].tid();
62   }
63 
64  protected:
65   TraceProcessorContext context;
66   BinderTracker* binder_tracker;
67 };
68 
TEST_F(BinderTrackerTest,RequestReply)69 TEST_F(BinderTrackerTest, RequestReply) {
70   int64_t req_ts = 100;
71   int64_t req_recv_ts = 105;
72   int64_t rep_ts = 150;
73   int64_t rep_recv_ts = 155;
74 
75   uint32_t req_tid = 5;
76   uint32_t rep_tid = 10;
77 
78   int32_t req_transaction_id = 1234;
79   int32_t rep_transaction_id = 5678;
80 
81   binder_tracker->Transaction(req_ts, req_tid, req_transaction_id, 9, rep_tid,
82                               rep_tid, false, 0, kNullStringId);
83   binder_tracker->TransactionReceived(req_recv_ts, rep_tid, req_transaction_id);
84 
85   binder_tracker->Transaction(rep_ts, rep_tid, rep_transaction_id, 99, req_tid,
86                               req_tid, true, 0, kNullStringId);
87   binder_tracker->TransactionReceived(rep_recv_ts, req_tid, rep_transaction_id);
88 
89   const auto& slice = context.storage->slice_table();
90   const auto& flow = context.storage->flow_table();
91   ASSERT_EQ(slice.row_count(), 2u);
92 
93   ASSERT_EQ(slice[0].ts(), req_ts);
94   ASSERT_EQ(slice[0].dur(), rep_recv_ts - req_ts);
95   ASSERT_EQ(TidForSlice(0), req_tid);
96 
97   ASSERT_EQ(slice[1].ts(), req_recv_ts);
98   ASSERT_EQ(slice[1].dur(), rep_ts - req_recv_ts);
99   ASSERT_EQ(TidForSlice(1), rep_tid);
100 
101   ASSERT_EQ(flow.row_count(), 1u);
102   ASSERT_EQ(flow[0].slice_out(), slice[0].id());
103   ASSERT_EQ(flow[0].slice_in(), slice[1].id());
104 
105   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
106 }
107 
TEST_F(BinderTrackerTest,Oneway)108 TEST_F(BinderTrackerTest, Oneway) {
109   int64_t sen_ts = 100;
110   int64_t rec_ts = 150;
111 
112   uint32_t sen_tid = 5;
113   uint32_t rec_tid = 10;
114 
115   int32_t transaction_id = 1234;
116 
117   binder_tracker->Transaction(sen_ts, sen_tid, transaction_id, 9, rec_tid,
118                               rec_tid, false, kOneWay, kNullStringId);
119   binder_tracker->TransactionReceived(rec_ts, rec_tid, transaction_id);
120 
121   const auto& slice = context.storage->slice_table();
122   const auto& flow = context.storage->flow_table();
123   ASSERT_EQ(slice.row_count(), 2u);
124 
125   ASSERT_EQ(slice[0].ts(), sen_ts);
126   ASSERT_EQ(slice[0].dur(), 0);
127   ASSERT_EQ(TidForSlice(0), sen_tid);
128 
129   ASSERT_EQ(slice[1].ts(), rec_ts);
130   ASSERT_EQ(slice[1].dur(), 0);
131   ASSERT_EQ(TidForSlice(1), rec_tid);
132 
133   ASSERT_EQ(flow.row_count(), 1u);
134   ASSERT_EQ(flow[0].slice_out(), slice[0].id());
135   ASSERT_EQ(flow[0].slice_in(), slice[1].id());
136 
137   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
138 }
139 
TEST_F(BinderTrackerTest,RequestReplyWithCommands)140 TEST_F(BinderTrackerTest, RequestReplyWithCommands) {
141   constexpr uint32_t kSndTid = 5;
142   constexpr uint32_t kRcvTid = 10;
143 
144   constexpr int32_t kTransactionId = 1234;
145   constexpr int32_t kReplyTransactionId = 5678;
146 
147   int64_t ts = 1;
148   binder_tracker->CommandToKernel(ts++, kSndTid,
149                                   BinderTracker::kBC_TRANSACTION);
150   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
151                               kRcvTid, false, 0, kNullStringId);
152   binder_tracker->TransactionReceived(ts++, kRcvTid, kTransactionId);
153   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
154                                    BinderTracker::kBR_TRANSACTION);
155   binder_tracker->CommandToKernel(ts++, kRcvTid, BinderTracker::kBC_REPLY);
156   binder_tracker->Transaction(ts++, kRcvTid, kReplyTransactionId, 99, kSndTid,
157                               kSndTid, true, 0, kNullStringId);
158   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
159                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
160   binder_tracker->ReturnFromKernel(ts++, kSndTid,
161                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
162   binder_tracker->TransactionReceived(ts++, kSndTid, kReplyTransactionId);
163   binder_tracker->ReturnFromKernel(ts++, kSndTid, BinderTracker::kBR_REPLY);
164 
165   const auto& slice = context.storage->slice_table();
166   ASSERT_EQ(slice.row_count(), 2u);
167   EXPECT_NE(slice[0].dur(), -1);
168   EXPECT_NE(slice[1].dur(), -1);
169 
170   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
171 }
172 
TEST_F(BinderTrackerTest,RequestReplyWithCommandsFailAfterBcTransaction)173 TEST_F(BinderTrackerTest, RequestReplyWithCommandsFailAfterBcTransaction) {
174   constexpr uint32_t kSndTid = 5;
175 
176   int64_t ts = 1;
177   binder_tracker->CommandToKernel(ts++, kSndTid,
178                                   BinderTracker::kBC_TRANSACTION);
179   binder_tracker->ReturnFromKernel(ts++, kSndTid,
180                                    BinderTracker::kBR_DEAD_REPLY);
181 
182   const auto& slice = context.storage->slice_table();
183   EXPECT_EQ(slice.row_count(), 0u);
184 
185   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
186 }
187 
TEST_F(BinderTrackerTest,RequestReplyWithCommandsFailAfterSendTxn)188 TEST_F(BinderTrackerTest, RequestReplyWithCommandsFailAfterSendTxn) {
189   constexpr uint32_t kSndTid = 5;
190   constexpr uint32_t kRcvTid = 10;
191 
192   constexpr int32_t kTransactionId = 1234;
193 
194   int64_t ts = 1;
195   binder_tracker->CommandToKernel(ts++, kSndTid,
196                                   BinderTracker::kBC_TRANSACTION);
197   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
198                               kRcvTid, false, 0, kNullStringId);
199   binder_tracker->ReturnFromKernel(ts++, kSndTid,
200                                    BinderTracker::kBR_FAILED_REPLY);
201 
202   const auto& slice = context.storage->slice_table();
203   ASSERT_EQ(slice.row_count(), 1u);
204   EXPECT_NE(slice[0].dur(), -1);
205 
206   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
207 }
208 
TEST_F(BinderTrackerTest,RequestReplyWithCommandsFailBeforeReplyTxn)209 TEST_F(BinderTrackerTest, RequestReplyWithCommandsFailBeforeReplyTxn) {
210   constexpr uint32_t kSndTid = 5;
211   constexpr uint32_t kRcvTid = 10;
212 
213   constexpr int32_t kTransactionId = 1234;
214 
215   int64_t ts = 1;
216   binder_tracker->CommandToKernel(ts++, kSndTid,
217                                   BinderTracker::kBC_TRANSACTION);
218   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
219                               kRcvTid, false, 0, kNullStringId);
220   binder_tracker->TransactionReceived(ts++, kRcvTid, kTransactionId);
221   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
222                                    BinderTracker::kBR_TRANSACTION);
223   binder_tracker->CommandToKernel(ts++, kRcvTid, BinderTracker::kBC_REPLY);
224   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
225                                    BinderTracker::kBR_FAILED_REPLY);
226   binder_tracker->ReturnFromKernel(ts++, kSndTid,
227                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
228   binder_tracker->ReturnFromKernel(ts++, kSndTid,
229                                    BinderTracker::kBR_FAILED_REPLY);
230 
231   const auto& slice = context.storage->slice_table();
232   ASSERT_EQ(slice.row_count(), 2u);
233   EXPECT_NE(slice[0].dur(), -1);
234   EXPECT_NE(slice[1].dur(), -1);
235 
236   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
237 }
238 
TEST_F(BinderTrackerTest,RequestReplyWithCommandsFailAfterReplyTxn)239 TEST_F(BinderTrackerTest, RequestReplyWithCommandsFailAfterReplyTxn) {
240   constexpr uint32_t kSndTid = 5;
241   constexpr uint32_t kRcvTid = 10;
242 
243   constexpr int32_t kTransactionId = 1234;
244   constexpr int32_t kReplyTransactionId = 5678;
245 
246   int64_t ts = 1;
247   binder_tracker->CommandToKernel(ts++, kSndTid,
248                                   BinderTracker::kBC_TRANSACTION);
249   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
250                               kRcvTid, false, 0, kNullStringId);
251   binder_tracker->TransactionReceived(ts++, kRcvTid, kTransactionId);
252   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
253                                    BinderTracker::kBR_TRANSACTION);
254   binder_tracker->CommandToKernel(ts++, kRcvTid, BinderTracker::kBC_REPLY);
255   binder_tracker->Transaction(ts++, kRcvTid, kReplyTransactionId, 99, kSndTid,
256                               kSndTid, true, 0, kNullStringId);
257   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
258                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
259   binder_tracker->ReturnFromKernel(ts++, kSndTid,
260                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
261   binder_tracker->ReturnFromKernel(ts++, kSndTid,
262                                    BinderTracker::kBR_FAILED_REPLY);
263 
264   const auto& slice = context.storage->slice_table();
265   ASSERT_EQ(slice.row_count(), 2u);
266   EXPECT_NE(slice[0].dur(), -1);
267   EXPECT_NE(slice[1].dur(), -1);
268 
269   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
270 }
271 
TEST_F(BinderTrackerTest,OneWayWithCommands)272 TEST_F(BinderTrackerTest, OneWayWithCommands) {
273   constexpr uint32_t kSndTid = 5;
274   constexpr uint32_t kRcvTid = 10;
275 
276   constexpr int32_t kTransactionId = 1234;
277 
278   int64_t ts = 1;
279   binder_tracker->CommandToKernel(ts++, kSndTid,
280                                   BinderTracker::kBC_TRANSACTION);
281   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
282                               kRcvTid, false, kOneWay, kNullStringId);
283   binder_tracker->ReturnFromKernel(ts++, kSndTid,
284                                    BinderTracker::kBR_TRANSACTION_COMPLETE);
285   binder_tracker->TransactionReceived(ts++, kRcvTid, kTransactionId);
286   binder_tracker->ReturnFromKernel(ts++, kRcvTid,
287                                    BinderTracker::kBR_TRANSACTION);
288 
289   const auto& slice = context.storage->slice_table();
290   ASSERT_EQ(slice.row_count(), 2u);
291   EXPECT_EQ(slice[0].dur(), 0);
292   EXPECT_EQ(slice[1].dur(), 0);
293 
294   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
295 }
296 
TEST_F(BinderTrackerTest,OneWayWithCommandsFailBeforeTxn)297 TEST_F(BinderTrackerTest, OneWayWithCommandsFailBeforeTxn) {
298   constexpr uint32_t kSndTid = 5;
299 
300   int64_t ts = 1;
301   binder_tracker->CommandToKernel(ts++, kSndTid,
302                                   BinderTracker::kBC_TRANSACTION);
303   binder_tracker->ReturnFromKernel(ts++, kSndTid,
304                                    BinderTracker::kBR_FAILED_REPLY);
305 
306   const auto& slice = context.storage->slice_table();
307   EXPECT_EQ(slice.row_count(), 0u);
308 
309   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
310 }
311 
TEST_F(BinderTrackerTest,OneWayWithCommandsFailAfterTxn)312 TEST_F(BinderTrackerTest, OneWayWithCommandsFailAfterTxn) {
313   constexpr uint32_t kSndTid = 5;
314   constexpr uint32_t kRcvTid = 10;
315 
316   constexpr int32_t kTransactionId = 1234;
317 
318   int64_t ts = 1;
319   binder_tracker->CommandToKernel(ts++, kSndTid,
320                                   BinderTracker::kBC_TRANSACTION);
321   binder_tracker->Transaction(ts++, kSndTid, kTransactionId, 9, kRcvTid,
322                               kRcvTid, false, kOneWay, kNullStringId);
323   binder_tracker->ReturnFromKernel(ts++, kSndTid,
324                                    BinderTracker::kBR_FAILED_REPLY);
325 
326   const auto& slice = context.storage->slice_table();
327   ASSERT_EQ(slice.row_count(), 1u);
328   EXPECT_EQ(slice[0].dur(), 0);
329 
330   EXPECT_TRUE(binder_tracker->utid_stacks_empty());
331 }
332 
333 }  // namespace
334 }  // namespace perfetto::trace_processor
335