blob: 504b57a4eef6bb6626e3f417a458bc0d7ab7cb14 [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 Ferrisf6f691b2017-09-25 19:23:07 -070061 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080062 AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070063
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080064 AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070065
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080066 AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
67 "/dev/fake_device");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070068
Christopher Ferris02fdb562017-12-08 15:04:49 -080069 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070070 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080071 AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070072
Christopher Ferris02fdb562017-12-08 15:04:49 -080073 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070074 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080075 AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070076
Christopher Ferris02fdb562017-12-08 15:04:49 -080077 elf = new ElfFake(new MemoryFake);
Christopher Ferrise69f4702017-10-19 16:08:58 -070078 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080079 AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070080
Christopher Ferris02fdb562017-12-08 15:04:49 -080081 elf = new ElfFake(new MemoryFake);
Christopher Ferris02a6c442019-03-11 14:43:33 -070082 ElfInterfaceFake* interface = new ElfInterfaceFake(nullptr);
83 interface->FakeSetSoname("lib_fake.so");
84 elf->FakeSetInterface(interface);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080085 AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
Christopher Ferris02a6c442019-03-11 14:43:33 -070086 MapInfo* map_info = maps_->Find(0x43000);
87 ASSERT_TRUE(map_info != nullptr);
88 map_info->elf_start_offset = 0x1d000;
Christopher Ferrise69f4702017-10-19 16:08:58 -070089
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080090 AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
Christopher Ferris02fdb562017-12-08 15:04:49 -080091
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080092 AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
Florian Mayer3d67d342019-02-27 18:00:37 +000093 const auto& info = *--maps_->end();
Christopher Ferrise762f1f2018-02-06 14:51:48 -080094 info->load_bias = 0;
Christopher Ferrise762f1f2018-02-06 14:51:48 -080095
Christopher Ferrise4df5f52018-02-12 13:24:18 -080096 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -080097 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
98 elf->FakeSetLoadBias(0x5000);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080099 AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
100 elf);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800101
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800102 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800103 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800104 AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_offset.oat",
105 elf);
Florian Mayer3d67d342019-02-27 18:00:37 +0000106 const auto& info2 = *--maps_->end();
107 info2->elf_offset = 0x8000;
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800108
Christopher Ferris02fdb562017-12-08 15:04:49 -0800109 process_memory_.reset(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700110 }
111
112 void SetUp() override {
113 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800114 regs_.FakeSetArch(ARCH_ARM);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700115 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700116 }
117
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800118 static std::unique_ptr<Maps> maps_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700119 static RegsFake regs_;
120 static std::shared_ptr<Memory> process_memory_;
121};
122
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800123std::unique_ptr<Maps> UnwinderTest::maps_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700124RegsFake UnwinderTest::regs_(5);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700125std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
126
127TEST_F(UnwinderTest, multiple_frames) {
128 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
129 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
130 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
131
Yabin Cui11e96fe2018-03-14 18:16:22 -0700132 regs_.set_pc(0x1000);
133 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700134 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
135 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
136 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
137
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800138 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700139 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800140 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700141
142 ASSERT_EQ(3U, unwinder.NumFrames());
143
144 auto* frame = &unwinder.frames()[0];
145 EXPECT_EQ(0U, frame->num);
146 EXPECT_EQ(0U, frame->rel_pc);
147 EXPECT_EQ(0x1000U, frame->pc);
148 EXPECT_EQ(0x10000U, frame->sp);
149 EXPECT_EQ("Frame0", frame->function_name);
150 EXPECT_EQ(0U, frame->function_offset);
151 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800152 EXPECT_EQ(0U, frame->map_elf_start_offset);
153 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700154 EXPECT_EQ(0x1000U, frame->map_start);
155 EXPECT_EQ(0x8000U, frame->map_end);
156 EXPECT_EQ(0U, frame->map_load_bias);
157 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
158
159 frame = &unwinder.frames()[1];
160 EXPECT_EQ(1U, frame->num);
161 EXPECT_EQ(0x100U, frame->rel_pc);
162 EXPECT_EQ(0x1100U, frame->pc);
163 EXPECT_EQ(0x10010U, frame->sp);
164 EXPECT_EQ("Frame1", frame->function_name);
165 EXPECT_EQ(1U, frame->function_offset);
166 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800167 EXPECT_EQ(0U, frame->map_elf_start_offset);
168 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700169 EXPECT_EQ(0x1000U, frame->map_start);
170 EXPECT_EQ(0x8000U, frame->map_end);
171 EXPECT_EQ(0U, frame->map_load_bias);
172 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
173
174 frame = &unwinder.frames()[2];
175 EXPECT_EQ(2U, frame->num);
176 EXPECT_EQ(0x200U, frame->rel_pc);
177 EXPECT_EQ(0x1200U, frame->pc);
178 EXPECT_EQ(0x10020U, frame->sp);
179 EXPECT_EQ("Frame2", frame->function_name);
180 EXPECT_EQ(2U, frame->function_offset);
181 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800182 EXPECT_EQ(0U, frame->map_elf_start_offset);
183 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700184 EXPECT_EQ(0x1000U, frame->map_start);
185 EXPECT_EQ(0x8000U, frame->map_end);
186 EXPECT_EQ(0U, frame->map_load_bias);
187 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
188}
189
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800190TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
191 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
192 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
193 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
194
Yabin Cui11e96fe2018-03-14 18:16:22 -0700195 regs_.set_pc(0x1000);
196 regs_.set_sp(0x10000);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800197 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
198 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
199 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
200
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800201 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800202 unwinder.SetResolveNames(false);
203 unwinder.Unwind();
204 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
205
206 ASSERT_EQ(3U, unwinder.NumFrames());
207
208 auto* frame = &unwinder.frames()[0];
209 EXPECT_EQ(0U, frame->num);
210 EXPECT_EQ(0U, frame->rel_pc);
211 EXPECT_EQ(0x1000U, frame->pc);
212 EXPECT_EQ(0x10000U, frame->sp);
213 EXPECT_EQ("", frame->function_name);
214 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000215 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800216 EXPECT_EQ(0U, frame->map_elf_start_offset);
217 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800218 EXPECT_EQ(0x1000U, frame->map_start);
219 EXPECT_EQ(0x8000U, frame->map_end);
220 EXPECT_EQ(0U, frame->map_load_bias);
221 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
222
223 frame = &unwinder.frames()[1];
224 EXPECT_EQ(1U, frame->num);
225 EXPECT_EQ(0x100U, frame->rel_pc);
226 EXPECT_EQ(0x1100U, frame->pc);
227 EXPECT_EQ(0x10010U, frame->sp);
228 EXPECT_EQ("", frame->function_name);
229 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000230 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800231 EXPECT_EQ(0U, frame->map_elf_start_offset);
232 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800233 EXPECT_EQ(0x1000U, frame->map_start);
234 EXPECT_EQ(0x8000U, frame->map_end);
235 EXPECT_EQ(0U, frame->map_load_bias);
236 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
237
238 frame = &unwinder.frames()[2];
239 EXPECT_EQ(2U, frame->num);
240 EXPECT_EQ(0x200U, frame->rel_pc);
241 EXPECT_EQ(0x1200U, frame->pc);
242 EXPECT_EQ(0x10020U, frame->sp);
243 EXPECT_EQ("", frame->function_name);
244 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000245 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800246 EXPECT_EQ(0U, frame->map_elf_start_offset);
247 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800248 EXPECT_EQ(0x1000U, frame->map_start);
249 EXPECT_EQ(0x8000U, frame->map_end);
250 EXPECT_EQ(0U, frame->map_load_bias);
251 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
252}
253
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800254TEST_F(UnwinderTest, non_zero_load_bias) {
255 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
256
Yabin Cui11e96fe2018-03-14 18:16:22 -0700257 regs_.set_pc(0xa5500);
258 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800259 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
260
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800261 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800262 unwinder.Unwind();
263 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
264
265 ASSERT_EQ(1U, unwinder.NumFrames());
266
267 auto* frame = &unwinder.frames()[0];
268 EXPECT_EQ(0U, frame->num);
269 EXPECT_EQ(0x5500U, frame->rel_pc);
270 EXPECT_EQ(0xa5500U, frame->pc);
271 EXPECT_EQ(0x10000U, frame->sp);
272 EXPECT_EQ("Frame0", frame->function_name);
273 EXPECT_EQ(0U, frame->function_offset);
274 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800275 EXPECT_EQ(0U, frame->map_elf_start_offset);
276 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800277 EXPECT_EQ(0xa5000U, frame->map_start);
278 EXPECT_EQ(0xa6000U, frame->map_end);
279 EXPECT_EQ(0x5000U, frame->map_load_bias);
280 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
281}
282
283TEST_F(UnwinderTest, non_zero_elf_offset) {
284 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
285
Yabin Cui11e96fe2018-03-14 18:16:22 -0700286 regs_.set_pc(0xa7500);
287 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800288 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
289
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800290 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800291 unwinder.Unwind();
292 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
293
294 ASSERT_EQ(1U, unwinder.NumFrames());
295
296 auto* frame = &unwinder.frames()[0];
297 EXPECT_EQ(0U, frame->num);
298 EXPECT_EQ(0x8500U, frame->rel_pc);
299 EXPECT_EQ(0xa7500U, frame->pc);
300 EXPECT_EQ(0x10000U, frame->sp);
301 EXPECT_EQ("Frame0", frame->function_name);
302 EXPECT_EQ(0U, frame->function_offset);
303 EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800304 EXPECT_EQ(0U, frame->map_elf_start_offset);
305 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800306 EXPECT_EQ(0xa7000U, frame->map_start);
307 EXPECT_EQ(0xa8000U, frame->map_end);
308 EXPECT_EQ(0U, frame->map_load_bias);
309 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
310}
311
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700312TEST_F(UnwinderTest, non_zero_map_offset) {
313 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
314
Yabin Cui11e96fe2018-03-14 18:16:22 -0700315 regs_.set_pc(0x43000);
316 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700317 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
318
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800319 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700320 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800321 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700322
323 ASSERT_EQ(1U, unwinder.NumFrames());
324
325 auto* frame = &unwinder.frames()[0];
326 EXPECT_EQ(0U, frame->num);
327 EXPECT_EQ(0U, frame->rel_pc);
328 EXPECT_EQ(0x43000U, frame->pc);
329 EXPECT_EQ(0x10000U, frame->sp);
330 EXPECT_EQ("Frame0", frame->function_name);
331 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700332 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
333 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
334 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
335 EXPECT_EQ(0x43000U, frame->map_start);
336 EXPECT_EQ(0x44000U, frame->map_end);
337 EXPECT_EQ(0U, frame->map_load_bias);
338 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
339}
340
341TEST_F(UnwinderTest, disable_embedded_soname) {
342 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
343
344 regs_.set_pc(0x43000);
345 regs_.set_sp(0x10000);
346 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
347
348 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
349 unwinder.SetEmbeddedSoname(false);
350 unwinder.Unwind();
351 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
352
353 ASSERT_EQ(1U, unwinder.NumFrames());
354
355 auto* frame = &unwinder.frames()[0];
356 EXPECT_EQ(0U, frame->num);
357 EXPECT_EQ(0U, frame->rel_pc);
358 EXPECT_EQ(0x43000U, frame->pc);
359 EXPECT_EQ(0x10000U, frame->sp);
360 EXPECT_EQ("Frame0", frame->function_name);
361 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700362 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700363 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800364 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700365 EXPECT_EQ(0x43000U, frame->map_start);
366 EXPECT_EQ(0x44000U, frame->map_end);
367 EXPECT_EQ(0U, frame->map_load_bias);
368 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
369}
370
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700371// Verify that no attempt to continue after the step indicates it is done.
372TEST_F(UnwinderTest, no_frames_after_finished) {
373 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
374 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
375 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
376 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
377 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
378
Yabin Cui11e96fe2018-03-14 18:16:22 -0700379 regs_.set_pc(0x1000);
380 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700381 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
382 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
383 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
384
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800385 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700386 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800387 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700388
389 ASSERT_EQ(1U, unwinder.NumFrames());
390
391 auto* frame = &unwinder.frames()[0];
392 EXPECT_EQ(0U, frame->num);
393 EXPECT_EQ(0U, frame->rel_pc);
394 EXPECT_EQ(0x1000U, frame->pc);
395 EXPECT_EQ(0x10000U, frame->sp);
396 EXPECT_EQ("Frame0", frame->function_name);
397 EXPECT_EQ(0U, frame->function_offset);
398 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800399 EXPECT_EQ(0U, frame->map_elf_start_offset);
400 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700401 EXPECT_EQ(0x1000U, frame->map_start);
402 EXPECT_EQ(0x8000U, frame->map_end);
403 EXPECT_EQ(0U, frame->map_load_bias);
404 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
405}
406
407// Verify the maximum frames to save.
408TEST_F(UnwinderTest, max_frames) {
409 for (size_t i = 0; i < 30; i++) {
410 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
411 ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
412 }
413
Yabin Cui11e96fe2018-03-14 18:16:22 -0700414 regs_.set_pc(0x1000);
415 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700416
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800417 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700418 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800419 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700420
421 ASSERT_EQ(20U, unwinder.NumFrames());
422
423 for (size_t i = 0; i < 20; i++) {
424 auto* frame = &unwinder.frames()[i];
425 EXPECT_EQ(i, frame->num);
426 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
427 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
428 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
429 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
430 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
431 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800432 EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
433 EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700434 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
435 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
436 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
437 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
438 }
439}
440
441// Verify that initial map names frames are removed.
442TEST_F(UnwinderTest, verify_frames_skipped) {
443 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
444 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
445 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
446
Yabin Cui11e96fe2018-03-14 18:16:22 -0700447 regs_.set_pc(0x20000);
448 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700449 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
450 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
451 ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false));
452 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
453 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
454 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
455 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
456 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
457
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800458 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700459 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
460 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800461 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700462
463 ASSERT_EQ(3U, unwinder.NumFrames());
464
465 auto* frame = &unwinder.frames()[0];
466 EXPECT_EQ(0U, frame->num);
467 EXPECT_EQ(0U, frame->rel_pc);
468 EXPECT_EQ(0x1000U, frame->pc);
469 EXPECT_EQ(0x10050U, frame->sp);
470 EXPECT_EQ("Frame0", frame->function_name);
471 EXPECT_EQ(0U, frame->function_offset);
472 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800473 EXPECT_EQ(0U, frame->map_elf_start_offset);
474 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700475 EXPECT_EQ(0x1000U, frame->map_start);
476 EXPECT_EQ(0x8000U, frame->map_end);
477 EXPECT_EQ(0U, frame->map_load_bias);
478 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
479
480 frame = &unwinder.frames()[1];
481 EXPECT_EQ(1U, frame->num);
482 EXPECT_EQ(0x1000U, frame->rel_pc);
483 EXPECT_EQ(0x21000U, frame->pc);
484 EXPECT_EQ(0x10060U, frame->sp);
485 EXPECT_EQ("Frame1", frame->function_name);
486 EXPECT_EQ(1U, frame->function_offset);
487 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800488 EXPECT_EQ(0U, frame->map_elf_start_offset);
489 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700490 EXPECT_EQ(0x20000U, frame->map_start);
491 EXPECT_EQ(0x22000U, frame->map_end);
492 EXPECT_EQ(0U, frame->map_load_bias);
493 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
494
495 frame = &unwinder.frames()[2];
496 EXPECT_EQ(2U, frame->num);
497 EXPECT_EQ(0U, frame->rel_pc);
498 EXPECT_EQ(0x23000U, frame->pc);
499 EXPECT_EQ(0x10070U, frame->sp);
500 EXPECT_EQ("Frame2", frame->function_name);
501 EXPECT_EQ(2U, frame->function_offset);
502 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800503 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700504 EXPECT_EQ(0x23000U, frame->map_start);
505 EXPECT_EQ(0x24000U, frame->map_end);
506 EXPECT_EQ(0U, frame->map_load_bias);
507 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
508}
509
510// Verify SP in a non-existant map is okay.
511TEST_F(UnwinderTest, sp_not_in_map) {
512 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
513 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
514
Yabin Cui11e96fe2018-03-14 18:16:22 -0700515 regs_.set_pc(0x1000);
516 regs_.set_sp(0x63000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700517 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
518 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
519
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800520 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700521 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800522 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700523
524 ASSERT_EQ(2U, unwinder.NumFrames());
525
526 auto* frame = &unwinder.frames()[0];
527 EXPECT_EQ(0U, frame->num);
528 EXPECT_EQ(0U, frame->rel_pc);
529 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700530 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700531 EXPECT_EQ("Frame0", frame->function_name);
532 EXPECT_EQ(0U, frame->function_offset);
533 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800534 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700535 EXPECT_EQ(0x1000U, frame->map_start);
536 EXPECT_EQ(0x8000U, frame->map_end);
537 EXPECT_EQ(0U, frame->map_load_bias);
538 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
539
540 frame = &unwinder.frames()[1];
541 EXPECT_EQ(1U, frame->num);
542 EXPECT_EQ(0x1000U, frame->rel_pc);
543 EXPECT_EQ(0x21000U, frame->pc);
544 EXPECT_EQ(0x50020U, frame->sp);
545 EXPECT_EQ("Frame1", frame->function_name);
546 EXPECT_EQ(1U, frame->function_offset);
547 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800548 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700549 EXPECT_EQ(0x20000U, frame->map_start);
550 EXPECT_EQ(0x22000U, frame->map_end);
551 EXPECT_EQ(0U, frame->map_load_bias);
552 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
553}
554
555// Verify PC in a device stops the unwind.
556TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
557 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
558 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
559 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
560
Yabin Cui11e96fe2018-03-14 18:16:22 -0700561 regs_.set_pc(0x13000);
562 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700563 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
564 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
565 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
566
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800567 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700568 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800569 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700570
571 ASSERT_EQ(1U, unwinder.NumFrames());
572}
573
574// Verify SP in a device stops the unwind.
575TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
576 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
577 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
578 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
579
Yabin Cui11e96fe2018-03-14 18:16:22 -0700580 regs_.set_pc(0x1000);
581 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700582 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
583 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
584 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
585
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800586 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700587 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800588 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700589
590 ASSERT_EQ(1U, unwinder.NumFrames());
591}
592
593// Verify a no map info frame gets a frame.
594TEST_F(UnwinderTest, pc_without_map) {
595 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
596
Yabin Cui11e96fe2018-03-14 18:16:22 -0700597 regs_.set_pc(0x41000);
598 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700599
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800600 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700601 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800602 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700603
604 ASSERT_EQ(1U, unwinder.NumFrames());
605
606 auto* frame = &unwinder.frames()[0];
607 EXPECT_EQ(0U, frame->num);
608 EXPECT_EQ(0x41000U, frame->rel_pc);
609 EXPECT_EQ(0x41000U, frame->pc);
610 EXPECT_EQ(0x13000U, frame->sp);
611 EXPECT_EQ("", frame->function_name);
612 EXPECT_EQ(0U, frame->function_offset);
613 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800614 EXPECT_EQ(0U, frame->map_elf_start_offset);
615 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700616 EXPECT_EQ(0U, frame->map_start);
617 EXPECT_EQ(0U, frame->map_end);
618 EXPECT_EQ(0U, frame->map_load_bias);
619 EXPECT_EQ(0, frame->map_flags);
620}
621
622// Verify that a speculative frame is added.
623TEST_F(UnwinderTest, speculative_frame) {
624 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
625 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
626
627 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700628 regs_.set_pc(0);
629 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700630 regs_.FakeSetReturnAddress(0x1202);
631 regs_.FakeSetReturnAddressValid(true);
632
633 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
634 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
635
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800636 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700637 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800638 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700639
640 ASSERT_EQ(3U, unwinder.NumFrames());
641
642 auto* frame = &unwinder.frames()[0];
643 EXPECT_EQ(0U, frame->num);
644 EXPECT_EQ(0U, frame->rel_pc);
645 EXPECT_EQ(0U, frame->pc);
646 EXPECT_EQ(0x10000U, frame->sp);
647 EXPECT_EQ("", frame->function_name);
648 EXPECT_EQ(0U, frame->function_offset);
649 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800650 EXPECT_EQ(0U, frame->map_elf_start_offset);
651 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700652 EXPECT_EQ(0U, frame->map_start);
653 EXPECT_EQ(0U, frame->map_end);
654 EXPECT_EQ(0U, frame->map_load_bias);
655 EXPECT_EQ(0, frame->map_flags);
656
657 frame = &unwinder.frames()[1];
658 EXPECT_EQ(1U, frame->num);
659 EXPECT_EQ(0x200U, frame->rel_pc);
660 EXPECT_EQ(0x1200U, frame->pc);
661 EXPECT_EQ(0x10000U, frame->sp);
662 EXPECT_EQ("Frame0", frame->function_name);
663 EXPECT_EQ(0U, frame->function_offset);
664 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800665 EXPECT_EQ(0U, frame->map_elf_start_offset);
666 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700667 EXPECT_EQ(0x1000U, frame->map_start);
668 EXPECT_EQ(0x8000U, frame->map_end);
669 EXPECT_EQ(0U, frame->map_load_bias);
670 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
671
672 frame = &unwinder.frames()[2];
673 EXPECT_EQ(2U, frame->num);
674 EXPECT_EQ(0x100U, frame->rel_pc);
675 EXPECT_EQ(0x23100U, frame->pc);
676 EXPECT_EQ(0x10020U, frame->sp);
677 EXPECT_EQ("Frame1", frame->function_name);
678 EXPECT_EQ(1U, frame->function_offset);
679 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800680 EXPECT_EQ(0U, frame->map_elf_start_offset);
681 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700682 EXPECT_EQ(0x23000U, frame->map_start);
683 EXPECT_EQ(0x24000U, frame->map_end);
684 EXPECT_EQ(0U, frame->map_load_bias);
685 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
686}
687
688// Verify that a speculative frame is added then removed because no other
689// frames are added.
690TEST_F(UnwinderTest, speculative_frame_removed) {
691 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
692 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
693
694 // Fake as if code called a nullptr function.
Christopher Ferris065f1562018-12-13 09:33:45 -0800695 regs_.set_pc(0x20000);
696 regs_.set_sp(0x10000);
697 ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
698 regs_.FakeSetReturnAddress(0x12);
699 regs_.FakeSetReturnAddressValid(true);
700
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800701 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris065f1562018-12-13 09:33:45 -0800702 unwinder.Unwind();
703 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
704
705 ASSERT_EQ(2U, unwinder.NumFrames());
706
707 auto* frame = &unwinder.frames()[0];
708 EXPECT_EQ(0U, frame->num);
709 EXPECT_EQ(0U, frame->rel_pc);
710 EXPECT_EQ(0x20000U, frame->pc);
711 EXPECT_EQ(0x10000U, frame->sp);
712 EXPECT_EQ("Frame0", frame->function_name);
713 EXPECT_EQ(0U, frame->function_offset);
714 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800715 EXPECT_EQ(0U, frame->map_elf_start_offset);
716 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800717 EXPECT_EQ(0x20000U, frame->map_start);
718 EXPECT_EQ(0x22000U, frame->map_end);
719 EXPECT_EQ(0U, frame->map_load_bias);
720 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
721
722 frame = &unwinder.frames()[1];
723 EXPECT_EQ(1U, frame->num);
724 EXPECT_EQ(0U, frame->rel_pc);
725 EXPECT_EQ(0U, frame->pc);
726 EXPECT_EQ(0x10010U, frame->sp);
727 EXPECT_EQ("", frame->function_name);
728 EXPECT_EQ(0U, frame->function_offset);
729 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800730 EXPECT_EQ(0U, frame->map_elf_start_offset);
731 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800732 EXPECT_EQ(0U, frame->map_start);
733 EXPECT_EQ(0U, frame->map_end);
734 EXPECT_EQ(0U, frame->map_load_bias);
735 EXPECT_EQ(0, frame->map_flags);
736}
737
738// Verify that a speculative frame is added and left if there are only
739// two frames and the pc is in the middle nowhere.
740TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
741 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
742 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
743
744 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700745 regs_.set_pc(0);
746 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700747 regs_.FakeSetReturnAddress(0x1202);
748 regs_.FakeSetReturnAddressValid(true);
749
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800750 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700751 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800752 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700753
Christopher Ferris065f1562018-12-13 09:33:45 -0800754 ASSERT_EQ(2U, unwinder.NumFrames());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700755
756 auto* frame = &unwinder.frames()[0];
757 EXPECT_EQ(0U, frame->num);
758 EXPECT_EQ(0U, frame->rel_pc);
759 EXPECT_EQ(0U, frame->pc);
760 EXPECT_EQ(0x10000U, frame->sp);
761 EXPECT_EQ("", frame->function_name);
762 EXPECT_EQ(0U, frame->function_offset);
763 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800764 EXPECT_EQ(0U, frame->map_elf_start_offset);
765 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700766 EXPECT_EQ(0U, frame->map_start);
767 EXPECT_EQ(0U, frame->map_end);
768 EXPECT_EQ(0U, frame->map_load_bias);
769 EXPECT_EQ(0, frame->map_flags);
Christopher Ferris065f1562018-12-13 09:33:45 -0800770
771 frame = &unwinder.frames()[1];
772 EXPECT_EQ(1U, frame->num);
773 EXPECT_EQ(0x200U, frame->rel_pc);
774 EXPECT_EQ(0x1200U, frame->pc);
775 EXPECT_EQ(0x10000U, frame->sp);
776 EXPECT_EQ("Frame0", frame->function_name);
777 EXPECT_EQ(0U, frame->function_offset);
778 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800779 EXPECT_EQ(0U, frame->map_elf_start_offset);
780 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800781 EXPECT_EQ(0x1000U, frame->map_start);
782 EXPECT_EQ(0x8000U, frame->map_end);
783 EXPECT_EQ(0U, frame->map_load_bias);
784 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700785}
786
Florian Mayerc479e4e2019-01-23 13:35:40 +0000787// Verify that a speculative frame does not cause a crash when it wasn't
788// really added due to a filter.
789TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
790 regs_.set_pc(0x23000);
791 regs_.set_sp(0x10000);
792 regs_.FakeSetReturnAddress(0x23100);
793 regs_.FakeSetReturnAddressValid(true);
794
795 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
796
797 std::vector<std::string> skip_names{"libanother.so"};
798 unwinder.Unwind(&skip_names);
799 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
800
801 ASSERT_EQ(0U, unwinder.NumFrames());
802}
803
Christopher Ferrise69f4702017-10-19 16:08:58 -0700804// Verify that an unwind stops when a frame is in given suffix.
805TEST_F(UnwinderTest, map_ignore_suffixes) {
806 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
807 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
808 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
809 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
810
811 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700812 regs_.set_pc(0x1000);
813 regs_.set_sp(0x10000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700814 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
815 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
816 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
817
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800818 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700819 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700820 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800821 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700822
823 ASSERT_EQ(2U, unwinder.NumFrames());
824 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800825 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700826 ASSERT_TRUE(map_info != nullptr);
827 EXPECT_TRUE(map_info->elf == nullptr);
828
829 auto* frame = &unwinder.frames()[0];
830 EXPECT_EQ(0U, frame->num);
831 EXPECT_EQ(0U, frame->rel_pc);
832 EXPECT_EQ(0x1000U, frame->pc);
833 EXPECT_EQ(0x10000U, frame->sp);
834 EXPECT_EQ("Frame0", frame->function_name);
835 EXPECT_EQ(0U, frame->function_offset);
836 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800837 EXPECT_EQ(0U, frame->map_elf_start_offset);
838 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700839 EXPECT_EQ(0x1000U, frame->map_start);
840 EXPECT_EQ(0x8000U, frame->map_end);
841 EXPECT_EQ(0U, frame->map_load_bias);
842 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
843
844 frame = &unwinder.frames()[1];
845 EXPECT_EQ(1U, frame->num);
846 EXPECT_EQ(0x400U, frame->rel_pc);
847 EXPECT_EQ(0x43400U, frame->pc);
848 EXPECT_EQ(0x10010U, frame->sp);
849 EXPECT_EQ("Frame1", frame->function_name);
850 EXPECT_EQ(1U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700851 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
852 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800853 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700854 EXPECT_EQ(0x43000U, frame->map_start);
855 EXPECT_EQ(0x44000U, frame->map_end);
856 EXPECT_EQ(0U, frame->map_load_bias);
857 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
858}
859
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700860// Verify that an unwind stops when the sp and pc don't change.
861TEST_F(UnwinderTest, sp_pc_do_not_change) {
862 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
863 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
864 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
865 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
866 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
867
Yabin Cui11e96fe2018-03-14 18:16:22 -0700868 regs_.set_pc(0x1000);
869 regs_.set_sp(0x10000);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700870 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
871 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
872 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
873 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
874 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
875 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
876
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800877 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700878 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800879 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700880
881 ASSERT_EQ(3U, unwinder.NumFrames());
882
883 auto* frame = &unwinder.frames()[0];
884 EXPECT_EQ(0U, frame->num);
885 EXPECT_EQ(0U, frame->rel_pc);
886 EXPECT_EQ(0x1000U, frame->pc);
887 EXPECT_EQ(0x10000U, frame->sp);
888 EXPECT_EQ("Frame0", frame->function_name);
889 EXPECT_EQ(0U, frame->function_offset);
890 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800891 EXPECT_EQ(0U, frame->map_elf_start_offset);
892 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700893 EXPECT_EQ(0x1000U, frame->map_start);
894 EXPECT_EQ(0x8000U, frame->map_end);
895 EXPECT_EQ(0U, frame->map_load_bias);
896 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
897
898 frame = &unwinder.frames()[1];
899 EXPECT_EQ(1U, frame->num);
900 EXPECT_EQ(0x400U, frame->rel_pc);
901 EXPECT_EQ(0x33400U, frame->pc);
902 EXPECT_EQ(0x10010U, frame->sp);
903 EXPECT_EQ("Frame1", frame->function_name);
904 EXPECT_EQ(1U, frame->function_offset);
905 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800906 EXPECT_EQ(0U, frame->map_elf_start_offset);
907 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700908 EXPECT_EQ(0x33000U, frame->map_start);
909 EXPECT_EQ(0x34000U, frame->map_end);
910 EXPECT_EQ(0U, frame->map_load_bias);
911 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
912
913 frame = &unwinder.frames()[2];
914 EXPECT_EQ(2U, frame->num);
915 EXPECT_EQ(0x500U, frame->rel_pc);
916 EXPECT_EQ(0x33500U, frame->pc);
917 EXPECT_EQ(0x10020U, frame->sp);
918 EXPECT_EQ("Frame2", frame->function_name);
919 EXPECT_EQ(2U, frame->function_offset);
920 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800921 EXPECT_EQ(0U, frame->map_elf_start_offset);
922 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700923 EXPECT_EQ(0x33000U, frame->map_start);
924 EXPECT_EQ(0x34000U, frame->map_end);
925 EXPECT_EQ(0U, frame->map_load_bias);
926 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
927}
928
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800929TEST_F(UnwinderTest, dex_pc_in_map) {
930 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700931 regs_.set_pc(0x1000);
932 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800933 regs_.FakeSetDexPc(0xa3400);
934
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800935 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800936 unwinder.Unwind();
937 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
938
939 ASSERT_EQ(2U, unwinder.NumFrames());
940
941 auto* frame = &unwinder.frames()[0];
942 EXPECT_EQ(0U, frame->num);
943 EXPECT_EQ(0x400U, frame->rel_pc);
944 EXPECT_EQ(0xa3400U, frame->pc);
945 EXPECT_EQ(0x10000U, frame->sp);
946 EXPECT_EQ("", frame->function_name);
947 EXPECT_EQ(0U, frame->function_offset);
948 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800949 EXPECT_EQ(0U, frame->map_elf_start_offset);
950 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800951 EXPECT_EQ(0xa3000U, frame->map_start);
952 EXPECT_EQ(0xa4000U, frame->map_end);
953 EXPECT_EQ(0U, frame->map_load_bias);
954 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
955
956 frame = &unwinder.frames()[1];
957 EXPECT_EQ(1U, frame->num);
958 EXPECT_EQ(0U, frame->rel_pc);
959 EXPECT_EQ(0x1000U, frame->pc);
960 EXPECT_EQ(0x10000U, frame->sp);
961 EXPECT_EQ("Frame0", frame->function_name);
962 EXPECT_EQ(0U, frame->function_offset);
963 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800964 EXPECT_EQ(0U, frame->map_elf_start_offset);
965 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800966 EXPECT_EQ(0x1000U, frame->map_start);
967 EXPECT_EQ(0x8000U, frame->map_end);
968 EXPECT_EQ(0U, frame->map_load_bias);
969 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
970}
971
972TEST_F(UnwinderTest, dex_pc_not_in_map) {
973 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700974 regs_.set_pc(0x1000);
975 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800976 regs_.FakeSetDexPc(0x50000);
977
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800978 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800979 unwinder.Unwind();
980 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
981
982 ASSERT_EQ(2U, unwinder.NumFrames());
983
984 auto* frame = &unwinder.frames()[0];
985 EXPECT_EQ(0U, frame->num);
986 EXPECT_EQ(0x50000U, frame->rel_pc);
987 EXPECT_EQ(0x50000U, frame->pc);
988 EXPECT_EQ(0x10000U, frame->sp);
989 EXPECT_EQ("", frame->function_name);
990 EXPECT_EQ(0U, frame->function_offset);
991 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800992 EXPECT_EQ(0U, frame->map_elf_start_offset);
993 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800994 EXPECT_EQ(0U, frame->map_start);
995 EXPECT_EQ(0U, frame->map_end);
996 EXPECT_EQ(0U, frame->map_load_bias);
997 EXPECT_EQ(0, frame->map_flags);
998
999 frame = &unwinder.frames()[1];
1000 EXPECT_EQ(1U, frame->num);
1001 EXPECT_EQ(0U, frame->rel_pc);
1002 EXPECT_EQ(0x1000U, frame->pc);
1003 EXPECT_EQ(0x10000U, frame->sp);
1004 EXPECT_EQ("Frame0", frame->function_name);
1005 EXPECT_EQ(0U, frame->function_offset);
1006 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001007 EXPECT_EQ(0U, frame->map_elf_start_offset);
1008 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001009 EXPECT_EQ(0x1000U, frame->map_start);
1010 EXPECT_EQ(0x8000U, frame->map_end);
1011 EXPECT_EQ(0U, frame->map_load_bias);
1012 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1013}
1014
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001015TEST_F(UnwinderTest, dex_pc_multiple_frames) {
1016 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1017 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001018 regs_.set_pc(0x1000);
1019 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001020 regs_.FakeSetDexPc(0xa3400);
1021 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
1022 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1023
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001024 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001025 unwinder.Unwind();
1026 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1027
1028 ASSERT_EQ(3U, unwinder.NumFrames());
1029
1030 auto* frame = &unwinder.frames()[0];
1031 EXPECT_EQ(0U, frame->num);
1032 EXPECT_EQ(0x400U, frame->rel_pc);
1033 EXPECT_EQ(0xa3400U, frame->pc);
1034 EXPECT_EQ(0x10000U, frame->sp);
1035 EXPECT_EQ("", frame->function_name);
1036 EXPECT_EQ(0U, frame->function_offset);
1037 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001038 EXPECT_EQ(0U, frame->map_elf_start_offset);
1039 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001040 EXPECT_EQ(0xa3000U, frame->map_start);
1041 EXPECT_EQ(0xa4000U, frame->map_end);
1042 EXPECT_EQ(0U, frame->map_load_bias);
1043 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1044
1045 frame = &unwinder.frames()[1];
1046 EXPECT_EQ(1U, frame->num);
1047 EXPECT_EQ(0U, frame->rel_pc);
1048 EXPECT_EQ(0x1000U, frame->pc);
1049 EXPECT_EQ(0x10000U, frame->sp);
1050 EXPECT_EQ("Frame0", frame->function_name);
1051 EXPECT_EQ(0U, frame->function_offset);
1052 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001053 EXPECT_EQ(0U, frame->map_elf_start_offset);
1054 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001055 EXPECT_EQ(0x1000U, frame->map_start);
1056 EXPECT_EQ(0x8000U, frame->map_end);
1057 EXPECT_EQ(0U, frame->map_load_bias);
1058 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1059
1060 frame = &unwinder.frames()[2];
1061 EXPECT_EQ(2U, frame->num);
1062 EXPECT_EQ(0x400U, frame->rel_pc);
1063 EXPECT_EQ(0x33400U, frame->pc);
1064 EXPECT_EQ(0x10010U, frame->sp);
1065 EXPECT_EQ("Frame1", frame->function_name);
1066 EXPECT_EQ(1U, frame->function_offset);
1067 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001068 EXPECT_EQ(0U, frame->map_elf_start_offset);
1069 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001070 EXPECT_EQ(0x33000U, frame->map_start);
1071 EXPECT_EQ(0x34000U, frame->map_end);
1072 EXPECT_EQ(0U, frame->map_load_bias);
1073 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1074}
1075
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001076TEST_F(UnwinderTest, dex_pc_max_frames) {
1077 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1078 regs_.set_pc(0x1000);
1079 regs_.set_sp(0x10000);
1080 regs_.FakeSetDexPc(0xa3400);
1081
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001082 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001083 unwinder.Unwind();
1084 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
1085
1086 ASSERT_EQ(1U, unwinder.NumFrames());
1087
1088 auto* frame = &unwinder.frames()[0];
1089 EXPECT_EQ(0U, frame->num);
1090 EXPECT_EQ(0x400U, frame->rel_pc);
1091 EXPECT_EQ(0xa3400U, frame->pc);
1092 EXPECT_EQ(0x10000U, frame->sp);
1093 EXPECT_EQ("", frame->function_name);
1094 EXPECT_EQ(0U, frame->function_offset);
1095 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001096 EXPECT_EQ(0U, frame->map_elf_start_offset);
1097 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001098 EXPECT_EQ(0xa3000U, frame->map_start);
1099 EXPECT_EQ(0xa4000U, frame->map_end);
1100 EXPECT_EQ(0U, frame->map_load_bias);
1101 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1102}
1103
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001104// Verify format frame code.
1105TEST_F(UnwinderTest, format_frame_static) {
1106 FrameData frame;
1107 frame.num = 1;
1108 frame.rel_pc = 0x1000;
1109 frame.pc = 0x4000;
1110 frame.sp = 0x1000;
1111 frame.function_name = "function";
1112 frame.function_offset = 100;
1113 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001114 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001115 frame.map_start = 0x3000;
1116 frame.map_end = 0x6000;
1117 frame.map_flags = PROT_READ;
1118
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001119 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001120 Unwinder::FormatFrame(frame, false));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001121 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001122 Unwinder::FormatFrame(frame, true));
1123
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001124 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001125 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
1126 Unwinder::FormatFrame(frame, false));
1127 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)",
1128 Unwinder::FormatFrame(frame, true));
1129
1130 frame.function_offset = 0;
1131 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
1132 Unwinder::FormatFrame(frame, false));
1133 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", Unwinder::FormatFrame(frame, true));
1134
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001135 // Verify the function name is demangled.
1136 frame.function_name = "_ZN4funcEv";
1137 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())",
1138 Unwinder::FormatFrame(frame, false));
1139 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", Unwinder::FormatFrame(frame, true));
1140
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001141 frame.function_name = "";
1142 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", Unwinder::FormatFrame(frame, false));
1143 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", Unwinder::FormatFrame(frame, true));
1144
1145 frame.map_name = "";
1146 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", Unwinder::FormatFrame(frame, false));
1147 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", Unwinder::FormatFrame(frame, true));
1148
1149 frame.map_start = 0;
1150 frame.map_end = 0;
1151 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", Unwinder::FormatFrame(frame, false));
1152 EXPECT_EQ(" #01 pc 00001000 <unknown>", Unwinder::FormatFrame(frame, true));
1153}
1154
Christopher Ferris02fdb562017-12-08 15:04:49 -08001155static std::string ArchToString(ArchEnum arch) {
1156 if (arch == ARCH_ARM) {
1157 return "Arm";
1158 } else if (arch == ARCH_ARM64) {
1159 return "Arm64";
1160 } else if (arch == ARCH_X86) {
1161 return "X86";
1162 } else if (arch == ARCH_X86_64) {
1163 return "X86_64";
1164 } else {
1165 return "Unknown";
1166 }
1167}
1168
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001169// Verify format frame code.
1170TEST_F(UnwinderTest, format_frame) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001171 std::vector<Regs*> reg_list;
1172 RegsArm* arm = new RegsArm;
1173 arm->set_pc(0x2300);
1174 arm->set_sp(0x10000);
1175 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001176
Christopher Ferris02fdb562017-12-08 15:04:49 -08001177 RegsArm64* arm64 = new RegsArm64;
1178 arm64->set_pc(0x2300);
1179 arm64->set_sp(0x10000);
1180 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001181
Christopher Ferris02fdb562017-12-08 15:04:49 -08001182 RegsX86* x86 = new RegsX86;
1183 x86->set_pc(0x2300);
1184 x86->set_sp(0x10000);
1185 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001186
Christopher Ferris02fdb562017-12-08 15:04:49 -08001187 RegsX86_64* x86_64 = new RegsX86_64;
1188 x86_64->set_pc(0x2300);
1189 x86_64->set_sp(0x10000);
1190 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001191
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001192 RegsMips* mips = new RegsMips;
1193 mips->set_pc(0x2300);
1194 mips->set_sp(0x10000);
1195 reg_list.push_back(mips);
1196
1197 RegsMips64* mips64 = new RegsMips64;
1198 mips64->set_pc(0x2300);
1199 mips64->set_sp(0x10000);
1200 reg_list.push_back(mips64);
1201
Christopher Ferris02fdb562017-12-08 15:04:49 -08001202 for (auto regs : reg_list) {
1203 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001204
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001205 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001206 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001207
Christopher Ferris02fdb562017-12-08 15:04:49 -08001208 ASSERT_EQ(1U, unwinder.NumFrames());
1209 std::string expected;
1210 switch (regs->Arch()) {
1211 case ARCH_ARM:
1212 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001213 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001214 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1215 break;
1216 case ARCH_ARM64:
1217 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001218 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001219 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1220 break;
1221 default:
1222 expected = "";
1223 }
1224 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1225 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1226 delete regs;
1227 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001228}
1229
1230} // namespace unwindstack