1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker *
4*288bf522SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker *
8*288bf522SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker *
10*288bf522SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker */
16*288bf522SAndroid Build Coastguard Worker
17*288bf522SAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*288bf522SAndroid Build Coastguard Worker
19*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
20*288bf522SAndroid Build Coastguard Worker
21*288bf522SAndroid Build Coastguard Worker #include <memory>
22*288bf522SAndroid Build Coastguard Worker #include <string>
23*288bf522SAndroid Build Coastguard Worker #include <vector>
24*288bf522SAndroid Build Coastguard Worker
25*288bf522SAndroid Build Coastguard Worker #include <android-base/file.h>
26*288bf522SAndroid Build Coastguard Worker
27*288bf522SAndroid Build Coastguard Worker #include "command.h"
28*288bf522SAndroid Build Coastguard Worker #include "get_test_data.h"
29*288bf522SAndroid Build Coastguard Worker #include "record_file.h"
30*288bf522SAndroid Build Coastguard Worker #include "test_util.h"
31*288bf522SAndroid Build Coastguard Worker
32*288bf522SAndroid Build Coastguard Worker using namespace simpleperf;
33*288bf522SAndroid Build Coastguard Worker
DebugUnwindCmd()34*288bf522SAndroid Build Coastguard Worker static std::unique_ptr<Command> DebugUnwindCmd() {
35*288bf522SAndroid Build Coastguard Worker return CreateCommandInstance("debug-unwind");
36*288bf522SAndroid Build Coastguard Worker }
37*288bf522SAndroid Build Coastguard Worker
38*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,unwind_sample_option)39*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, unwind_sample_option) {
40*288bf522SAndroid Build Coastguard Worker std::string input_data = GetTestData(PERF_DATA_NO_UNWIND);
41*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
42*288bf522SAndroid Build Coastguard Worker
43*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
44*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", input_data, "--unwind-sample"}));
45*288bf522SAndroid Build Coastguard Worker ASSERT_NE(capture.Finish().find("sample_time: 1516379654300997"), std::string::npos);
46*288bf522SAndroid Build Coastguard Worker }
47*288bf522SAndroid Build Coastguard Worker
48*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,sample_time_option)49*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, sample_time_option) {
50*288bf522SAndroid Build Coastguard Worker std::string input_data = GetTestData(PERF_DATA_NO_UNWIND);
51*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
52*288bf522SAndroid Build Coastguard Worker
53*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
54*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", input_data, "--unwind-sample", "--sample-time",
55*288bf522SAndroid Build Coastguard Worker "1516379654300997", "--sample-time",
56*288bf522SAndroid Build Coastguard Worker "1516379654363914,1516379655959122"}));
57*288bf522SAndroid Build Coastguard Worker std::string output = capture.Finish();
58*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("sample_time: 1516379654300997"), std::string::npos);
59*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("sample_time: 1516379654363914"), std::string::npos);
60*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("sample_time: 1516379655959122"), std::string::npos);
61*288bf522SAndroid Build Coastguard Worker }
62*288bf522SAndroid Build Coastguard Worker
63*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,output_option)64*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, output_option) {
65*288bf522SAndroid Build Coastguard Worker std::string input_data = GetTestData(PERF_DATA_NO_UNWIND);
66*288bf522SAndroid Build Coastguard Worker TemporaryFile tmpfile;
67*288bf522SAndroid Build Coastguard Worker close(tmpfile.release());
68*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", input_data, "--unwind-sample", "--sample-time",
69*288bf522SAndroid Build Coastguard Worker "1516379654300997", "-o", tmpfile.path}));
70*288bf522SAndroid Build Coastguard Worker std::string output;
71*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tmpfile.path, &output));
72*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("sample_time: 1516379654300997"), std::string::npos);
73*288bf522SAndroid Build Coastguard Worker }
74*288bf522SAndroid Build Coastguard Worker
75*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,symfs_option)76*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, symfs_option) {
77*288bf522SAndroid Build Coastguard Worker std::string input_data = GetTestData(NATIVELIB_IN_APK_PERF_DATA);
78*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
79*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
80*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", input_data, "--symfs", GetTestDataDir(),
81*288bf522SAndroid Build Coastguard Worker "--unwind-sample", "--sample-time", "500329355223"}));
82*288bf522SAndroid Build Coastguard Worker ASSERT_NE(capture.Finish().find(
83*288bf522SAndroid Build Coastguard Worker "dso_4: /data/app/com.example.hellojni-1/base.apk!/lib/arm64-v8a/libhello-jni.so"),
84*288bf522SAndroid Build Coastguard Worker std::string::npos);
85*288bf522SAndroid Build Coastguard Worker }
86*288bf522SAndroid Build Coastguard Worker
87*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,unwind_with_ip_zero_in_callchain)88*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, unwind_with_ip_zero_in_callchain) {
89*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
90*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
91*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", GetTestData(PERF_DATA_WITH_IP_ZERO_IN_CALLCHAIN),
92*288bf522SAndroid Build Coastguard Worker "--unwind-sample", "--sample-time", "152526249937103"}));
93*288bf522SAndroid Build Coastguard Worker ASSERT_NE(capture.Finish().find("sample_time: 152526249937103"), std::string::npos);
94*288bf522SAndroid Build Coastguard Worker }
95*288bf522SAndroid Build Coastguard Worker
96*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,unwind_embedded_lib_in_apk)97*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, unwind_embedded_lib_in_apk) {
98*288bf522SAndroid Build Coastguard Worker // Check if we can unwind through a native library embedded in an apk. In the profiling data
99*288bf522SAndroid Build Coastguard Worker // file, there is a sample with ip address pointing to
100*288bf522SAndroid Build Coastguard Worker // /data/app/simpleperf.demo.cpp_api/base.apk!/lib/arm64-v8a/libnative-lib.so.
101*288bf522SAndroid Build Coastguard Worker // If unwound successfully, it can reach a function in libc.so.
102*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
103*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
104*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", GetTestData("perf_unwind_embedded_lib_in_apk.data"),
105*288bf522SAndroid Build Coastguard Worker "--symfs", GetTestDataDir(), "--unwind-sample",
106*288bf522SAndroid Build Coastguard Worker "--sample-time", "20345907755421"}));
107*288bf522SAndroid Build Coastguard Worker std::string output = capture.Finish();
108*288bf522SAndroid Build Coastguard Worker ASSERT_NE(
109*288bf522SAndroid Build Coastguard Worker output.find(
110*288bf522SAndroid Build Coastguard Worker "dso_1: /data/app/simpleperf.demo.cpp_api/base.apk!/lib/arm64-v8a/libnative-lib.so"),
111*288bf522SAndroid Build Coastguard Worker std::string::npos)
112*288bf522SAndroid Build Coastguard Worker << output;
113*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("dso_2: /bionic/lib64/libc.so"), std::string::npos) << output;
114*288bf522SAndroid Build Coastguard Worker }
115*288bf522SAndroid Build Coastguard Worker
116*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,unwind_sample_in_unwinding_debug_info_file)117*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, unwind_sample_in_unwinding_debug_info_file) {
118*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
119*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
120*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run(
121*288bf522SAndroid Build Coastguard Worker {"-i", GetTestData("perf_with_failed_unwinding_debug_info.data"), "--unwind-sample"}));
122*288bf522SAndroid Build Coastguard Worker std::string output = capture.Finish();
123*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("symbol_5: android.os.Handler.post"), std::string::npos) << output;
124*288bf522SAndroid Build Coastguard Worker }
125*288bf522SAndroid Build Coastguard Worker
126*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,skip_sample_print_option)127*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, skip_sample_print_option) {
128*288bf522SAndroid Build Coastguard Worker std::string input_data = GetTestData(PERF_DATA_NO_UNWIND);
129*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
130*288bf522SAndroid Build Coastguard Worker
131*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
132*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", input_data, "--unwind-sample", "--skip-sample-print"}));
133*288bf522SAndroid Build Coastguard Worker
134*288bf522SAndroid Build Coastguard Worker std::string output = capture.Finish();
135*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(output.find("sample_time:"), std::string::npos);
136*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("unwinding_sample_count: 8"), std::string::npos);
137*288bf522SAndroid Build Coastguard Worker }
138*288bf522SAndroid Build Coastguard Worker
139*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,generate_test_file)140*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, generate_test_file) {
141*288bf522SAndroid Build Coastguard Worker TemporaryFile tmpfile;
142*288bf522SAndroid Build Coastguard Worker close(tmpfile.release());
143*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run(
144*288bf522SAndroid Build Coastguard Worker {"-i", GetTestData("perf_with_failed_unwinding_debug_info.data"), "--generate-test-file",
145*288bf522SAndroid Build Coastguard Worker "--sample-time", "626968783364202", "-o", tmpfile.path, "--keep-binaries-in-test-file",
146*288bf522SAndroid Build Coastguard Worker "perf.data_jit_app_cache:255984-259968,perf.data_jit_app_cache:280144-283632"}));
147*288bf522SAndroid Build Coastguard Worker
148*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
149*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
150*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", tmpfile.path, "--unwind-sample"}));
151*288bf522SAndroid Build Coastguard Worker std::string output = capture.Finish();
152*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("symbol_2: android.os.Handler.enqueueMessage"), std::string::npos);
153*288bf522SAndroid Build Coastguard Worker }
154*288bf522SAndroid Build Coastguard Worker
155*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,generate_test_file_with_build_id)156*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, generate_test_file_with_build_id) {
157*288bf522SAndroid Build Coastguard Worker TemporaryFile tmpfile;
158*288bf522SAndroid Build Coastguard Worker close(tmpfile.release());
159*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run({"-i", GetTestData("perf_display_bitmaps.data"),
160*288bf522SAndroid Build Coastguard Worker "--generate-test-file", "--sample-time", "684943450156904",
161*288bf522SAndroid Build Coastguard Worker "-o", tmpfile.path, "--keep-binaries-in-test-file",
162*288bf522SAndroid Build Coastguard Worker "/apex/com.android.runtime/lib64/bionic/libc.so"}));
163*288bf522SAndroid Build Coastguard Worker auto reader = RecordFileReader::CreateInstance(tmpfile.path);
164*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(reader);
165*288bf522SAndroid Build Coastguard Worker auto build_ids = reader->ReadBuildIdFeature();
166*288bf522SAndroid Build Coastguard Worker ASSERT_EQ(build_ids.size(), 1);
167*288bf522SAndroid Build Coastguard Worker ASSERT_STREQ(build_ids[0].filename, "/apex/com.android.runtime/lib64/bionic/libc.so");
168*288bf522SAndroid Build Coastguard Worker }
169*288bf522SAndroid Build Coastguard Worker
170*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,generate_report)171*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, generate_report) {
172*288bf522SAndroid Build Coastguard Worker TemporaryFile tmpfile;
173*288bf522SAndroid Build Coastguard Worker close(tmpfile.release());
174*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(
175*288bf522SAndroid Build Coastguard Worker DebugUnwindCmd()->Run({"-i", GetTestData("perf_with_failed_unwinding_debug_info.data"),
176*288bf522SAndroid Build Coastguard Worker "--generate-report", "-o", tmpfile.path}));
177*288bf522SAndroid Build Coastguard Worker std::string output;
178*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::ReadFileToString(tmpfile.path, &output));
179*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("unwinding_error_code: 4"), std::string::npos);
180*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("symbol_2: android.os.Handler.enqueueMessage"), std::string::npos);
181*288bf522SAndroid Build Coastguard Worker }
182*288bf522SAndroid Build Coastguard Worker
183*288bf522SAndroid Build Coastguard Worker // @CddTest = 6.1/C-0-2
TEST(cmd_debug_unwind,unwind_sample_for_small_map_range)184*288bf522SAndroid Build Coastguard Worker TEST(cmd_debug_unwind, unwind_sample_for_small_map_range) {
185*288bf522SAndroid Build Coastguard Worker CaptureStdout capture;
186*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(capture.Start());
187*288bf522SAndroid Build Coastguard Worker ASSERT_TRUE(DebugUnwindCmd()->Run(
188*288bf522SAndroid Build Coastguard Worker {"-i", GetTestData("debug_unwind_small_map_range.data"), "--unwind-sample"}));
189*288bf522SAndroid Build Coastguard Worker std::string output = capture.Finish();
190*288bf522SAndroid Build Coastguard Worker ASSERT_NE(output.find("dso_3: /apex/com.android.art/lib64/libart.so"), std::string::npos)
191*288bf522SAndroid Build Coastguard Worker << output;
192*288bf522SAndroid Build Coastguard Worker }
193