blob: 869d1189ea7ac85983c9ef23750efae57481de1f [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);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700130 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700131 }
132
133 static MapsFake maps_;
134 static RegsFake regs_;
135 static std::shared_ptr<Memory> process_memory_;
136};
137
138MapsFake UnwinderTest::maps_;
139RegsFake UnwinderTest::regs_(5, 0);
140std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
141
142TEST_F(UnwinderTest, multiple_frames) {
143 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
144 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
145 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
146
147 regs_.FakeSetPc(0x1000);
148 regs_.FakeSetSp(0x10000);
149 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
150 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
151 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
152
153 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
154 unwinder.Unwind();
155
156 ASSERT_EQ(3U, unwinder.NumFrames());
157
158 auto* frame = &unwinder.frames()[0];
159 EXPECT_EQ(0U, frame->num);
160 EXPECT_EQ(0U, frame->rel_pc);
161 EXPECT_EQ(0x1000U, frame->pc);
162 EXPECT_EQ(0x10000U, frame->sp);
163 EXPECT_EQ("Frame0", frame->function_name);
164 EXPECT_EQ(0U, frame->function_offset);
165 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
166 EXPECT_EQ(0U, frame->map_offset);
167 EXPECT_EQ(0x1000U, frame->map_start);
168 EXPECT_EQ(0x8000U, frame->map_end);
169 EXPECT_EQ(0U, frame->map_load_bias);
170 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
171
172 frame = &unwinder.frames()[1];
173 EXPECT_EQ(1U, frame->num);
174 EXPECT_EQ(0x100U, frame->rel_pc);
175 EXPECT_EQ(0x1100U, frame->pc);
176 EXPECT_EQ(0x10010U, frame->sp);
177 EXPECT_EQ("Frame1", frame->function_name);
178 EXPECT_EQ(1U, frame->function_offset);
179 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
180 EXPECT_EQ(0U, frame->map_offset);
181 EXPECT_EQ(0x1000U, frame->map_start);
182 EXPECT_EQ(0x8000U, frame->map_end);
183 EXPECT_EQ(0U, frame->map_load_bias);
184 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
185
186 frame = &unwinder.frames()[2];
187 EXPECT_EQ(2U, frame->num);
188 EXPECT_EQ(0x200U, frame->rel_pc);
189 EXPECT_EQ(0x1200U, frame->pc);
190 EXPECT_EQ(0x10020U, frame->sp);
191 EXPECT_EQ("Frame2", frame->function_name);
192 EXPECT_EQ(2U, frame->function_offset);
193 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
194 EXPECT_EQ(0U, frame->map_offset);
195 EXPECT_EQ(0x1000U, frame->map_start);
196 EXPECT_EQ(0x8000U, frame->map_end);
197 EXPECT_EQ(0U, frame->map_load_bias);
198 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
199}
200
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700201TEST_F(UnwinderTest, non_zero_map_offset) {
202 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
203
204 regs_.FakeSetPc(0x43000);
205 regs_.FakeSetSp(0x10000);
206 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
207
208 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
209 unwinder.Unwind();
210
211 ASSERT_EQ(1U, unwinder.NumFrames());
212
213 auto* frame = &unwinder.frames()[0];
214 EXPECT_EQ(0U, frame->num);
215 EXPECT_EQ(0U, frame->rel_pc);
216 EXPECT_EQ(0x43000U, frame->pc);
217 EXPECT_EQ(0x10000U, frame->sp);
218 EXPECT_EQ("Frame0", frame->function_name);
219 EXPECT_EQ(0U, frame->function_offset);
220 EXPECT_EQ("/fake/fake.apk", frame->map_name);
221 EXPECT_EQ(0x1d000U, frame->map_offset);
222 EXPECT_EQ(0x43000U, frame->map_start);
223 EXPECT_EQ(0x44000U, frame->map_end);
224 EXPECT_EQ(0U, frame->map_load_bias);
225 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
226}
227
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700228// Verify that no attempt to continue after the step indicates it is done.
229TEST_F(UnwinderTest, no_frames_after_finished) {
230 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
231 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
232 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
233 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
234 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
235
236 regs_.FakeSetPc(0x1000);
237 regs_.FakeSetSp(0x10000);
238 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
239 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
240 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
241
242 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
243 unwinder.Unwind();
244
245 ASSERT_EQ(1U, unwinder.NumFrames());
246
247 auto* frame = &unwinder.frames()[0];
248 EXPECT_EQ(0U, frame->num);
249 EXPECT_EQ(0U, frame->rel_pc);
250 EXPECT_EQ(0x1000U, frame->pc);
251 EXPECT_EQ(0x10000U, frame->sp);
252 EXPECT_EQ("Frame0", frame->function_name);
253 EXPECT_EQ(0U, frame->function_offset);
254 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
255 EXPECT_EQ(0U, frame->map_offset);
256 EXPECT_EQ(0x1000U, frame->map_start);
257 EXPECT_EQ(0x8000U, frame->map_end);
258 EXPECT_EQ(0U, frame->map_load_bias);
259 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
260}
261
262// Verify the maximum frames to save.
263TEST_F(UnwinderTest, max_frames) {
264 for (size_t i = 0; i < 30; i++) {
265 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
266 ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
267 }
268
269 regs_.FakeSetPc(0x1000);
270 regs_.FakeSetSp(0x10000);
271
272 Unwinder unwinder(20, &maps_, &regs_, process_memory_);
273 unwinder.Unwind();
274
275 ASSERT_EQ(20U, unwinder.NumFrames());
276
277 for (size_t i = 0; i < 20; i++) {
278 auto* frame = &unwinder.frames()[i];
279 EXPECT_EQ(i, frame->num);
280 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
281 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
282 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
283 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
284 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
285 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
286 EXPECT_EQ(0U, frame->map_offset) << "Failed at frame " << i;
287 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
288 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
289 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
290 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
291 }
292}
293
294// Verify that initial map names frames are removed.
295TEST_F(UnwinderTest, verify_frames_skipped) {
296 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
297 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
298 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
299
300 regs_.FakeSetPc(0x20000);
301 regs_.FakeSetSp(0x10000);
302 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
303 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
304 ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false));
305 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
306 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
307 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
308 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
309 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
310
311 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700312 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
313 unwinder.Unwind(&skip_libs);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700314
315 ASSERT_EQ(3U, unwinder.NumFrames());
316
317 auto* frame = &unwinder.frames()[0];
318 EXPECT_EQ(0U, frame->num);
319 EXPECT_EQ(0U, frame->rel_pc);
320 EXPECT_EQ(0x1000U, frame->pc);
321 EXPECT_EQ(0x10050U, frame->sp);
322 EXPECT_EQ("Frame0", frame->function_name);
323 EXPECT_EQ(0U, frame->function_offset);
324 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
325 EXPECT_EQ(0U, frame->map_offset);
326 EXPECT_EQ(0x1000U, frame->map_start);
327 EXPECT_EQ(0x8000U, frame->map_end);
328 EXPECT_EQ(0U, frame->map_load_bias);
329 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
330
331 frame = &unwinder.frames()[1];
332 EXPECT_EQ(1U, frame->num);
333 EXPECT_EQ(0x1000U, frame->rel_pc);
334 EXPECT_EQ(0x21000U, frame->pc);
335 EXPECT_EQ(0x10060U, frame->sp);
336 EXPECT_EQ("Frame1", frame->function_name);
337 EXPECT_EQ(1U, frame->function_offset);
338 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
339 EXPECT_EQ(0U, frame->map_offset);
340 EXPECT_EQ(0x20000U, frame->map_start);
341 EXPECT_EQ(0x22000U, frame->map_end);
342 EXPECT_EQ(0U, frame->map_load_bias);
343 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
344
345 frame = &unwinder.frames()[2];
346 EXPECT_EQ(2U, frame->num);
347 EXPECT_EQ(0U, frame->rel_pc);
348 EXPECT_EQ(0x23000U, frame->pc);
349 EXPECT_EQ(0x10070U, frame->sp);
350 EXPECT_EQ("Frame2", frame->function_name);
351 EXPECT_EQ(2U, frame->function_offset);
352 EXPECT_EQ("/fake/libanother.so", frame->map_name);
353 EXPECT_EQ(0U, frame->map_offset);
354 EXPECT_EQ(0x23000U, frame->map_start);
355 EXPECT_EQ(0x24000U, frame->map_end);
356 EXPECT_EQ(0U, frame->map_load_bias);
357 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
358}
359
360// Verify SP in a non-existant map is okay.
361TEST_F(UnwinderTest, sp_not_in_map) {
362 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
363 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
364
365 regs_.FakeSetPc(0x1000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700366 regs_.FakeSetSp(0x63000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700367 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
368 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
369
370 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
371 unwinder.Unwind();
372
373 ASSERT_EQ(2U, unwinder.NumFrames());
374
375 auto* frame = &unwinder.frames()[0];
376 EXPECT_EQ(0U, frame->num);
377 EXPECT_EQ(0U, frame->rel_pc);
378 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700379 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700380 EXPECT_EQ("Frame0", frame->function_name);
381 EXPECT_EQ(0U, frame->function_offset);
382 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
383 EXPECT_EQ(0U, frame->map_offset);
384 EXPECT_EQ(0x1000U, frame->map_start);
385 EXPECT_EQ(0x8000U, frame->map_end);
386 EXPECT_EQ(0U, frame->map_load_bias);
387 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
388
389 frame = &unwinder.frames()[1];
390 EXPECT_EQ(1U, frame->num);
391 EXPECT_EQ(0x1000U, frame->rel_pc);
392 EXPECT_EQ(0x21000U, frame->pc);
393 EXPECT_EQ(0x50020U, frame->sp);
394 EXPECT_EQ("Frame1", frame->function_name);
395 EXPECT_EQ(1U, frame->function_offset);
396 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
397 EXPECT_EQ(0U, frame->map_offset);
398 EXPECT_EQ(0x20000U, frame->map_start);
399 EXPECT_EQ(0x22000U, frame->map_end);
400 EXPECT_EQ(0U, frame->map_load_bias);
401 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
402}
403
404// Verify PC in a device stops the unwind.
405TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
406 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
407 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
408 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
409
410 regs_.FakeSetPc(0x13000);
411 regs_.FakeSetSp(0x10000);
412 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
413 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
414 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
415
416 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
417 unwinder.Unwind();
418
419 ASSERT_EQ(1U, unwinder.NumFrames());
420}
421
422// Verify SP in a device stops the unwind.
423TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
424 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
425 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
426 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
427
428 regs_.FakeSetPc(0x1000);
429 regs_.FakeSetSp(0x13000);
430 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
431 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
432 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
433
434 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
435 unwinder.Unwind();
436
437 ASSERT_EQ(1U, unwinder.NumFrames());
438}
439
440// Verify a no map info frame gets a frame.
441TEST_F(UnwinderTest, pc_without_map) {
442 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
443
444 regs_.FakeSetPc(0x41000);
445 regs_.FakeSetSp(0x13000);
446
447 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
448 unwinder.Unwind();
449
450 ASSERT_EQ(1U, unwinder.NumFrames());
451
452 auto* frame = &unwinder.frames()[0];
453 EXPECT_EQ(0U, frame->num);
454 EXPECT_EQ(0x41000U, frame->rel_pc);
455 EXPECT_EQ(0x41000U, frame->pc);
456 EXPECT_EQ(0x13000U, frame->sp);
457 EXPECT_EQ("", frame->function_name);
458 EXPECT_EQ(0U, frame->function_offset);
459 EXPECT_EQ("", frame->map_name);
460 EXPECT_EQ(0U, frame->map_offset);
461 EXPECT_EQ(0U, frame->map_start);
462 EXPECT_EQ(0U, frame->map_end);
463 EXPECT_EQ(0U, frame->map_load_bias);
464 EXPECT_EQ(0, frame->map_flags);
465}
466
467// Verify that a speculative frame is added.
468TEST_F(UnwinderTest, speculative_frame) {
469 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
470 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
471
472 // Fake as if code called a nullptr function.
473 regs_.FakeSetPc(0);
474 regs_.FakeSetSp(0x10000);
475 regs_.FakeSetReturnAddress(0x1202);
476 regs_.FakeSetReturnAddressValid(true);
477
478 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
479 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
480
481 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
482 unwinder.Unwind();
483
484 ASSERT_EQ(3U, unwinder.NumFrames());
485
486 auto* frame = &unwinder.frames()[0];
487 EXPECT_EQ(0U, frame->num);
488 EXPECT_EQ(0U, frame->rel_pc);
489 EXPECT_EQ(0U, frame->pc);
490 EXPECT_EQ(0x10000U, frame->sp);
491 EXPECT_EQ("", frame->function_name);
492 EXPECT_EQ(0U, frame->function_offset);
493 EXPECT_EQ("", frame->map_name);
494 EXPECT_EQ(0U, frame->map_offset);
495 EXPECT_EQ(0U, frame->map_start);
496 EXPECT_EQ(0U, frame->map_end);
497 EXPECT_EQ(0U, frame->map_load_bias);
498 EXPECT_EQ(0, frame->map_flags);
499
500 frame = &unwinder.frames()[1];
501 EXPECT_EQ(1U, frame->num);
502 EXPECT_EQ(0x200U, frame->rel_pc);
503 EXPECT_EQ(0x1200U, frame->pc);
504 EXPECT_EQ(0x10000U, frame->sp);
505 EXPECT_EQ("Frame0", frame->function_name);
506 EXPECT_EQ(0U, frame->function_offset);
507 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
508 EXPECT_EQ(0U, frame->map_offset);
509 EXPECT_EQ(0x1000U, frame->map_start);
510 EXPECT_EQ(0x8000U, frame->map_end);
511 EXPECT_EQ(0U, frame->map_load_bias);
512 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
513
514 frame = &unwinder.frames()[2];
515 EXPECT_EQ(2U, frame->num);
516 EXPECT_EQ(0x100U, frame->rel_pc);
517 EXPECT_EQ(0x23100U, frame->pc);
518 EXPECT_EQ(0x10020U, frame->sp);
519 EXPECT_EQ("Frame1", frame->function_name);
520 EXPECT_EQ(1U, frame->function_offset);
521 EXPECT_EQ("/fake/libanother.so", frame->map_name);
522 EXPECT_EQ(0U, frame->map_offset);
523 EXPECT_EQ(0x23000U, frame->map_start);
524 EXPECT_EQ(0x24000U, frame->map_end);
525 EXPECT_EQ(0U, frame->map_load_bias);
526 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
527}
528
529// Verify that a speculative frame is added then removed because no other
530// frames are added.
531TEST_F(UnwinderTest, speculative_frame_removed) {
532 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
533 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
534
535 // Fake as if code called a nullptr function.
536 regs_.FakeSetPc(0);
537 regs_.FakeSetSp(0x10000);
538 regs_.FakeSetReturnAddress(0x1202);
539 regs_.FakeSetReturnAddressValid(true);
540
541 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
542 unwinder.Unwind();
543
544 ASSERT_EQ(1U, unwinder.NumFrames());
545
546 auto* frame = &unwinder.frames()[0];
547 EXPECT_EQ(0U, frame->num);
548 EXPECT_EQ(0U, frame->rel_pc);
549 EXPECT_EQ(0U, frame->pc);
550 EXPECT_EQ(0x10000U, frame->sp);
551 EXPECT_EQ("", frame->function_name);
552 EXPECT_EQ(0U, frame->function_offset);
553 EXPECT_EQ("", frame->map_name);
554 EXPECT_EQ(0U, frame->map_offset);
555 EXPECT_EQ(0U, frame->map_start);
556 EXPECT_EQ(0U, frame->map_end);
557 EXPECT_EQ(0U, frame->map_load_bias);
558 EXPECT_EQ(0, frame->map_flags);
559}
560
Christopher Ferrise69f4702017-10-19 16:08:58 -0700561// Verify that an unwind stops when a frame is in given suffix.
562TEST_F(UnwinderTest, map_ignore_suffixes) {
563 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
564 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
565 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
566 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
567
568 // Fake as if code called a nullptr function.
569 regs_.FakeSetPc(0x1000);
570 regs_.FakeSetSp(0x10000);
571 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
572 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
573 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
574
575 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700576 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700577 unwinder.Unwind(nullptr, &suffixes);
578
579 ASSERT_EQ(2U, unwinder.NumFrames());
580 // Make sure the elf was not initialized.
581 MapInfo* map_info = maps_.Find(0x53000);
582 ASSERT_TRUE(map_info != nullptr);
583 EXPECT_TRUE(map_info->elf == nullptr);
584
585 auto* frame = &unwinder.frames()[0];
586 EXPECT_EQ(0U, frame->num);
587 EXPECT_EQ(0U, frame->rel_pc);
588 EXPECT_EQ(0x1000U, frame->pc);
589 EXPECT_EQ(0x10000U, frame->sp);
590 EXPECT_EQ("Frame0", frame->function_name);
591 EXPECT_EQ(0U, frame->function_offset);
592 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
593 EXPECT_EQ(0U, frame->map_offset);
594 EXPECT_EQ(0x1000U, frame->map_start);
595 EXPECT_EQ(0x8000U, frame->map_end);
596 EXPECT_EQ(0U, frame->map_load_bias);
597 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
598
599 frame = &unwinder.frames()[1];
600 EXPECT_EQ(1U, frame->num);
601 EXPECT_EQ(0x400U, frame->rel_pc);
602 EXPECT_EQ(0x43400U, frame->pc);
603 EXPECT_EQ(0x10010U, frame->sp);
604 EXPECT_EQ("Frame1", frame->function_name);
605 EXPECT_EQ(1U, frame->function_offset);
606 EXPECT_EQ("/fake/fake.apk", frame->map_name);
607 EXPECT_EQ(0x1d000U, frame->map_offset);
608 EXPECT_EQ(0x43000U, frame->map_start);
609 EXPECT_EQ(0x44000U, frame->map_end);
610 EXPECT_EQ(0U, frame->map_load_bias);
611 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
612}
613
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700614// Verify that an unwind stops when the sp and pc don't change.
615TEST_F(UnwinderTest, sp_pc_do_not_change) {
616 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
617 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
618 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
619 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
620 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
621
622 regs_.FakeSetPc(0x1000);
623 regs_.FakeSetSp(0x10000);
624 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
625 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
626 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
627 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
628 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
629 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
630
631 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
632 unwinder.Unwind();
633
634 ASSERT_EQ(3U, unwinder.NumFrames());
635
636 auto* frame = &unwinder.frames()[0];
637 EXPECT_EQ(0U, frame->num);
638 EXPECT_EQ(0U, frame->rel_pc);
639 EXPECT_EQ(0x1000U, frame->pc);
640 EXPECT_EQ(0x10000U, frame->sp);
641 EXPECT_EQ("Frame0", frame->function_name);
642 EXPECT_EQ(0U, frame->function_offset);
643 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
644 EXPECT_EQ(0U, frame->map_offset);
645 EXPECT_EQ(0x1000U, frame->map_start);
646 EXPECT_EQ(0x8000U, frame->map_end);
647 EXPECT_EQ(0U, frame->map_load_bias);
648 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
649
650 frame = &unwinder.frames()[1];
651 EXPECT_EQ(1U, frame->num);
652 EXPECT_EQ(0x400U, frame->rel_pc);
653 EXPECT_EQ(0x33400U, frame->pc);
654 EXPECT_EQ(0x10010U, frame->sp);
655 EXPECT_EQ("Frame1", frame->function_name);
656 EXPECT_EQ(1U, frame->function_offset);
657 EXPECT_EQ("/fake/compressed.so", frame->map_name);
658 EXPECT_EQ(0U, frame->map_offset);
659 EXPECT_EQ(0x33000U, frame->map_start);
660 EXPECT_EQ(0x34000U, frame->map_end);
661 EXPECT_EQ(0U, frame->map_load_bias);
662 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
663
664 frame = &unwinder.frames()[2];
665 EXPECT_EQ(2U, frame->num);
666 EXPECT_EQ(0x500U, frame->rel_pc);
667 EXPECT_EQ(0x33500U, frame->pc);
668 EXPECT_EQ(0x10020U, frame->sp);
669 EXPECT_EQ("Frame2", frame->function_name);
670 EXPECT_EQ(2U, frame->function_offset);
671 EXPECT_EQ("/fake/compressed.so", frame->map_name);
672 EXPECT_EQ(0U, frame->map_offset);
673 EXPECT_EQ(0x33000U, frame->map_start);
674 EXPECT_EQ(0x34000U, frame->map_end);
675 EXPECT_EQ(0U, frame->map_load_bias);
676 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
677}
678
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700679// Verify format frame code.
680TEST_F(UnwinderTest, format_frame_static) {
681 FrameData frame;
682 frame.num = 1;
683 frame.rel_pc = 0x1000;
684 frame.pc = 0x4000;
685 frame.sp = 0x1000;
686 frame.function_name = "function";
687 frame.function_offset = 100;
688 frame.map_name = "/fake/libfake.so";
689 frame.map_offset = 0x2000;
690 frame.map_start = 0x3000;
691 frame.map_end = 0x6000;
692 frame.map_flags = PROT_READ;
693
694 EXPECT_EQ(" #01 pc 0000000000001000 (offset 0x2000) /fake/libfake.so (function+100)",
695 Unwinder::FormatFrame(frame, false));
696 EXPECT_EQ(" #01 pc 00001000 (offset 0x2000) /fake/libfake.so (function+100)",
697 Unwinder::FormatFrame(frame, true));
698
699 frame.map_offset = 0;
700 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
701 Unwinder::FormatFrame(frame, false));
702 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)",
703 Unwinder::FormatFrame(frame, true));
704
705 frame.function_offset = 0;
706 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
707 Unwinder::FormatFrame(frame, false));
708 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", Unwinder::FormatFrame(frame, true));
709
710 frame.function_name = "";
711 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", Unwinder::FormatFrame(frame, false));
712 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", Unwinder::FormatFrame(frame, true));
713
714 frame.map_name = "";
715 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", Unwinder::FormatFrame(frame, false));
716 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", Unwinder::FormatFrame(frame, true));
717
718 frame.map_start = 0;
719 frame.map_end = 0;
720 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", Unwinder::FormatFrame(frame, false));
721 EXPECT_EQ(" #01 pc 00001000 <unknown>", Unwinder::FormatFrame(frame, true));
722}
723
724// Verify format frame code.
725TEST_F(UnwinderTest, format_frame) {
726 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
727
728 regs_.FakeSetPc(0x2300);
729 regs_.FakeSetSp(0x10000);
730
731 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
732 unwinder.Unwind();
733
734 ASSERT_EQ(1U, unwinder.NumFrames());
735
736 regs_.FakeSetMachineType(EM_ARM);
737 EXPECT_EQ(" #00 pc 00001300 /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
738 regs_.FakeSetMachineType(EM_386);
739 EXPECT_EQ(" #00 pc 00001300 /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
740
741 regs_.FakeSetMachineType(EM_AARCH64);
742 EXPECT_EQ(" #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
743 regs_.FakeSetMachineType(EM_X86_64);
744 EXPECT_EQ(" #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
745
746 EXPECT_EQ("", unwinder.FormatFrame(1));
747}
748
749} // namespace unwindstack