1 /*
2 * Copyright (C) 2021 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 <stdlib.h>
18
19 #include "test/gtest_and_gmock.h"
20
21 #include "perfetto/ext/base/file_utils.h"
22 #include "perfetto/ext/base/string_view.h"
23 #include "perfetto/ext/base/temp_file.h"
24 #include "src/profiling/symbolizer/breakpad_symbolizer.h"
25
26 namespace perfetto {
27 namespace profiling {
28
29 namespace {
30
TEST(BreakpadSymbolizerTest,NonExistantFile)31 TEST(BreakpadSymbolizerTest, NonExistantFile) {
32 const std::string kBadFilePath = "/bad/file/path";
33 constexpr char kTestDir[] = "Unused";
34 BreakpadSymbolizer symbolizer(kTestDir);
35 symbolizer.SetBreakpadFileForTesting(kBadFilePath);
36 std::vector<uint64_t> addresses = {0x1010u, 0x1040u, 0x10d0u, 0x1140u};
37 std::vector<std::vector<SymbolizedFrame>> frames =
38 symbolizer.Symbolize("mapping", "build", 0, addresses);
39 EXPECT_TRUE(frames.empty());
40 }
41
42 // To make it easy to read, each FUNC record is followed by two LINE records:
43 // one showing the start address of the ending instruction and one showing the
44 // address where the function ends.
45 constexpr char kTestFileContents[] =
46 "MODULE mac x86_64 A68BC89F12C foo.so\n"
47 "FUNC 1010 23 0 foo_foo()\n"
48 "1031 2 39 4\n"
49 "1033 0 0 0\n"
50 "FUNC 1040 84 0 bar_bar_bar()\n"
51 "10b6 e 44 5\n"
52 "10c4 0 0 0\n"
53 "FUNC 10d0 6b 0 foo::bar()\n"
54 "1136 5 44 5\n"
55 "113b 0 0 0\n"
56 "FUNC 1140 6b 0 baz()\n"
57 "114a 2 82 5\n"
58 "114c 0 0 0\n";
59 constexpr ssize_t kTestFileLength = base::ArraySize(kTestFileContents);
60
TEST(BreakpadSymbolizerTest,SymbolFrames)61 TEST(BreakpadSymbolizerTest, SymbolFrames) {
62 base::TempFile test_file = base::TempFile::Create();
63 ASSERT_TRUE(*test_file);
64 ssize_t written =
65 base::WriteAll(test_file.fd(), kTestFileContents, kTestFileLength);
66 ASSERT_EQ(written, kTestFileLength);
67 constexpr char kTestDir[] = "Unused";
68 BreakpadSymbolizer symbolizer(kTestDir);
69 symbolizer.SetBreakpadFileForTesting(test_file.path());
70 // The first 4 addresses are valid, while the last four, cannot be mapped to a
71 // function because they are either too low, too large, or not mapped in any
72 // function's range.
73 std::vector<uint64_t> addresses = {0x1010u, 0x1040u, 0x10d0u, 0x1140u,
74 0xeu, 0x1036u, 0x30d0u, 0x113eu};
75 std::vector<std::vector<SymbolizedFrame>> frames =
76 symbolizer.Symbolize("mapping", "build", 0, addresses);
77 ASSERT_EQ(frames.size(), 8u);
78 EXPECT_EQ(frames[0][0].function_name, "foo_foo()");
79 EXPECT_EQ(frames[1][0].function_name, "bar_bar_bar()");
80 EXPECT_EQ(frames[2][0].function_name, "foo::bar()");
81 EXPECT_EQ(frames[3][0].function_name, "baz()");
82 EXPECT_TRUE(frames[4][0].function_name.empty());
83 EXPECT_TRUE(frames[5][0].function_name.empty());
84 EXPECT_TRUE(frames[6][0].function_name.empty());
85 EXPECT_TRUE(frames[7][0].function_name.empty());
86 }
87
88 } // namespace
89 } // namespace profiling
90 } // namespace perfetto
91