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