blob: 8a90baec0ddc36ed9e575990dd8f1738a6135a30 [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>
31#include <unwindstack/Unwinder.h>
32
33#include "ElfFake.h"
34#include "MemoryFake.h"
35#include "RegsFake.h"
36
37namespace unwindstack {
38
39class MapsFake : public Maps {
40 public:
41 MapsFake() = default;
42 virtual ~MapsFake() = default;
43
44 bool Parse() { return true; }
45
46 void FakeClear() { maps_.clear(); }
47
48 void FakeAddMapInfo(const MapInfo& map_info) { maps_.push_back(map_info); }
49};
50
51class UnwinderTest : public ::testing::Test {
52 protected:
53 static void SetUpTestCase() {
54 maps_.FakeClear();
55 MapInfo info;
56 info.name = "/system/fake/libc.so";
57 info.start = 0x1000;
58 info.end = 0x8000;
59 info.offset = 0;
60 info.flags = PROT_READ | PROT_WRITE;
61 ElfFake* elf = new ElfFake(nullptr);
62 info.elf = elf;
63 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
64 info.elf_offset = 0;
65 maps_.FakeAddMapInfo(info);
66
67 info.name = "[stack]";
68 info.start = 0x10000;
69 info.end = 0x12000;
70 info.flags = PROT_READ | PROT_WRITE;
71 info.elf = nullptr;
72 maps_.FakeAddMapInfo(info);
73
74 info.name = "/dev/fake_device";
75 info.start = 0x13000;
76 info.end = 0x15000;
77 info.flags = PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP;
78 info.elf = nullptr;
79 maps_.FakeAddMapInfo(info);
80
81 info.name = "/system/fake/libunwind.so";
82 info.start = 0x20000;
83 info.end = 0x22000;
84 info.flags = PROT_READ | PROT_WRITE;
85 elf = new ElfFake(nullptr);
86 info.elf = elf;
87 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
88 maps_.FakeAddMapInfo(info);
89
90 info.name = "/fake/libanother.so";
91 info.start = 0x23000;
92 info.end = 0x24000;
93 info.flags = PROT_READ | PROT_WRITE;
94 elf = new ElfFake(nullptr);
95 info.elf = elf;
96 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
97 maps_.FakeAddMapInfo(info);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070098
Christopher Ferrise69f4702017-10-19 16:08:58 -070099 info.name = "/fake/compressed.so";
100 info.start = 0x33000;
101 info.end = 0x34000;
102 info.flags = PROT_READ | PROT_WRITE;
103 elf = new ElfFake(nullptr);
104 info.elf = elf;
105 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
106 maps_.FakeAddMapInfo(info);
107
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700108 info.name = "/fake/fake.apk";
109 info.start = 0x43000;
110 info.end = 0x44000;
111 info.offset = 0x1d000;
112 info.flags = PROT_READ | PROT_WRITE;
113 elf = new ElfFake(nullptr);
114 info.elf = elf;
115 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
116 maps_.FakeAddMapInfo(info);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700117
118 info.name = "/fake/fake.oat";
119 info.start = 0x53000;
120 info.end = 0x54000;
121 info.offset = 0;
122 info.flags = PROT_READ | PROT_WRITE;
123 info.elf = nullptr;
124 maps_.FakeAddMapInfo(info);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700125 }
126
127 void SetUp() override {
128 ElfInterfaceFake::FakeClear();
129 regs_.FakeSetMachineType(EM_ARM);
130 }
131
132 static MapsFake maps_;
133 static RegsFake regs_;
134 static std::shared_ptr<Memory> process_memory_;
135};
136
137MapsFake UnwinderTest::maps_;
138RegsFake UnwinderTest::regs_(5, 0);
139std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
140
141TEST_F(UnwinderTest, multiple_frames) {
142 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
143 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
144 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
145
146 regs_.FakeSetPc(0x1000);
147 regs_.FakeSetSp(0x10000);
148 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
149 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
150 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
151
152 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
153 unwinder.Unwind();
154
155 ASSERT_EQ(3U, unwinder.NumFrames());
156
157 auto* frame = &unwinder.frames()[0];
158 EXPECT_EQ(0U, frame->num);
159 EXPECT_EQ(0U, frame->rel_pc);
160 EXPECT_EQ(0x1000U, frame->pc);
161 EXPECT_EQ(0x10000U, frame->sp);
162 EXPECT_EQ("Frame0", frame->function_name);
163 EXPECT_EQ(0U, frame->function_offset);
164 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
165 EXPECT_EQ(0U, frame->map_offset);
166 EXPECT_EQ(0x1000U, frame->map_start);
167 EXPECT_EQ(0x8000U, frame->map_end);
168 EXPECT_EQ(0U, frame->map_load_bias);
169 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
170
171 frame = &unwinder.frames()[1];
172 EXPECT_EQ(1U, frame->num);
173 EXPECT_EQ(0x100U, frame->rel_pc);
174 EXPECT_EQ(0x1100U, frame->pc);
175 EXPECT_EQ(0x10010U, frame->sp);
176 EXPECT_EQ("Frame1", frame->function_name);
177 EXPECT_EQ(1U, frame->function_offset);
178 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
179 EXPECT_EQ(0U, frame->map_offset);
180 EXPECT_EQ(0x1000U, frame->map_start);
181 EXPECT_EQ(0x8000U, frame->map_end);
182 EXPECT_EQ(0U, frame->map_load_bias);
183 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
184
185 frame = &unwinder.frames()[2];
186 EXPECT_EQ(2U, frame->num);
187 EXPECT_EQ(0x200U, frame->rel_pc);
188 EXPECT_EQ(0x1200U, frame->pc);
189 EXPECT_EQ(0x10020U, frame->sp);
190 EXPECT_EQ("Frame2", frame->function_name);
191 EXPECT_EQ(2U, frame->function_offset);
192 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
193 EXPECT_EQ(0U, frame->map_offset);
194 EXPECT_EQ(0x1000U, frame->map_start);
195 EXPECT_EQ(0x8000U, frame->map_end);
196 EXPECT_EQ(0U, frame->map_load_bias);
197 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
198}
199
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700200TEST_F(UnwinderTest, non_zero_map_offset) {
201 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
202
203 regs_.FakeSetPc(0x43000);
204 regs_.FakeSetSp(0x10000);
205 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
206
207 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
208 unwinder.Unwind();
209
210 ASSERT_EQ(1U, unwinder.NumFrames());
211
212 auto* frame = &unwinder.frames()[0];
213 EXPECT_EQ(0U, frame->num);
214 EXPECT_EQ(0U, frame->rel_pc);
215 EXPECT_EQ(0x43000U, frame->pc);
216 EXPECT_EQ(0x10000U, frame->sp);
217 EXPECT_EQ("Frame0", frame->function_name);
218 EXPECT_EQ(0U, frame->function_offset);
219 EXPECT_EQ("/fake/fake.apk", frame->map_name);
220 EXPECT_EQ(0x1d000U, frame->map_offset);
221 EXPECT_EQ(0x43000U, frame->map_start);
222 EXPECT_EQ(0x44000U, frame->map_end);
223 EXPECT_EQ(0U, frame->map_load_bias);
224 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
225}
226
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700227// Verify that no attempt to continue after the step indicates it is done.
228TEST_F(UnwinderTest, no_frames_after_finished) {
229 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
230 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
231 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
232 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
233 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
234
235 regs_.FakeSetPc(0x1000);
236 regs_.FakeSetSp(0x10000);
237 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
238 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
239 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
240
241 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
242 unwinder.Unwind();
243
244 ASSERT_EQ(1U, unwinder.NumFrames());
245
246 auto* frame = &unwinder.frames()[0];
247 EXPECT_EQ(0U, frame->num);
248 EXPECT_EQ(0U, frame->rel_pc);
249 EXPECT_EQ(0x1000U, frame->pc);
250 EXPECT_EQ(0x10000U, frame->sp);
251 EXPECT_EQ("Frame0", frame->function_name);
252 EXPECT_EQ(0U, frame->function_offset);
253 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
254 EXPECT_EQ(0U, frame->map_offset);
255 EXPECT_EQ(0x1000U, frame->map_start);
256 EXPECT_EQ(0x8000U, frame->map_end);
257 EXPECT_EQ(0U, frame->map_load_bias);
258 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
259}
260
261// Verify the maximum frames to save.
262TEST_F(UnwinderTest, max_frames) {
263 for (size_t i = 0; i < 30; i++) {
264 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
265 ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
266 }
267
268 regs_.FakeSetPc(0x1000);
269 regs_.FakeSetSp(0x10000);
270
271 Unwinder unwinder(20, &maps_, &regs_, process_memory_);
272 unwinder.Unwind();
273
274 ASSERT_EQ(20U, unwinder.NumFrames());
275
276 for (size_t i = 0; i < 20; i++) {
277 auto* frame = &unwinder.frames()[i];
278 EXPECT_EQ(i, frame->num);
279 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
280 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
281 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
282 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
283 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
284 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
285 EXPECT_EQ(0U, frame->map_offset) << "Failed at frame " << i;
286 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
287 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
288 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
289 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
290 }
291}
292
293// Verify that initial map names frames are removed.
294TEST_F(UnwinderTest, verify_frames_skipped) {
295 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
296 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
297 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
298
299 regs_.FakeSetPc(0x20000);
300 regs_.FakeSetSp(0x10000);
301 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
302 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
303 ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false));
304 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
305 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
306 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
307 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
308 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
309
310 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700311 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
312 unwinder.Unwind(&skip_libs);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700313
314 ASSERT_EQ(3U, unwinder.NumFrames());
315
316 auto* frame = &unwinder.frames()[0];
317 EXPECT_EQ(0U, frame->num);
318 EXPECT_EQ(0U, frame->rel_pc);
319 EXPECT_EQ(0x1000U, frame->pc);
320 EXPECT_EQ(0x10050U, frame->sp);
321 EXPECT_EQ("Frame0", frame->function_name);
322 EXPECT_EQ(0U, frame->function_offset);
323 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
324 EXPECT_EQ(0U, frame->map_offset);
325 EXPECT_EQ(0x1000U, frame->map_start);
326 EXPECT_EQ(0x8000U, frame->map_end);
327 EXPECT_EQ(0U, frame->map_load_bias);
328 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
329
330 frame = &unwinder.frames()[1];
331 EXPECT_EQ(1U, frame->num);
332 EXPECT_EQ(0x1000U, frame->rel_pc);
333 EXPECT_EQ(0x21000U, frame->pc);
334 EXPECT_EQ(0x10060U, frame->sp);
335 EXPECT_EQ("Frame1", frame->function_name);
336 EXPECT_EQ(1U, frame->function_offset);
337 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
338 EXPECT_EQ(0U, frame->map_offset);
339 EXPECT_EQ(0x20000U, frame->map_start);
340 EXPECT_EQ(0x22000U, frame->map_end);
341 EXPECT_EQ(0U, frame->map_load_bias);
342 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
343
344 frame = &unwinder.frames()[2];
345 EXPECT_EQ(2U, frame->num);
346 EXPECT_EQ(0U, frame->rel_pc);
347 EXPECT_EQ(0x23000U, frame->pc);
348 EXPECT_EQ(0x10070U, frame->sp);
349 EXPECT_EQ("Frame2", frame->function_name);
350 EXPECT_EQ(2U, frame->function_offset);
351 EXPECT_EQ("/fake/libanother.so", frame->map_name);
352 EXPECT_EQ(0U, frame->map_offset);
353 EXPECT_EQ(0x23000U, frame->map_start);
354 EXPECT_EQ(0x24000U, frame->map_end);
355 EXPECT_EQ(0U, frame->map_load_bias);
356 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
357}
358
359// Verify SP in a non-existant map is okay.
360TEST_F(UnwinderTest, sp_not_in_map) {
361 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
362 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
363
364 regs_.FakeSetPc(0x1000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700365 regs_.FakeSetSp(0x63000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700366 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
367 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
368
369 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
370 unwinder.Unwind();
371
372 ASSERT_EQ(2U, unwinder.NumFrames());
373
374 auto* frame = &unwinder.frames()[0];
375 EXPECT_EQ(0U, frame->num);
376 EXPECT_EQ(0U, frame->rel_pc);
377 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700378 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700379 EXPECT_EQ("Frame0", frame->function_name);
380 EXPECT_EQ(0U, frame->function_offset);
381 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
382 EXPECT_EQ(0U, frame->map_offset);
383 EXPECT_EQ(0x1000U, frame->map_start);
384 EXPECT_EQ(0x8000U, frame->map_end);
385 EXPECT_EQ(0U, frame->map_load_bias);
386 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
387
388 frame = &unwinder.frames()[1];
389 EXPECT_EQ(1U, frame->num);
390 EXPECT_EQ(0x1000U, frame->rel_pc);
391 EXPECT_EQ(0x21000U, frame->pc);
392 EXPECT_EQ(0x50020U, frame->sp);
393 EXPECT_EQ("Frame1", frame->function_name);
394 EXPECT_EQ(1U, frame->function_offset);
395 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
396 EXPECT_EQ(0U, frame->map_offset);
397 EXPECT_EQ(0x20000U, frame->map_start);
398 EXPECT_EQ(0x22000U, frame->map_end);
399 EXPECT_EQ(0U, frame->map_load_bias);
400 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
401}
402
403// Verify PC in a device stops the unwind.
404TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
405 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
406 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
407 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
408
409 regs_.FakeSetPc(0x13000);
410 regs_.FakeSetSp(0x10000);
411 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
412 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
413 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
414
415 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
416 unwinder.Unwind();
417
418 ASSERT_EQ(1U, unwinder.NumFrames());
419}
420
421// Verify SP in a device stops the unwind.
422TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
423 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
424 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
425 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
426
427 regs_.FakeSetPc(0x1000);
428 regs_.FakeSetSp(0x13000);
429 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
430 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
431 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
432
433 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
434 unwinder.Unwind();
435
436 ASSERT_EQ(1U, unwinder.NumFrames());
437}
438
439// Verify a no map info frame gets a frame.
440TEST_F(UnwinderTest, pc_without_map) {
441 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
442
443 regs_.FakeSetPc(0x41000);
444 regs_.FakeSetSp(0x13000);
445
446 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
447 unwinder.Unwind();
448
449 ASSERT_EQ(1U, unwinder.NumFrames());
450
451 auto* frame = &unwinder.frames()[0];
452 EXPECT_EQ(0U, frame->num);
453 EXPECT_EQ(0x41000U, frame->rel_pc);
454 EXPECT_EQ(0x41000U, frame->pc);
455 EXPECT_EQ(0x13000U, frame->sp);
456 EXPECT_EQ("", frame->function_name);
457 EXPECT_EQ(0U, frame->function_offset);
458 EXPECT_EQ("", frame->map_name);
459 EXPECT_EQ(0U, frame->map_offset);
460 EXPECT_EQ(0U, frame->map_start);
461 EXPECT_EQ(0U, frame->map_end);
462 EXPECT_EQ(0U, frame->map_load_bias);
463 EXPECT_EQ(0, frame->map_flags);
464}
465
466// Verify that a speculative frame is added.
467TEST_F(UnwinderTest, speculative_frame) {
468 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
469 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
470
471 // Fake as if code called a nullptr function.
472 regs_.FakeSetPc(0);
473 regs_.FakeSetSp(0x10000);
474 regs_.FakeSetReturnAddress(0x1202);
475 regs_.FakeSetReturnAddressValid(true);
476
477 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
478 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
479
480 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
481 unwinder.Unwind();
482
483 ASSERT_EQ(3U, unwinder.NumFrames());
484
485 auto* frame = &unwinder.frames()[0];
486 EXPECT_EQ(0U, frame->num);
487 EXPECT_EQ(0U, frame->rel_pc);
488 EXPECT_EQ(0U, frame->pc);
489 EXPECT_EQ(0x10000U, frame->sp);
490 EXPECT_EQ("", frame->function_name);
491 EXPECT_EQ(0U, frame->function_offset);
492 EXPECT_EQ("", frame->map_name);
493 EXPECT_EQ(0U, frame->map_offset);
494 EXPECT_EQ(0U, frame->map_start);
495 EXPECT_EQ(0U, frame->map_end);
496 EXPECT_EQ(0U, frame->map_load_bias);
497 EXPECT_EQ(0, frame->map_flags);
498
499 frame = &unwinder.frames()[1];
500 EXPECT_EQ(1U, frame->num);
501 EXPECT_EQ(0x200U, frame->rel_pc);
502 EXPECT_EQ(0x1200U, frame->pc);
503 EXPECT_EQ(0x10000U, frame->sp);
504 EXPECT_EQ("Frame0", frame->function_name);
505 EXPECT_EQ(0U, frame->function_offset);
506 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
507 EXPECT_EQ(0U, frame->map_offset);
508 EXPECT_EQ(0x1000U, frame->map_start);
509 EXPECT_EQ(0x8000U, frame->map_end);
510 EXPECT_EQ(0U, frame->map_load_bias);
511 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
512
513 frame = &unwinder.frames()[2];
514 EXPECT_EQ(2U, frame->num);
515 EXPECT_EQ(0x100U, frame->rel_pc);
516 EXPECT_EQ(0x23100U, frame->pc);
517 EXPECT_EQ(0x10020U, frame->sp);
518 EXPECT_EQ("Frame1", frame->function_name);
519 EXPECT_EQ(1U, frame->function_offset);
520 EXPECT_EQ("/fake/libanother.so", frame->map_name);
521 EXPECT_EQ(0U, frame->map_offset);
522 EXPECT_EQ(0x23000U, frame->map_start);
523 EXPECT_EQ(0x24000U, frame->map_end);
524 EXPECT_EQ(0U, frame->map_load_bias);
525 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
526}
527
528// Verify that a speculative frame is added then removed because no other
529// frames are added.
530TEST_F(UnwinderTest, speculative_frame_removed) {
531 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
532 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
533
534 // Fake as if code called a nullptr function.
535 regs_.FakeSetPc(0);
536 regs_.FakeSetSp(0x10000);
537 regs_.FakeSetReturnAddress(0x1202);
538 regs_.FakeSetReturnAddressValid(true);
539
540 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
541 unwinder.Unwind();
542
543 ASSERT_EQ(1U, unwinder.NumFrames());
544
545 auto* frame = &unwinder.frames()[0];
546 EXPECT_EQ(0U, frame->num);
547 EXPECT_EQ(0U, frame->rel_pc);
548 EXPECT_EQ(0U, frame->pc);
549 EXPECT_EQ(0x10000U, frame->sp);
550 EXPECT_EQ("", frame->function_name);
551 EXPECT_EQ(0U, frame->function_offset);
552 EXPECT_EQ("", frame->map_name);
553 EXPECT_EQ(0U, frame->map_offset);
554 EXPECT_EQ(0U, frame->map_start);
555 EXPECT_EQ(0U, frame->map_end);
556 EXPECT_EQ(0U, frame->map_load_bias);
557 EXPECT_EQ(0, frame->map_flags);
558}
559
Christopher Ferrise69f4702017-10-19 16:08:58 -0700560// Verify that an unwind stops when a frame is in given suffix.
561TEST_F(UnwinderTest, map_ignore_suffixes) {
562 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
563 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
564 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
565 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
566
567 // Fake as if code called a nullptr function.
568 regs_.FakeSetPc(0x1000);
569 regs_.FakeSetSp(0x10000);
570 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
571 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
572 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
573
574 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700575 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700576 unwinder.Unwind(nullptr, &suffixes);
577
578 ASSERT_EQ(2U, unwinder.NumFrames());
579 // Make sure the elf was not initialized.
580 MapInfo* map_info = maps_.Find(0x53000);
581 ASSERT_TRUE(map_info != nullptr);
582 EXPECT_TRUE(map_info->elf == nullptr);
583
584 auto* frame = &unwinder.frames()[0];
585 EXPECT_EQ(0U, frame->num);
586 EXPECT_EQ(0U, frame->rel_pc);
587 EXPECT_EQ(0x1000U, frame->pc);
588 EXPECT_EQ(0x10000U, frame->sp);
589 EXPECT_EQ("Frame0", frame->function_name);
590 EXPECT_EQ(0U, frame->function_offset);
591 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
592 EXPECT_EQ(0U, frame->map_offset);
593 EXPECT_EQ(0x1000U, frame->map_start);
594 EXPECT_EQ(0x8000U, frame->map_end);
595 EXPECT_EQ(0U, frame->map_load_bias);
596 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
597
598 frame = &unwinder.frames()[1];
599 EXPECT_EQ(1U, frame->num);
600 EXPECT_EQ(0x400U, frame->rel_pc);
601 EXPECT_EQ(0x43400U, frame->pc);
602 EXPECT_EQ(0x10010U, frame->sp);
603 EXPECT_EQ("Frame1", frame->function_name);
604 EXPECT_EQ(1U, frame->function_offset);
605 EXPECT_EQ("/fake/fake.apk", frame->map_name);
606 EXPECT_EQ(0x1d000U, frame->map_offset);
607 EXPECT_EQ(0x43000U, frame->map_start);
608 EXPECT_EQ(0x44000U, frame->map_end);
609 EXPECT_EQ(0U, frame->map_load_bias);
610 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
611}
612
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700613// Verify format frame code.
614TEST_F(UnwinderTest, format_frame_static) {
615 FrameData frame;
616 frame.num = 1;
617 frame.rel_pc = 0x1000;
618 frame.pc = 0x4000;
619 frame.sp = 0x1000;
620 frame.function_name = "function";
621 frame.function_offset = 100;
622 frame.map_name = "/fake/libfake.so";
623 frame.map_offset = 0x2000;
624 frame.map_start = 0x3000;
625 frame.map_end = 0x6000;
626 frame.map_flags = PROT_READ;
627
628 EXPECT_EQ(" #01 pc 0000000000001000 (offset 0x2000) /fake/libfake.so (function+100)",
629 Unwinder::FormatFrame(frame, false));
630 EXPECT_EQ(" #01 pc 00001000 (offset 0x2000) /fake/libfake.so (function+100)",
631 Unwinder::FormatFrame(frame, true));
632
633 frame.map_offset = 0;
634 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
635 Unwinder::FormatFrame(frame, false));
636 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)",
637 Unwinder::FormatFrame(frame, true));
638
639 frame.function_offset = 0;
640 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
641 Unwinder::FormatFrame(frame, false));
642 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", Unwinder::FormatFrame(frame, true));
643
644 frame.function_name = "";
645 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", Unwinder::FormatFrame(frame, false));
646 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", Unwinder::FormatFrame(frame, true));
647
648 frame.map_name = "";
649 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", Unwinder::FormatFrame(frame, false));
650 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", Unwinder::FormatFrame(frame, true));
651
652 frame.map_start = 0;
653 frame.map_end = 0;
654 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", Unwinder::FormatFrame(frame, false));
655 EXPECT_EQ(" #01 pc 00001000 <unknown>", Unwinder::FormatFrame(frame, true));
656}
657
658// Verify format frame code.
659TEST_F(UnwinderTest, format_frame) {
660 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
661
662 regs_.FakeSetPc(0x2300);
663 regs_.FakeSetSp(0x10000);
664
665 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
666 unwinder.Unwind();
667
668 ASSERT_EQ(1U, unwinder.NumFrames());
669
670 regs_.FakeSetMachineType(EM_ARM);
671 EXPECT_EQ(" #00 pc 00001300 /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
672 regs_.FakeSetMachineType(EM_386);
673 EXPECT_EQ(" #00 pc 00001300 /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
674
675 regs_.FakeSetMachineType(EM_AARCH64);
676 EXPECT_EQ(" #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
677 regs_.FakeSetMachineType(EM_X86_64);
678 EXPECT_EQ(" #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
679
680 EXPECT_EQ("", unwinder.FormatFrame(1));
681}
682
683} // namespace unwindstack