blob: 48e038e9adbef5c63a8bbc5e096c1411833b5280 [file] [log] [blame]
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001/*
2 * Copyright (C) 2017 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 <elf.h>
18#include <stdint.h>
19#include <sys/mman.h>
20
21#include <memory>
22#include <set>
23#include <string>
24
25#include <gtest/gtest.h>
26
27#include <unwindstack/Elf.h>
28#include <unwindstack/Maps.h>
29#include <unwindstack/Memory.h>
30#include <unwindstack/Regs.h>
Christopher Ferris02fdb562017-12-08 15:04:49 -080031#include <unwindstack/RegsArm.h>
32#include <unwindstack/RegsArm64.h>
33#include <unwindstack/RegsX86.h>
34#include <unwindstack/RegsX86_64.h>
Douglas Leung61b1a1a2017-11-08 10:53:53 +010035#include <unwindstack/RegsMips.h>
36#include <unwindstack/RegsMips64.h>
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070037#include <unwindstack/Unwinder.h>
38
39#include "ElfFake.h"
40#include "MemoryFake.h"
41#include "RegsFake.h"
42
43namespace unwindstack {
44
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070045class UnwinderTest : public ::testing::Test {
46 protected:
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080047 static void AddMapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
48 const char* name, Elf* elf = nullptr) {
49 std::string str_name(name);
50 maps_->Add(start, end, offset, flags, name, static_cast<uint64_t>(-1));
51 if (elf != nullptr) {
Florian Mayer3d67d342019-02-27 18:00:37 +000052 const auto& map_info = *--maps_->end();
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080053 map_info->elf.reset(elf);
54 }
55 }
56
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070057 static void SetUpTestCase() {
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080058 maps_.reset(new Maps);
59
Christopher Ferris02fdb562017-12-08 15:04:49 -080060 ElfFake* elf = new ElfFake(new MemoryFake);
Christopher Ferris78133452019-03-14 13:44:38 -070061 ElfInterfaceFake* interface_fake = new ElfInterfaceFake(nullptr);
62 interface_fake->FakeSetBuildID("FAKE");
63 elf->FakeSetInterface(interface_fake);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080064 AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070065
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080066 AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070067
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080068 AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
69 "/dev/fake_device");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070070
Christopher Ferris02fdb562017-12-08 15:04:49 -080071 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070072 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080073 AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070074
Christopher Ferris02fdb562017-12-08 15:04:49 -080075 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070076 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080077 AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070078
Christopher Ferris02fdb562017-12-08 15:04:49 -080079 elf = new ElfFake(new MemoryFake);
Christopher Ferrise69f4702017-10-19 16:08:58 -070080 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080081 AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070082
Christopher Ferris02fdb562017-12-08 15:04:49 -080083 elf = new ElfFake(new MemoryFake);
Christopher Ferris02a6c442019-03-11 14:43:33 -070084 ElfInterfaceFake* interface = new ElfInterfaceFake(nullptr);
85 interface->FakeSetSoname("lib_fake.so");
86 elf->FakeSetInterface(interface);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080087 AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
Christopher Ferris02a6c442019-03-11 14:43:33 -070088 MapInfo* map_info = maps_->Find(0x43000);
89 ASSERT_TRUE(map_info != nullptr);
90 map_info->elf_start_offset = 0x1d000;
Christopher Ferrise69f4702017-10-19 16:08:58 -070091
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080092 AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
Christopher Ferris02fdb562017-12-08 15:04:49 -080093
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080094 AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
Florian Mayer3d67d342019-02-27 18:00:37 +000095 const auto& info = *--maps_->end();
Christopher Ferrise762f1f2018-02-06 14:51:48 -080096 info->load_bias = 0;
Christopher Ferrise762f1f2018-02-06 14:51:48 -080097
Christopher Ferrise4df5f52018-02-12 13:24:18 -080098 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -080099 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
100 elf->FakeSetLoadBias(0x5000);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800101 AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
102 elf);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800103
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800104 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800105 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800106 AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_offset.oat",
107 elf);
Florian Mayer3d67d342019-02-27 18:00:37 +0000108 const auto& info2 = *--maps_->end();
109 info2->elf_offset = 0x8000;
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800110
Christopher Ferris02fdb562017-12-08 15:04:49 -0800111 process_memory_.reset(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700112 }
113
114 void SetUp() override {
115 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800116 regs_.FakeSetArch(ARCH_ARM);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700117 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700118 }
119
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800120 static std::unique_ptr<Maps> maps_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700121 static RegsFake regs_;
122 static std::shared_ptr<Memory> process_memory_;
123};
124
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800125std::unique_ptr<Maps> UnwinderTest::maps_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700126RegsFake UnwinderTest::regs_(5);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700127std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
128
129TEST_F(UnwinderTest, multiple_frames) {
130 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
131 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
132 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
133
Yabin Cui11e96fe2018-03-14 18:16:22 -0700134 regs_.set_pc(0x1000);
135 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700136 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
137 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
138 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
139
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800140 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700141 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800142 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700143
144 ASSERT_EQ(3U, unwinder.NumFrames());
145
146 auto* frame = &unwinder.frames()[0];
147 EXPECT_EQ(0U, frame->num);
148 EXPECT_EQ(0U, frame->rel_pc);
149 EXPECT_EQ(0x1000U, frame->pc);
150 EXPECT_EQ(0x10000U, frame->sp);
151 EXPECT_EQ("Frame0", frame->function_name);
152 EXPECT_EQ(0U, frame->function_offset);
153 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800154 EXPECT_EQ(0U, frame->map_elf_start_offset);
155 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700156 EXPECT_EQ(0x1000U, frame->map_start);
157 EXPECT_EQ(0x8000U, frame->map_end);
158 EXPECT_EQ(0U, frame->map_load_bias);
159 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
160
161 frame = &unwinder.frames()[1];
162 EXPECT_EQ(1U, frame->num);
163 EXPECT_EQ(0x100U, frame->rel_pc);
164 EXPECT_EQ(0x1100U, frame->pc);
165 EXPECT_EQ(0x10010U, frame->sp);
166 EXPECT_EQ("Frame1", frame->function_name);
167 EXPECT_EQ(1U, frame->function_offset);
168 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800169 EXPECT_EQ(0U, frame->map_elf_start_offset);
170 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700171 EXPECT_EQ(0x1000U, frame->map_start);
172 EXPECT_EQ(0x8000U, frame->map_end);
173 EXPECT_EQ(0U, frame->map_load_bias);
174 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
175
176 frame = &unwinder.frames()[2];
177 EXPECT_EQ(2U, frame->num);
178 EXPECT_EQ(0x200U, frame->rel_pc);
179 EXPECT_EQ(0x1200U, frame->pc);
180 EXPECT_EQ(0x10020U, frame->sp);
181 EXPECT_EQ("Frame2", frame->function_name);
182 EXPECT_EQ(2U, frame->function_offset);
183 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800184 EXPECT_EQ(0U, frame->map_elf_start_offset);
185 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700186 EXPECT_EQ(0x1000U, frame->map_start);
187 EXPECT_EQ(0x8000U, frame->map_end);
188 EXPECT_EQ(0U, frame->map_load_bias);
189 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
190}
191
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800192TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
193 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
194 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
195 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
196
Yabin Cui11e96fe2018-03-14 18:16:22 -0700197 regs_.set_pc(0x1000);
198 regs_.set_sp(0x10000);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800199 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
200 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
201 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
202
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800203 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800204 unwinder.SetResolveNames(false);
205 unwinder.Unwind();
206 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
207
208 ASSERT_EQ(3U, unwinder.NumFrames());
209
210 auto* frame = &unwinder.frames()[0];
211 EXPECT_EQ(0U, frame->num);
212 EXPECT_EQ(0U, frame->rel_pc);
213 EXPECT_EQ(0x1000U, frame->pc);
214 EXPECT_EQ(0x10000U, frame->sp);
215 EXPECT_EQ("", frame->function_name);
216 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000217 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800218 EXPECT_EQ(0U, frame->map_elf_start_offset);
219 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800220 EXPECT_EQ(0x1000U, frame->map_start);
221 EXPECT_EQ(0x8000U, frame->map_end);
222 EXPECT_EQ(0U, frame->map_load_bias);
223 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
224
225 frame = &unwinder.frames()[1];
226 EXPECT_EQ(1U, frame->num);
227 EXPECT_EQ(0x100U, frame->rel_pc);
228 EXPECT_EQ(0x1100U, frame->pc);
229 EXPECT_EQ(0x10010U, frame->sp);
230 EXPECT_EQ("", frame->function_name);
231 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000232 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800233 EXPECT_EQ(0U, frame->map_elf_start_offset);
234 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800235 EXPECT_EQ(0x1000U, frame->map_start);
236 EXPECT_EQ(0x8000U, frame->map_end);
237 EXPECT_EQ(0U, frame->map_load_bias);
238 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
239
240 frame = &unwinder.frames()[2];
241 EXPECT_EQ(2U, frame->num);
242 EXPECT_EQ(0x200U, frame->rel_pc);
243 EXPECT_EQ(0x1200U, frame->pc);
244 EXPECT_EQ(0x10020U, frame->sp);
245 EXPECT_EQ("", frame->function_name);
246 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000247 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800248 EXPECT_EQ(0U, frame->map_elf_start_offset);
249 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800250 EXPECT_EQ(0x1000U, frame->map_start);
251 EXPECT_EQ(0x8000U, frame->map_end);
252 EXPECT_EQ(0U, frame->map_load_bias);
253 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
254}
255
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800256TEST_F(UnwinderTest, non_zero_load_bias) {
257 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
258
Yabin Cui11e96fe2018-03-14 18:16:22 -0700259 regs_.set_pc(0xa5500);
260 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800261 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
262
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800263 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800264 unwinder.Unwind();
265 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
266
267 ASSERT_EQ(1U, unwinder.NumFrames());
268
269 auto* frame = &unwinder.frames()[0];
270 EXPECT_EQ(0U, frame->num);
271 EXPECT_EQ(0x5500U, frame->rel_pc);
272 EXPECT_EQ(0xa5500U, frame->pc);
273 EXPECT_EQ(0x10000U, frame->sp);
274 EXPECT_EQ("Frame0", frame->function_name);
275 EXPECT_EQ(0U, frame->function_offset);
276 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800277 EXPECT_EQ(0U, frame->map_elf_start_offset);
278 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800279 EXPECT_EQ(0xa5000U, frame->map_start);
280 EXPECT_EQ(0xa6000U, frame->map_end);
281 EXPECT_EQ(0x5000U, frame->map_load_bias);
282 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
283}
284
285TEST_F(UnwinderTest, non_zero_elf_offset) {
286 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
287
Yabin Cui11e96fe2018-03-14 18:16:22 -0700288 regs_.set_pc(0xa7500);
289 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800290 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
291
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800292 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800293 unwinder.Unwind();
294 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
295
296 ASSERT_EQ(1U, unwinder.NumFrames());
297
298 auto* frame = &unwinder.frames()[0];
299 EXPECT_EQ(0U, frame->num);
300 EXPECT_EQ(0x8500U, frame->rel_pc);
301 EXPECT_EQ(0xa7500U, frame->pc);
302 EXPECT_EQ(0x10000U, frame->sp);
303 EXPECT_EQ("Frame0", frame->function_name);
304 EXPECT_EQ(0U, frame->function_offset);
305 EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800306 EXPECT_EQ(0U, frame->map_elf_start_offset);
307 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800308 EXPECT_EQ(0xa7000U, frame->map_start);
309 EXPECT_EQ(0xa8000U, frame->map_end);
310 EXPECT_EQ(0U, frame->map_load_bias);
311 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
312}
313
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700314TEST_F(UnwinderTest, non_zero_map_offset) {
315 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
316
Yabin Cui11e96fe2018-03-14 18:16:22 -0700317 regs_.set_pc(0x43000);
318 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700319 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
320
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800321 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700322 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800323 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700324
325 ASSERT_EQ(1U, unwinder.NumFrames());
326
327 auto* frame = &unwinder.frames()[0];
328 EXPECT_EQ(0U, frame->num);
329 EXPECT_EQ(0U, frame->rel_pc);
330 EXPECT_EQ(0x43000U, frame->pc);
331 EXPECT_EQ(0x10000U, frame->sp);
332 EXPECT_EQ("Frame0", frame->function_name);
333 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700334 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
335 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
336 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
337 EXPECT_EQ(0x43000U, frame->map_start);
338 EXPECT_EQ(0x44000U, frame->map_end);
339 EXPECT_EQ(0U, frame->map_load_bias);
340 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
341}
342
343TEST_F(UnwinderTest, disable_embedded_soname) {
344 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
345
346 regs_.set_pc(0x43000);
347 regs_.set_sp(0x10000);
348 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
349
350 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
351 unwinder.SetEmbeddedSoname(false);
352 unwinder.Unwind();
353 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
354
355 ASSERT_EQ(1U, unwinder.NumFrames());
356
357 auto* frame = &unwinder.frames()[0];
358 EXPECT_EQ(0U, frame->num);
359 EXPECT_EQ(0U, frame->rel_pc);
360 EXPECT_EQ(0x43000U, frame->pc);
361 EXPECT_EQ(0x10000U, frame->sp);
362 EXPECT_EQ("Frame0", frame->function_name);
363 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700364 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700365 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800366 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700367 EXPECT_EQ(0x43000U, frame->map_start);
368 EXPECT_EQ(0x44000U, frame->map_end);
369 EXPECT_EQ(0U, frame->map_load_bias);
370 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
371}
372
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700373// Verify that no attempt to continue after the step indicates it is done.
374TEST_F(UnwinderTest, no_frames_after_finished) {
375 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
376 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
377 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
378 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
379 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
380
Yabin Cui11e96fe2018-03-14 18:16:22 -0700381 regs_.set_pc(0x1000);
382 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700383 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
384 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
385 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
386
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800387 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700388 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800389 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700390
391 ASSERT_EQ(1U, unwinder.NumFrames());
392
393 auto* frame = &unwinder.frames()[0];
394 EXPECT_EQ(0U, frame->num);
395 EXPECT_EQ(0U, frame->rel_pc);
396 EXPECT_EQ(0x1000U, frame->pc);
397 EXPECT_EQ(0x10000U, frame->sp);
398 EXPECT_EQ("Frame0", frame->function_name);
399 EXPECT_EQ(0U, frame->function_offset);
400 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800401 EXPECT_EQ(0U, frame->map_elf_start_offset);
402 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700403 EXPECT_EQ(0x1000U, frame->map_start);
404 EXPECT_EQ(0x8000U, frame->map_end);
405 EXPECT_EQ(0U, frame->map_load_bias);
406 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
407}
408
409// Verify the maximum frames to save.
410TEST_F(UnwinderTest, max_frames) {
411 for (size_t i = 0; i < 30; i++) {
412 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
413 ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
414 }
415
Yabin Cui11e96fe2018-03-14 18:16:22 -0700416 regs_.set_pc(0x1000);
417 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700418
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800419 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700420 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800421 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700422
423 ASSERT_EQ(20U, unwinder.NumFrames());
424
425 for (size_t i = 0; i < 20; i++) {
426 auto* frame = &unwinder.frames()[i];
427 EXPECT_EQ(i, frame->num);
428 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
429 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
430 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
431 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
432 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
433 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800434 EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
435 EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700436 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
437 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
438 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
439 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
440 }
441}
442
443// Verify that initial map names frames are removed.
444TEST_F(UnwinderTest, verify_frames_skipped) {
445 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
446 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
447 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
448
Yabin Cui11e96fe2018-03-14 18:16:22 -0700449 regs_.set_pc(0x20000);
450 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700451 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
452 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
453 ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false));
454 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
455 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
456 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
457 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
458 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
459
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800460 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700461 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
462 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800463 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700464
465 ASSERT_EQ(3U, unwinder.NumFrames());
466
467 auto* frame = &unwinder.frames()[0];
468 EXPECT_EQ(0U, frame->num);
469 EXPECT_EQ(0U, frame->rel_pc);
470 EXPECT_EQ(0x1000U, frame->pc);
471 EXPECT_EQ(0x10050U, frame->sp);
472 EXPECT_EQ("Frame0", frame->function_name);
473 EXPECT_EQ(0U, frame->function_offset);
474 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800475 EXPECT_EQ(0U, frame->map_elf_start_offset);
476 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700477 EXPECT_EQ(0x1000U, frame->map_start);
478 EXPECT_EQ(0x8000U, frame->map_end);
479 EXPECT_EQ(0U, frame->map_load_bias);
480 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
481
482 frame = &unwinder.frames()[1];
483 EXPECT_EQ(1U, frame->num);
484 EXPECT_EQ(0x1000U, frame->rel_pc);
485 EXPECT_EQ(0x21000U, frame->pc);
486 EXPECT_EQ(0x10060U, frame->sp);
487 EXPECT_EQ("Frame1", frame->function_name);
488 EXPECT_EQ(1U, frame->function_offset);
489 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800490 EXPECT_EQ(0U, frame->map_elf_start_offset);
491 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700492 EXPECT_EQ(0x20000U, frame->map_start);
493 EXPECT_EQ(0x22000U, frame->map_end);
494 EXPECT_EQ(0U, frame->map_load_bias);
495 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
496
497 frame = &unwinder.frames()[2];
498 EXPECT_EQ(2U, frame->num);
499 EXPECT_EQ(0U, frame->rel_pc);
500 EXPECT_EQ(0x23000U, frame->pc);
501 EXPECT_EQ(0x10070U, frame->sp);
502 EXPECT_EQ("Frame2", frame->function_name);
503 EXPECT_EQ(2U, frame->function_offset);
504 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800505 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700506 EXPECT_EQ(0x23000U, frame->map_start);
507 EXPECT_EQ(0x24000U, frame->map_end);
508 EXPECT_EQ(0U, frame->map_load_bias);
509 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
510}
511
512// Verify SP in a non-existant map is okay.
513TEST_F(UnwinderTest, sp_not_in_map) {
514 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
515 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
516
Yabin Cui11e96fe2018-03-14 18:16:22 -0700517 regs_.set_pc(0x1000);
518 regs_.set_sp(0x63000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700519 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
520 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
521
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800522 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700523 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800524 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700525
526 ASSERT_EQ(2U, unwinder.NumFrames());
527
528 auto* frame = &unwinder.frames()[0];
529 EXPECT_EQ(0U, frame->num);
530 EXPECT_EQ(0U, frame->rel_pc);
531 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700532 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700533 EXPECT_EQ("Frame0", frame->function_name);
534 EXPECT_EQ(0U, frame->function_offset);
535 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800536 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700537 EXPECT_EQ(0x1000U, frame->map_start);
538 EXPECT_EQ(0x8000U, frame->map_end);
539 EXPECT_EQ(0U, frame->map_load_bias);
540 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
541
542 frame = &unwinder.frames()[1];
543 EXPECT_EQ(1U, frame->num);
544 EXPECT_EQ(0x1000U, frame->rel_pc);
545 EXPECT_EQ(0x21000U, frame->pc);
546 EXPECT_EQ(0x50020U, frame->sp);
547 EXPECT_EQ("Frame1", frame->function_name);
548 EXPECT_EQ(1U, frame->function_offset);
549 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800550 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700551 EXPECT_EQ(0x20000U, frame->map_start);
552 EXPECT_EQ(0x22000U, frame->map_end);
553 EXPECT_EQ(0U, frame->map_load_bias);
554 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
555}
556
557// Verify PC in a device stops the unwind.
558TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
559 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
560 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
561 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
562
Yabin Cui11e96fe2018-03-14 18:16:22 -0700563 regs_.set_pc(0x13000);
564 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700565 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
566 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
567 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
568
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800569 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700570 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800571 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700572
573 ASSERT_EQ(1U, unwinder.NumFrames());
574}
575
576// Verify SP in a device stops the unwind.
577TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
578 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
579 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
580 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
581
Yabin Cui11e96fe2018-03-14 18:16:22 -0700582 regs_.set_pc(0x1000);
583 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700584 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
585 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
586 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
587
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800588 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700589 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800590 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700591
592 ASSERT_EQ(1U, unwinder.NumFrames());
593}
594
595// Verify a no map info frame gets a frame.
596TEST_F(UnwinderTest, pc_without_map) {
597 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
598
Yabin Cui11e96fe2018-03-14 18:16:22 -0700599 regs_.set_pc(0x41000);
600 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700601
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800602 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700603 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800604 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700605
606 ASSERT_EQ(1U, unwinder.NumFrames());
607
608 auto* frame = &unwinder.frames()[0];
609 EXPECT_EQ(0U, frame->num);
610 EXPECT_EQ(0x41000U, frame->rel_pc);
611 EXPECT_EQ(0x41000U, frame->pc);
612 EXPECT_EQ(0x13000U, frame->sp);
613 EXPECT_EQ("", frame->function_name);
614 EXPECT_EQ(0U, frame->function_offset);
615 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800616 EXPECT_EQ(0U, frame->map_elf_start_offset);
617 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700618 EXPECT_EQ(0U, frame->map_start);
619 EXPECT_EQ(0U, frame->map_end);
620 EXPECT_EQ(0U, frame->map_load_bias);
621 EXPECT_EQ(0, frame->map_flags);
622}
623
624// Verify that a speculative frame is added.
625TEST_F(UnwinderTest, speculative_frame) {
626 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
627 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
628
629 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700630 regs_.set_pc(0);
631 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700632 regs_.FakeSetReturnAddress(0x1202);
633 regs_.FakeSetReturnAddressValid(true);
634
635 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
636 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
637
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800638 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700639 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800640 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700641
642 ASSERT_EQ(3U, unwinder.NumFrames());
643
644 auto* frame = &unwinder.frames()[0];
645 EXPECT_EQ(0U, frame->num);
646 EXPECT_EQ(0U, frame->rel_pc);
647 EXPECT_EQ(0U, frame->pc);
648 EXPECT_EQ(0x10000U, frame->sp);
649 EXPECT_EQ("", frame->function_name);
650 EXPECT_EQ(0U, frame->function_offset);
651 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800652 EXPECT_EQ(0U, frame->map_elf_start_offset);
653 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700654 EXPECT_EQ(0U, frame->map_start);
655 EXPECT_EQ(0U, frame->map_end);
656 EXPECT_EQ(0U, frame->map_load_bias);
657 EXPECT_EQ(0, frame->map_flags);
658
659 frame = &unwinder.frames()[1];
660 EXPECT_EQ(1U, frame->num);
661 EXPECT_EQ(0x200U, frame->rel_pc);
662 EXPECT_EQ(0x1200U, frame->pc);
663 EXPECT_EQ(0x10000U, frame->sp);
664 EXPECT_EQ("Frame0", frame->function_name);
665 EXPECT_EQ(0U, frame->function_offset);
666 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800667 EXPECT_EQ(0U, frame->map_elf_start_offset);
668 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700669 EXPECT_EQ(0x1000U, frame->map_start);
670 EXPECT_EQ(0x8000U, frame->map_end);
671 EXPECT_EQ(0U, frame->map_load_bias);
672 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
673
674 frame = &unwinder.frames()[2];
675 EXPECT_EQ(2U, frame->num);
676 EXPECT_EQ(0x100U, frame->rel_pc);
677 EXPECT_EQ(0x23100U, frame->pc);
678 EXPECT_EQ(0x10020U, frame->sp);
679 EXPECT_EQ("Frame1", frame->function_name);
680 EXPECT_EQ(1U, frame->function_offset);
681 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800682 EXPECT_EQ(0U, frame->map_elf_start_offset);
683 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700684 EXPECT_EQ(0x23000U, frame->map_start);
685 EXPECT_EQ(0x24000U, frame->map_end);
686 EXPECT_EQ(0U, frame->map_load_bias);
687 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
688}
689
690// Verify that a speculative frame is added then removed because no other
691// frames are added.
692TEST_F(UnwinderTest, speculative_frame_removed) {
693 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
694 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
695
696 // Fake as if code called a nullptr function.
Christopher Ferris065f1562018-12-13 09:33:45 -0800697 regs_.set_pc(0x20000);
698 regs_.set_sp(0x10000);
699 ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
700 regs_.FakeSetReturnAddress(0x12);
701 regs_.FakeSetReturnAddressValid(true);
702
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800703 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris065f1562018-12-13 09:33:45 -0800704 unwinder.Unwind();
705 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
706
707 ASSERT_EQ(2U, unwinder.NumFrames());
708
709 auto* frame = &unwinder.frames()[0];
710 EXPECT_EQ(0U, frame->num);
711 EXPECT_EQ(0U, frame->rel_pc);
712 EXPECT_EQ(0x20000U, frame->pc);
713 EXPECT_EQ(0x10000U, frame->sp);
714 EXPECT_EQ("Frame0", frame->function_name);
715 EXPECT_EQ(0U, frame->function_offset);
716 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800717 EXPECT_EQ(0U, frame->map_elf_start_offset);
718 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800719 EXPECT_EQ(0x20000U, frame->map_start);
720 EXPECT_EQ(0x22000U, frame->map_end);
721 EXPECT_EQ(0U, frame->map_load_bias);
722 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
723
724 frame = &unwinder.frames()[1];
725 EXPECT_EQ(1U, frame->num);
726 EXPECT_EQ(0U, frame->rel_pc);
727 EXPECT_EQ(0U, frame->pc);
728 EXPECT_EQ(0x10010U, frame->sp);
729 EXPECT_EQ("", frame->function_name);
730 EXPECT_EQ(0U, frame->function_offset);
731 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800732 EXPECT_EQ(0U, frame->map_elf_start_offset);
733 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800734 EXPECT_EQ(0U, frame->map_start);
735 EXPECT_EQ(0U, frame->map_end);
736 EXPECT_EQ(0U, frame->map_load_bias);
737 EXPECT_EQ(0, frame->map_flags);
738}
739
740// Verify that a speculative frame is added and left if there are only
741// two frames and the pc is in the middle nowhere.
742TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
743 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
744 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
745
746 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700747 regs_.set_pc(0);
748 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700749 regs_.FakeSetReturnAddress(0x1202);
750 regs_.FakeSetReturnAddressValid(true);
751
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800752 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700753 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800754 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700755
Christopher Ferris065f1562018-12-13 09:33:45 -0800756 ASSERT_EQ(2U, unwinder.NumFrames());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700757
758 auto* frame = &unwinder.frames()[0];
759 EXPECT_EQ(0U, frame->num);
760 EXPECT_EQ(0U, frame->rel_pc);
761 EXPECT_EQ(0U, frame->pc);
762 EXPECT_EQ(0x10000U, frame->sp);
763 EXPECT_EQ("", frame->function_name);
764 EXPECT_EQ(0U, frame->function_offset);
765 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800766 EXPECT_EQ(0U, frame->map_elf_start_offset);
767 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700768 EXPECT_EQ(0U, frame->map_start);
769 EXPECT_EQ(0U, frame->map_end);
770 EXPECT_EQ(0U, frame->map_load_bias);
771 EXPECT_EQ(0, frame->map_flags);
Christopher Ferris065f1562018-12-13 09:33:45 -0800772
773 frame = &unwinder.frames()[1];
774 EXPECT_EQ(1U, frame->num);
775 EXPECT_EQ(0x200U, frame->rel_pc);
776 EXPECT_EQ(0x1200U, frame->pc);
777 EXPECT_EQ(0x10000U, frame->sp);
778 EXPECT_EQ("Frame0", frame->function_name);
779 EXPECT_EQ(0U, frame->function_offset);
780 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800781 EXPECT_EQ(0U, frame->map_elf_start_offset);
782 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800783 EXPECT_EQ(0x1000U, frame->map_start);
784 EXPECT_EQ(0x8000U, frame->map_end);
785 EXPECT_EQ(0U, frame->map_load_bias);
786 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700787}
788
Florian Mayerc479e4e2019-01-23 13:35:40 +0000789// Verify that a speculative frame does not cause a crash when it wasn't
790// really added due to a filter.
791TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
792 regs_.set_pc(0x23000);
793 regs_.set_sp(0x10000);
794 regs_.FakeSetReturnAddress(0x23100);
795 regs_.FakeSetReturnAddressValid(true);
796
797 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
798
799 std::vector<std::string> skip_names{"libanother.so"};
800 unwinder.Unwind(&skip_names);
801 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
802
803 ASSERT_EQ(0U, unwinder.NumFrames());
804}
805
Christopher Ferrise69f4702017-10-19 16:08:58 -0700806// Verify that an unwind stops when a frame is in given suffix.
807TEST_F(UnwinderTest, map_ignore_suffixes) {
808 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
809 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
810 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
811 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
812
813 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700814 regs_.set_pc(0x1000);
815 regs_.set_sp(0x10000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700816 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
817 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
818 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
819
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800820 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700821 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700822 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800823 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700824
825 ASSERT_EQ(2U, unwinder.NumFrames());
826 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800827 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700828 ASSERT_TRUE(map_info != nullptr);
829 EXPECT_TRUE(map_info->elf == nullptr);
830
831 auto* frame = &unwinder.frames()[0];
832 EXPECT_EQ(0U, frame->num);
833 EXPECT_EQ(0U, frame->rel_pc);
834 EXPECT_EQ(0x1000U, frame->pc);
835 EXPECT_EQ(0x10000U, frame->sp);
836 EXPECT_EQ("Frame0", frame->function_name);
837 EXPECT_EQ(0U, frame->function_offset);
838 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800839 EXPECT_EQ(0U, frame->map_elf_start_offset);
840 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700841 EXPECT_EQ(0x1000U, frame->map_start);
842 EXPECT_EQ(0x8000U, frame->map_end);
843 EXPECT_EQ(0U, frame->map_load_bias);
844 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
845
846 frame = &unwinder.frames()[1];
847 EXPECT_EQ(1U, frame->num);
848 EXPECT_EQ(0x400U, frame->rel_pc);
849 EXPECT_EQ(0x43400U, frame->pc);
850 EXPECT_EQ(0x10010U, frame->sp);
851 EXPECT_EQ("Frame1", frame->function_name);
852 EXPECT_EQ(1U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700853 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
854 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800855 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700856 EXPECT_EQ(0x43000U, frame->map_start);
857 EXPECT_EQ(0x44000U, frame->map_end);
858 EXPECT_EQ(0U, frame->map_load_bias);
859 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
860}
861
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700862// Verify that an unwind stops when the sp and pc don't change.
863TEST_F(UnwinderTest, sp_pc_do_not_change) {
864 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
865 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
866 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
867 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
868 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
869
Yabin Cui11e96fe2018-03-14 18:16:22 -0700870 regs_.set_pc(0x1000);
871 regs_.set_sp(0x10000);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700872 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
873 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
874 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
875 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
876 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
877 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
878
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800879 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700880 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800881 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700882
883 ASSERT_EQ(3U, unwinder.NumFrames());
884
885 auto* frame = &unwinder.frames()[0];
886 EXPECT_EQ(0U, frame->num);
887 EXPECT_EQ(0U, frame->rel_pc);
888 EXPECT_EQ(0x1000U, frame->pc);
889 EXPECT_EQ(0x10000U, frame->sp);
890 EXPECT_EQ("Frame0", frame->function_name);
891 EXPECT_EQ(0U, frame->function_offset);
892 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800893 EXPECT_EQ(0U, frame->map_elf_start_offset);
894 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700895 EXPECT_EQ(0x1000U, frame->map_start);
896 EXPECT_EQ(0x8000U, frame->map_end);
897 EXPECT_EQ(0U, frame->map_load_bias);
898 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
899
900 frame = &unwinder.frames()[1];
901 EXPECT_EQ(1U, frame->num);
902 EXPECT_EQ(0x400U, frame->rel_pc);
903 EXPECT_EQ(0x33400U, frame->pc);
904 EXPECT_EQ(0x10010U, frame->sp);
905 EXPECT_EQ("Frame1", frame->function_name);
906 EXPECT_EQ(1U, frame->function_offset);
907 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800908 EXPECT_EQ(0U, frame->map_elf_start_offset);
909 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700910 EXPECT_EQ(0x33000U, frame->map_start);
911 EXPECT_EQ(0x34000U, frame->map_end);
912 EXPECT_EQ(0U, frame->map_load_bias);
913 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
914
915 frame = &unwinder.frames()[2];
916 EXPECT_EQ(2U, frame->num);
917 EXPECT_EQ(0x500U, frame->rel_pc);
918 EXPECT_EQ(0x33500U, frame->pc);
919 EXPECT_EQ(0x10020U, frame->sp);
920 EXPECT_EQ("Frame2", frame->function_name);
921 EXPECT_EQ(2U, frame->function_offset);
922 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800923 EXPECT_EQ(0U, frame->map_elf_start_offset);
924 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700925 EXPECT_EQ(0x33000U, frame->map_start);
926 EXPECT_EQ(0x34000U, frame->map_end);
927 EXPECT_EQ(0U, frame->map_load_bias);
928 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
929}
930
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800931TEST_F(UnwinderTest, dex_pc_in_map) {
932 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700933 regs_.set_pc(0x1000);
934 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800935 regs_.FakeSetDexPc(0xa3400);
936
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800937 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800938 unwinder.Unwind();
939 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
940
941 ASSERT_EQ(2U, unwinder.NumFrames());
942
943 auto* frame = &unwinder.frames()[0];
944 EXPECT_EQ(0U, frame->num);
945 EXPECT_EQ(0x400U, frame->rel_pc);
946 EXPECT_EQ(0xa3400U, frame->pc);
947 EXPECT_EQ(0x10000U, frame->sp);
948 EXPECT_EQ("", frame->function_name);
949 EXPECT_EQ(0U, frame->function_offset);
950 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800951 EXPECT_EQ(0U, frame->map_elf_start_offset);
952 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800953 EXPECT_EQ(0xa3000U, frame->map_start);
954 EXPECT_EQ(0xa4000U, frame->map_end);
955 EXPECT_EQ(0U, frame->map_load_bias);
956 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
957
958 frame = &unwinder.frames()[1];
959 EXPECT_EQ(1U, frame->num);
960 EXPECT_EQ(0U, frame->rel_pc);
961 EXPECT_EQ(0x1000U, frame->pc);
962 EXPECT_EQ(0x10000U, frame->sp);
963 EXPECT_EQ("Frame0", frame->function_name);
964 EXPECT_EQ(0U, frame->function_offset);
965 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800966 EXPECT_EQ(0U, frame->map_elf_start_offset);
967 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800968 EXPECT_EQ(0x1000U, frame->map_start);
969 EXPECT_EQ(0x8000U, frame->map_end);
970 EXPECT_EQ(0U, frame->map_load_bias);
971 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
972}
973
974TEST_F(UnwinderTest, dex_pc_not_in_map) {
975 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700976 regs_.set_pc(0x1000);
977 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800978 regs_.FakeSetDexPc(0x50000);
979
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800980 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800981 unwinder.Unwind();
982 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
983
984 ASSERT_EQ(2U, unwinder.NumFrames());
985
986 auto* frame = &unwinder.frames()[0];
987 EXPECT_EQ(0U, frame->num);
988 EXPECT_EQ(0x50000U, frame->rel_pc);
989 EXPECT_EQ(0x50000U, frame->pc);
990 EXPECT_EQ(0x10000U, frame->sp);
991 EXPECT_EQ("", frame->function_name);
992 EXPECT_EQ(0U, frame->function_offset);
993 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800994 EXPECT_EQ(0U, frame->map_elf_start_offset);
995 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800996 EXPECT_EQ(0U, frame->map_start);
997 EXPECT_EQ(0U, frame->map_end);
998 EXPECT_EQ(0U, frame->map_load_bias);
999 EXPECT_EQ(0, frame->map_flags);
1000
1001 frame = &unwinder.frames()[1];
1002 EXPECT_EQ(1U, frame->num);
1003 EXPECT_EQ(0U, frame->rel_pc);
1004 EXPECT_EQ(0x1000U, frame->pc);
1005 EXPECT_EQ(0x10000U, frame->sp);
1006 EXPECT_EQ("Frame0", frame->function_name);
1007 EXPECT_EQ(0U, frame->function_offset);
1008 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001009 EXPECT_EQ(0U, frame->map_elf_start_offset);
1010 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001011 EXPECT_EQ(0x1000U, frame->map_start);
1012 EXPECT_EQ(0x8000U, frame->map_end);
1013 EXPECT_EQ(0U, frame->map_load_bias);
1014 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1015}
1016
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001017TEST_F(UnwinderTest, dex_pc_multiple_frames) {
1018 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1019 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001020 regs_.set_pc(0x1000);
1021 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001022 regs_.FakeSetDexPc(0xa3400);
1023 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
1024 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1025
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001026 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001027 unwinder.Unwind();
1028 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1029
1030 ASSERT_EQ(3U, unwinder.NumFrames());
1031
1032 auto* frame = &unwinder.frames()[0];
1033 EXPECT_EQ(0U, frame->num);
1034 EXPECT_EQ(0x400U, frame->rel_pc);
1035 EXPECT_EQ(0xa3400U, frame->pc);
1036 EXPECT_EQ(0x10000U, frame->sp);
1037 EXPECT_EQ("", frame->function_name);
1038 EXPECT_EQ(0U, frame->function_offset);
1039 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001040 EXPECT_EQ(0U, frame->map_elf_start_offset);
1041 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001042 EXPECT_EQ(0xa3000U, frame->map_start);
1043 EXPECT_EQ(0xa4000U, frame->map_end);
1044 EXPECT_EQ(0U, frame->map_load_bias);
1045 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1046
1047 frame = &unwinder.frames()[1];
1048 EXPECT_EQ(1U, frame->num);
1049 EXPECT_EQ(0U, frame->rel_pc);
1050 EXPECT_EQ(0x1000U, frame->pc);
1051 EXPECT_EQ(0x10000U, frame->sp);
1052 EXPECT_EQ("Frame0", frame->function_name);
1053 EXPECT_EQ(0U, frame->function_offset);
1054 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001055 EXPECT_EQ(0U, frame->map_elf_start_offset);
1056 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001057 EXPECT_EQ(0x1000U, frame->map_start);
1058 EXPECT_EQ(0x8000U, frame->map_end);
1059 EXPECT_EQ(0U, frame->map_load_bias);
1060 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1061
1062 frame = &unwinder.frames()[2];
1063 EXPECT_EQ(2U, frame->num);
1064 EXPECT_EQ(0x400U, frame->rel_pc);
1065 EXPECT_EQ(0x33400U, frame->pc);
1066 EXPECT_EQ(0x10010U, frame->sp);
1067 EXPECT_EQ("Frame1", frame->function_name);
1068 EXPECT_EQ(1U, frame->function_offset);
1069 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001070 EXPECT_EQ(0U, frame->map_elf_start_offset);
1071 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001072 EXPECT_EQ(0x33000U, frame->map_start);
1073 EXPECT_EQ(0x34000U, frame->map_end);
1074 EXPECT_EQ(0U, frame->map_load_bias);
1075 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1076}
1077
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001078TEST_F(UnwinderTest, dex_pc_max_frames) {
1079 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1080 regs_.set_pc(0x1000);
1081 regs_.set_sp(0x10000);
1082 regs_.FakeSetDexPc(0xa3400);
1083
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001084 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001085 unwinder.Unwind();
1086 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
1087
1088 ASSERT_EQ(1U, unwinder.NumFrames());
1089
1090 auto* frame = &unwinder.frames()[0];
1091 EXPECT_EQ(0U, frame->num);
1092 EXPECT_EQ(0x400U, frame->rel_pc);
1093 EXPECT_EQ(0xa3400U, frame->pc);
1094 EXPECT_EQ(0x10000U, frame->sp);
1095 EXPECT_EQ("", frame->function_name);
1096 EXPECT_EQ(0U, frame->function_offset);
1097 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001098 EXPECT_EQ(0U, frame->map_elf_start_offset);
1099 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001100 EXPECT_EQ(0xa3000U, frame->map_start);
1101 EXPECT_EQ(0xa4000U, frame->map_end);
1102 EXPECT_EQ(0U, frame->map_load_bias);
1103 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1104}
1105
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001106// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001107TEST_F(UnwinderTest, format_frame) {
1108 RegsFake regs_arm(10);
1109 regs_arm.FakeSetArch(ARCH_ARM);
1110 Unwinder unwinder32(10, maps_.get(), &regs_arm, process_memory_);
1111
1112 RegsFake regs_arm64(10);
1113 regs_arm64.FakeSetArch(ARCH_ARM64);
1114 Unwinder unwinder64(10, maps_.get(), &regs_arm64, process_memory_);
1115
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001116 FrameData frame;
1117 frame.num = 1;
1118 frame.rel_pc = 0x1000;
1119 frame.pc = 0x4000;
1120 frame.sp = 0x1000;
1121 frame.function_name = "function";
1122 frame.function_offset = 100;
1123 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001124 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001125 frame.map_start = 0x3000;
1126 frame.map_end = 0x6000;
1127 frame.map_flags = PROT_READ;
1128
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001129 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001130 unwinder64.FormatFrame(frame));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001131 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001132 unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001133
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001134 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001135 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001136 unwinder64.FormatFrame(frame));
1137 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001138
1139 frame.function_offset = 0;
1140 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
Christopher Ferris78133452019-03-14 13:44:38 -07001141 unwinder64.FormatFrame(frame));
1142 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001143
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001144 // Verify the function name is demangled.
1145 frame.function_name = "_ZN4funcEv";
Christopher Ferris78133452019-03-14 13:44:38 -07001146 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())", unwinder64.FormatFrame(frame));
1147 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", unwinder32.FormatFrame(frame));
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001148
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001149 frame.function_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001150 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", unwinder64.FormatFrame(frame));
1151 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001152
1153 frame.map_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001154 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", unwinder64.FormatFrame(frame));
1155 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001156
1157 frame.map_start = 0;
1158 frame.map_end = 0;
Christopher Ferris78133452019-03-14 13:44:38 -07001159 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", unwinder64.FormatFrame(frame));
1160 EXPECT_EQ(" #01 pc 00001000 <unknown>", unwinder32.FormatFrame(frame));
1161}
1162
1163TEST_F(UnwinderTest, format_frame_build_id) {
1164 RegsFake regs(10);
1165 regs.FakeSetArch(ARCH_ARM);
1166 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1167
1168 FrameData frame;
1169 frame.num = 1;
1170 frame.rel_pc = 0x1000;
1171 frame.pc = 0x4000;
1172 frame.sp = 0x1000;
1173 frame.function_name = "function";
1174 frame.function_offset = 100;
1175 frame.map_name = "/fake/libfake.so";
1176 frame.map_elf_start_offset = 0;
1177 frame.map_start = 0x3000;
1178 frame.map_end = 0x6000;
1179 frame.map_flags = PROT_READ;
1180
1181 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder.FormatFrame(frame));
1182 unwinder.SetDisplayBuildID(true);
1183 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100) (BuildId: 46414b45)",
1184 unwinder.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001185}
1186
Christopher Ferris02fdb562017-12-08 15:04:49 -08001187static std::string ArchToString(ArchEnum arch) {
1188 if (arch == ARCH_ARM) {
1189 return "Arm";
1190 } else if (arch == ARCH_ARM64) {
1191 return "Arm64";
1192 } else if (arch == ARCH_X86) {
1193 return "X86";
1194 } else if (arch == ARCH_X86_64) {
1195 return "X86_64";
1196 } else {
1197 return "Unknown";
1198 }
1199}
1200
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001201// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001202TEST_F(UnwinderTest, format_frame_by_arch) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001203 std::vector<Regs*> reg_list;
1204 RegsArm* arm = new RegsArm;
1205 arm->set_pc(0x2300);
1206 arm->set_sp(0x10000);
1207 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001208
Christopher Ferris02fdb562017-12-08 15:04:49 -08001209 RegsArm64* arm64 = new RegsArm64;
1210 arm64->set_pc(0x2300);
1211 arm64->set_sp(0x10000);
1212 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001213
Christopher Ferris02fdb562017-12-08 15:04:49 -08001214 RegsX86* x86 = new RegsX86;
1215 x86->set_pc(0x2300);
1216 x86->set_sp(0x10000);
1217 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001218
Christopher Ferris02fdb562017-12-08 15:04:49 -08001219 RegsX86_64* x86_64 = new RegsX86_64;
1220 x86_64->set_pc(0x2300);
1221 x86_64->set_sp(0x10000);
1222 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001223
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001224 RegsMips* mips = new RegsMips;
1225 mips->set_pc(0x2300);
1226 mips->set_sp(0x10000);
1227 reg_list.push_back(mips);
1228
1229 RegsMips64* mips64 = new RegsMips64;
1230 mips64->set_pc(0x2300);
1231 mips64->set_sp(0x10000);
1232 reg_list.push_back(mips64);
1233
Christopher Ferris02fdb562017-12-08 15:04:49 -08001234 for (auto regs : reg_list) {
1235 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001236
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001237 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001238 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001239
Christopher Ferris02fdb562017-12-08 15:04:49 -08001240 ASSERT_EQ(1U, unwinder.NumFrames());
1241 std::string expected;
1242 switch (regs->Arch()) {
1243 case ARCH_ARM:
1244 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001245 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001246 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1247 break;
1248 case ARCH_ARM64:
1249 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001250 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001251 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1252 break;
1253 default:
1254 expected = "";
1255 }
1256 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1257 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1258 delete regs;
1259 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001260}
1261
1262} // namespace unwindstack