blob: 831d3b5b5e5979718555c0504e83aaf0193e7df1 [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
45class MapsFake : public Maps {
46 public:
47 MapsFake() = default;
48 virtual ~MapsFake() = default;
49
50 bool Parse() { return true; }
51
52 void FakeClear() { maps_.clear(); }
53
Christopher Ferrisbe788d82017-11-27 14:50:38 -080054 void FakeAddMapInfo(MapInfo* map_info) { maps_.push_back(map_info); }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070055};
56
57class UnwinderTest : public ::testing::Test {
58 protected:
59 static void SetUpTestCase() {
60 maps_.FakeClear();
Christopher Ferris9d5712c2018-10-01 21:01:09 -070061 MapInfo* info =
62 new MapInfo(&maps_, 0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so");
Christopher Ferris02fdb562017-12-08 15:04:49 -080063 ElfFake* elf = new ElfFake(new MemoryFake);
Christopher Ferris0b79ae12018-01-25 12:15:56 -080064 info->elf.reset(elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070065 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070066 maps_.FakeAddMapInfo(info);
67
Christopher Ferris9d5712c2018-10-01 21:01:09 -070068 info = new MapInfo(&maps_, 0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070069 maps_.FakeAddMapInfo(info);
70
Christopher Ferris9d5712c2018-10-01 21:01:09 -070071 info = new MapInfo(&maps_, 0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
Christopher Ferrisbe788d82017-11-27 14:50:38 -080072 "/dev/fake_device");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070073 maps_.FakeAddMapInfo(info);
74
Christopher Ferris9d5712c2018-10-01 21:01:09 -070075 info = new MapInfo(&maps_, 0x20000, 0x22000, 0, PROT_READ | PROT_WRITE,
76 "/system/fake/libunwind.so");
Christopher Ferris02fdb562017-12-08 15:04:49 -080077 elf = new ElfFake(new MemoryFake);
Christopher Ferris0b79ae12018-01-25 12:15:56 -080078 info->elf.reset(elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070079 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
80 maps_.FakeAddMapInfo(info);
81
Christopher Ferris9d5712c2018-10-01 21:01:09 -070082 info = new MapInfo(&maps_, 0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so");
Christopher Ferris02fdb562017-12-08 15:04:49 -080083 elf = new ElfFake(new MemoryFake);
Christopher Ferris0b79ae12018-01-25 12:15:56 -080084 info->elf.reset(elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070085 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
86 maps_.FakeAddMapInfo(info);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070087
Christopher Ferris9d5712c2018-10-01 21:01:09 -070088 info = new MapInfo(&maps_, 0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so");
Christopher Ferris02fdb562017-12-08 15:04:49 -080089 elf = new ElfFake(new MemoryFake);
Christopher Ferris0b79ae12018-01-25 12:15:56 -080090 info->elf.reset(elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070091 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
92 maps_.FakeAddMapInfo(info);
93
Christopher Ferris9d5712c2018-10-01 21:01:09 -070094 info = new MapInfo(&maps_, 0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk");
Christopher Ferris02fdb562017-12-08 15:04:49 -080095 elf = new ElfFake(new MemoryFake);
Christopher Ferris0b79ae12018-01-25 12:15:56 -080096 info->elf.reset(elf);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070097 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
98 maps_.FakeAddMapInfo(info);
Christopher Ferrise69f4702017-10-19 16:08:58 -070099
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700100 info = new MapInfo(&maps_, 0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
Christopher Ferrise69f4702017-10-19 16:08:58 -0700101 maps_.FakeAddMapInfo(info);
Christopher Ferris02fdb562017-12-08 15:04:49 -0800102
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700103 info = new MapInfo(&maps_, 0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
104 "/fake/fake.vdex");
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800105 info->load_bias = 0;
106 maps_.FakeAddMapInfo(info);
107
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700108 info = new MapInfo(&maps_, 0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800109 "/fake/fake_load_bias.so");
110 elf = new ElfFake(new MemoryFake);
111 info->elf.reset(elf);
112 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
113 elf->FakeSetLoadBias(0x5000);
114 maps_.FakeAddMapInfo(info);
115
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700116 info = new MapInfo(&maps_, 0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800117 "/fake/fake_offset.oat");
118 elf = new ElfFake(new MemoryFake);
119 info->elf.reset(elf);
120 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
121 info->elf_offset = 0x8000;
122 maps_.FakeAddMapInfo(info);
123
Christopher Ferris02fdb562017-12-08 15:04:49 -0800124 process_memory_.reset(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700125 }
126
127 void SetUp() override {
128 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800129 regs_.FakeSetArch(ARCH_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_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700139RegsFake UnwinderTest::regs_(5);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700140std::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
Yabin Cui11e96fe2018-03-14 18:16:22 -0700147 regs_.set_pc(0x1000);
148 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700149 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();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800155 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700156
157 ASSERT_EQ(3U, unwinder.NumFrames());
158
159 auto* frame = &unwinder.frames()[0];
160 EXPECT_EQ(0U, frame->num);
161 EXPECT_EQ(0U, frame->rel_pc);
162 EXPECT_EQ(0x1000U, frame->pc);
163 EXPECT_EQ(0x10000U, frame->sp);
164 EXPECT_EQ("Frame0", frame->function_name);
165 EXPECT_EQ(0U, frame->function_offset);
166 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
167 EXPECT_EQ(0U, frame->map_offset);
168 EXPECT_EQ(0x1000U, frame->map_start);
169 EXPECT_EQ(0x8000U, frame->map_end);
170 EXPECT_EQ(0U, frame->map_load_bias);
171 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
172
173 frame = &unwinder.frames()[1];
174 EXPECT_EQ(1U, frame->num);
175 EXPECT_EQ(0x100U, frame->rel_pc);
176 EXPECT_EQ(0x1100U, frame->pc);
177 EXPECT_EQ(0x10010U, frame->sp);
178 EXPECT_EQ("Frame1", frame->function_name);
179 EXPECT_EQ(1U, frame->function_offset);
180 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
181 EXPECT_EQ(0U, frame->map_offset);
182 EXPECT_EQ(0x1000U, frame->map_start);
183 EXPECT_EQ(0x8000U, frame->map_end);
184 EXPECT_EQ(0U, frame->map_load_bias);
185 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
186
187 frame = &unwinder.frames()[2];
188 EXPECT_EQ(2U, frame->num);
189 EXPECT_EQ(0x200U, frame->rel_pc);
190 EXPECT_EQ(0x1200U, frame->pc);
191 EXPECT_EQ(0x10020U, frame->sp);
192 EXPECT_EQ("Frame2", frame->function_name);
193 EXPECT_EQ(2U, frame->function_offset);
194 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
195 EXPECT_EQ(0U, frame->map_offset);
196 EXPECT_EQ(0x1000U, frame->map_start);
197 EXPECT_EQ(0x8000U, frame->map_end);
198 EXPECT_EQ(0U, frame->map_load_bias);
199 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
200}
201
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800202TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
203 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
204 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
205 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
206
Yabin Cui11e96fe2018-03-14 18:16:22 -0700207 regs_.set_pc(0x1000);
208 regs_.set_sp(0x10000);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800209 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
210 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
211 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
212
213 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
214 unwinder.SetResolveNames(false);
215 unwinder.Unwind();
216 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
217
218 ASSERT_EQ(3U, unwinder.NumFrames());
219
220 auto* frame = &unwinder.frames()[0];
221 EXPECT_EQ(0U, frame->num);
222 EXPECT_EQ(0U, frame->rel_pc);
223 EXPECT_EQ(0x1000U, frame->pc);
224 EXPECT_EQ(0x10000U, frame->sp);
225 EXPECT_EQ("", frame->function_name);
226 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000227 EXPECT_EQ("", frame->map_name);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800228 EXPECT_EQ(0U, frame->map_offset);
229 EXPECT_EQ(0x1000U, frame->map_start);
230 EXPECT_EQ(0x8000U, frame->map_end);
231 EXPECT_EQ(0U, frame->map_load_bias);
232 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
233
234 frame = &unwinder.frames()[1];
235 EXPECT_EQ(1U, frame->num);
236 EXPECT_EQ(0x100U, frame->rel_pc);
237 EXPECT_EQ(0x1100U, frame->pc);
238 EXPECT_EQ(0x10010U, frame->sp);
239 EXPECT_EQ("", frame->function_name);
240 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000241 EXPECT_EQ("", frame->map_name);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800242 EXPECT_EQ(0U, frame->map_offset);
243 EXPECT_EQ(0x1000U, frame->map_start);
244 EXPECT_EQ(0x8000U, frame->map_end);
245 EXPECT_EQ(0U, frame->map_load_bias);
246 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
247
248 frame = &unwinder.frames()[2];
249 EXPECT_EQ(2U, frame->num);
250 EXPECT_EQ(0x200U, frame->rel_pc);
251 EXPECT_EQ(0x1200U, frame->pc);
252 EXPECT_EQ(0x10020U, frame->sp);
253 EXPECT_EQ("", frame->function_name);
254 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000255 EXPECT_EQ("", frame->map_name);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800256 EXPECT_EQ(0U, frame->map_offset);
257 EXPECT_EQ(0x1000U, frame->map_start);
258 EXPECT_EQ(0x8000U, frame->map_end);
259 EXPECT_EQ(0U, frame->map_load_bias);
260 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
261}
262
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800263TEST_F(UnwinderTest, non_zero_load_bias) {
264 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
265
Yabin Cui11e96fe2018-03-14 18:16:22 -0700266 regs_.set_pc(0xa5500);
267 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800268 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
269
270 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
271 unwinder.Unwind();
272 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
273
274 ASSERT_EQ(1U, unwinder.NumFrames());
275
276 auto* frame = &unwinder.frames()[0];
277 EXPECT_EQ(0U, frame->num);
278 EXPECT_EQ(0x5500U, frame->rel_pc);
279 EXPECT_EQ(0xa5500U, frame->pc);
280 EXPECT_EQ(0x10000U, frame->sp);
281 EXPECT_EQ("Frame0", frame->function_name);
282 EXPECT_EQ(0U, frame->function_offset);
283 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
284 EXPECT_EQ(0U, frame->map_offset);
285 EXPECT_EQ(0xa5000U, frame->map_start);
286 EXPECT_EQ(0xa6000U, frame->map_end);
287 EXPECT_EQ(0x5000U, frame->map_load_bias);
288 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
289}
290
291TEST_F(UnwinderTest, non_zero_elf_offset) {
292 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
293
Yabin Cui11e96fe2018-03-14 18:16:22 -0700294 regs_.set_pc(0xa7500);
295 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800296 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
297
298 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
299 unwinder.Unwind();
300 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
301
302 ASSERT_EQ(1U, unwinder.NumFrames());
303
304 auto* frame = &unwinder.frames()[0];
305 EXPECT_EQ(0U, frame->num);
306 EXPECT_EQ(0x8500U, frame->rel_pc);
307 EXPECT_EQ(0xa7500U, frame->pc);
308 EXPECT_EQ(0x10000U, frame->sp);
309 EXPECT_EQ("Frame0", frame->function_name);
310 EXPECT_EQ(0U, frame->function_offset);
311 EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
312 EXPECT_EQ(0U, frame->map_offset);
313 EXPECT_EQ(0xa7000U, frame->map_start);
314 EXPECT_EQ(0xa8000U, frame->map_end);
315 EXPECT_EQ(0U, frame->map_load_bias);
316 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
317}
318
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700319TEST_F(UnwinderTest, non_zero_map_offset) {
320 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
321
Yabin Cui11e96fe2018-03-14 18:16:22 -0700322 regs_.set_pc(0x43000);
323 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700324 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
325
326 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
327 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800328 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700329
330 ASSERT_EQ(1U, unwinder.NumFrames());
331
332 auto* frame = &unwinder.frames()[0];
333 EXPECT_EQ(0U, frame->num);
334 EXPECT_EQ(0U, frame->rel_pc);
335 EXPECT_EQ(0x43000U, frame->pc);
336 EXPECT_EQ(0x10000U, frame->sp);
337 EXPECT_EQ("Frame0", frame->function_name);
338 EXPECT_EQ(0U, frame->function_offset);
339 EXPECT_EQ("/fake/fake.apk", frame->map_name);
340 EXPECT_EQ(0x1d000U, frame->map_offset);
341 EXPECT_EQ(0x43000U, frame->map_start);
342 EXPECT_EQ(0x44000U, frame->map_end);
343 EXPECT_EQ(0U, frame->map_load_bias);
344 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
345}
346
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700347// Verify that no attempt to continue after the step indicates it is done.
348TEST_F(UnwinderTest, no_frames_after_finished) {
349 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
350 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
351 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
352 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
353 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
354
Yabin Cui11e96fe2018-03-14 18:16:22 -0700355 regs_.set_pc(0x1000);
356 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700357 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
358 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
359 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
360
361 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
362 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800363 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700364
365 ASSERT_EQ(1U, unwinder.NumFrames());
366
367 auto* frame = &unwinder.frames()[0];
368 EXPECT_EQ(0U, frame->num);
369 EXPECT_EQ(0U, frame->rel_pc);
370 EXPECT_EQ(0x1000U, frame->pc);
371 EXPECT_EQ(0x10000U, frame->sp);
372 EXPECT_EQ("Frame0", frame->function_name);
373 EXPECT_EQ(0U, frame->function_offset);
374 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
375 EXPECT_EQ(0U, frame->map_offset);
376 EXPECT_EQ(0x1000U, frame->map_start);
377 EXPECT_EQ(0x8000U, frame->map_end);
378 EXPECT_EQ(0U, frame->map_load_bias);
379 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
380}
381
382// Verify the maximum frames to save.
383TEST_F(UnwinderTest, max_frames) {
384 for (size_t i = 0; i < 30; i++) {
385 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
386 ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
387 }
388
Yabin Cui11e96fe2018-03-14 18:16:22 -0700389 regs_.set_pc(0x1000);
390 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700391
392 Unwinder unwinder(20, &maps_, &regs_, process_memory_);
393 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800394 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700395
396 ASSERT_EQ(20U, unwinder.NumFrames());
397
398 for (size_t i = 0; i < 20; i++) {
399 auto* frame = &unwinder.frames()[i];
400 EXPECT_EQ(i, frame->num);
401 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
402 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
403 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
404 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
405 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
406 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
407 EXPECT_EQ(0U, frame->map_offset) << "Failed at frame " << i;
408 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
409 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
410 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
411 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
412 }
413}
414
415// Verify that initial map names frames are removed.
416TEST_F(UnwinderTest, verify_frames_skipped) {
417 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
418 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
419 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
420
Yabin Cui11e96fe2018-03-14 18:16:22 -0700421 regs_.set_pc(0x20000);
422 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700423 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
424 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
425 ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false));
426 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
427 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
428 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
429 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
430 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
431
432 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700433 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
434 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800435 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700436
437 ASSERT_EQ(3U, unwinder.NumFrames());
438
439 auto* frame = &unwinder.frames()[0];
440 EXPECT_EQ(0U, frame->num);
441 EXPECT_EQ(0U, frame->rel_pc);
442 EXPECT_EQ(0x1000U, frame->pc);
443 EXPECT_EQ(0x10050U, frame->sp);
444 EXPECT_EQ("Frame0", frame->function_name);
445 EXPECT_EQ(0U, frame->function_offset);
446 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
447 EXPECT_EQ(0U, frame->map_offset);
448 EXPECT_EQ(0x1000U, frame->map_start);
449 EXPECT_EQ(0x8000U, frame->map_end);
450 EXPECT_EQ(0U, frame->map_load_bias);
451 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
452
453 frame = &unwinder.frames()[1];
454 EXPECT_EQ(1U, frame->num);
455 EXPECT_EQ(0x1000U, frame->rel_pc);
456 EXPECT_EQ(0x21000U, frame->pc);
457 EXPECT_EQ(0x10060U, frame->sp);
458 EXPECT_EQ("Frame1", frame->function_name);
459 EXPECT_EQ(1U, frame->function_offset);
460 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
461 EXPECT_EQ(0U, frame->map_offset);
462 EXPECT_EQ(0x20000U, frame->map_start);
463 EXPECT_EQ(0x22000U, frame->map_end);
464 EXPECT_EQ(0U, frame->map_load_bias);
465 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
466
467 frame = &unwinder.frames()[2];
468 EXPECT_EQ(2U, frame->num);
469 EXPECT_EQ(0U, frame->rel_pc);
470 EXPECT_EQ(0x23000U, frame->pc);
471 EXPECT_EQ(0x10070U, frame->sp);
472 EXPECT_EQ("Frame2", frame->function_name);
473 EXPECT_EQ(2U, frame->function_offset);
474 EXPECT_EQ("/fake/libanother.so", frame->map_name);
475 EXPECT_EQ(0U, frame->map_offset);
476 EXPECT_EQ(0x23000U, frame->map_start);
477 EXPECT_EQ(0x24000U, frame->map_end);
478 EXPECT_EQ(0U, frame->map_load_bias);
479 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
480}
481
482// Verify SP in a non-existant map is okay.
483TEST_F(UnwinderTest, sp_not_in_map) {
484 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
485 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
486
Yabin Cui11e96fe2018-03-14 18:16:22 -0700487 regs_.set_pc(0x1000);
488 regs_.set_sp(0x63000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700489 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
490 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
491
492 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
493 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800494 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700495
496 ASSERT_EQ(2U, unwinder.NumFrames());
497
498 auto* frame = &unwinder.frames()[0];
499 EXPECT_EQ(0U, frame->num);
500 EXPECT_EQ(0U, frame->rel_pc);
501 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700502 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700503 EXPECT_EQ("Frame0", frame->function_name);
504 EXPECT_EQ(0U, frame->function_offset);
505 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
506 EXPECT_EQ(0U, frame->map_offset);
507 EXPECT_EQ(0x1000U, frame->map_start);
508 EXPECT_EQ(0x8000U, frame->map_end);
509 EXPECT_EQ(0U, frame->map_load_bias);
510 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
511
512 frame = &unwinder.frames()[1];
513 EXPECT_EQ(1U, frame->num);
514 EXPECT_EQ(0x1000U, frame->rel_pc);
515 EXPECT_EQ(0x21000U, frame->pc);
516 EXPECT_EQ(0x50020U, frame->sp);
517 EXPECT_EQ("Frame1", frame->function_name);
518 EXPECT_EQ(1U, frame->function_offset);
519 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
520 EXPECT_EQ(0U, frame->map_offset);
521 EXPECT_EQ(0x20000U, frame->map_start);
522 EXPECT_EQ(0x22000U, frame->map_end);
523 EXPECT_EQ(0U, frame->map_load_bias);
524 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
525}
526
527// Verify PC in a device stops the unwind.
528TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
529 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
530 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
531 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
532
Yabin Cui11e96fe2018-03-14 18:16:22 -0700533 regs_.set_pc(0x13000);
534 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700535 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
536 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
537 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
538
539 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
540 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800541 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700542
543 ASSERT_EQ(1U, unwinder.NumFrames());
544}
545
546// Verify SP in a device stops the unwind.
547TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
548 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
549 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
550 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
551
Yabin Cui11e96fe2018-03-14 18:16:22 -0700552 regs_.set_pc(0x1000);
553 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700554 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
555 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
556 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
557
558 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
559 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800560 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700561
562 ASSERT_EQ(1U, unwinder.NumFrames());
563}
564
565// Verify a no map info frame gets a frame.
566TEST_F(UnwinderTest, pc_without_map) {
567 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
568
Yabin Cui11e96fe2018-03-14 18:16:22 -0700569 regs_.set_pc(0x41000);
570 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700571
572 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
573 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800574 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700575
576 ASSERT_EQ(1U, unwinder.NumFrames());
577
578 auto* frame = &unwinder.frames()[0];
579 EXPECT_EQ(0U, frame->num);
580 EXPECT_EQ(0x41000U, frame->rel_pc);
581 EXPECT_EQ(0x41000U, frame->pc);
582 EXPECT_EQ(0x13000U, frame->sp);
583 EXPECT_EQ("", frame->function_name);
584 EXPECT_EQ(0U, frame->function_offset);
585 EXPECT_EQ("", frame->map_name);
586 EXPECT_EQ(0U, frame->map_offset);
587 EXPECT_EQ(0U, frame->map_start);
588 EXPECT_EQ(0U, frame->map_end);
589 EXPECT_EQ(0U, frame->map_load_bias);
590 EXPECT_EQ(0, frame->map_flags);
591}
592
593// Verify that a speculative frame is added.
594TEST_F(UnwinderTest, speculative_frame) {
595 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
596 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
597
598 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700599 regs_.set_pc(0);
600 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700601 regs_.FakeSetReturnAddress(0x1202);
602 regs_.FakeSetReturnAddressValid(true);
603
604 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
605 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
606
607 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
608 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800609 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700610
611 ASSERT_EQ(3U, unwinder.NumFrames());
612
613 auto* frame = &unwinder.frames()[0];
614 EXPECT_EQ(0U, frame->num);
615 EXPECT_EQ(0U, frame->rel_pc);
616 EXPECT_EQ(0U, frame->pc);
617 EXPECT_EQ(0x10000U, frame->sp);
618 EXPECT_EQ("", frame->function_name);
619 EXPECT_EQ(0U, frame->function_offset);
620 EXPECT_EQ("", frame->map_name);
621 EXPECT_EQ(0U, frame->map_offset);
622 EXPECT_EQ(0U, frame->map_start);
623 EXPECT_EQ(0U, frame->map_end);
624 EXPECT_EQ(0U, frame->map_load_bias);
625 EXPECT_EQ(0, frame->map_flags);
626
627 frame = &unwinder.frames()[1];
628 EXPECT_EQ(1U, frame->num);
629 EXPECT_EQ(0x200U, frame->rel_pc);
630 EXPECT_EQ(0x1200U, frame->pc);
631 EXPECT_EQ(0x10000U, frame->sp);
632 EXPECT_EQ("Frame0", frame->function_name);
633 EXPECT_EQ(0U, frame->function_offset);
634 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
635 EXPECT_EQ(0U, frame->map_offset);
636 EXPECT_EQ(0x1000U, frame->map_start);
637 EXPECT_EQ(0x8000U, frame->map_end);
638 EXPECT_EQ(0U, frame->map_load_bias);
639 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
640
641 frame = &unwinder.frames()[2];
642 EXPECT_EQ(2U, frame->num);
643 EXPECT_EQ(0x100U, frame->rel_pc);
644 EXPECT_EQ(0x23100U, frame->pc);
645 EXPECT_EQ(0x10020U, frame->sp);
646 EXPECT_EQ("Frame1", frame->function_name);
647 EXPECT_EQ(1U, frame->function_offset);
648 EXPECT_EQ("/fake/libanother.so", frame->map_name);
649 EXPECT_EQ(0U, frame->map_offset);
650 EXPECT_EQ(0x23000U, frame->map_start);
651 EXPECT_EQ(0x24000U, frame->map_end);
652 EXPECT_EQ(0U, frame->map_load_bias);
653 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
654}
655
656// Verify that a speculative frame is added then removed because no other
657// frames are added.
658TEST_F(UnwinderTest, speculative_frame_removed) {
659 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
660 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
661
662 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700663 regs_.set_pc(0);
664 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700665 regs_.FakeSetReturnAddress(0x1202);
666 regs_.FakeSetReturnAddressValid(true);
667
668 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
669 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800670 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700671
672 ASSERT_EQ(1U, unwinder.NumFrames());
673
674 auto* frame = &unwinder.frames()[0];
675 EXPECT_EQ(0U, frame->num);
676 EXPECT_EQ(0U, frame->rel_pc);
677 EXPECT_EQ(0U, frame->pc);
678 EXPECT_EQ(0x10000U, frame->sp);
679 EXPECT_EQ("", frame->function_name);
680 EXPECT_EQ(0U, frame->function_offset);
681 EXPECT_EQ("", frame->map_name);
682 EXPECT_EQ(0U, frame->map_offset);
683 EXPECT_EQ(0U, frame->map_start);
684 EXPECT_EQ(0U, frame->map_end);
685 EXPECT_EQ(0U, frame->map_load_bias);
686 EXPECT_EQ(0, frame->map_flags);
687}
688
Christopher Ferrise69f4702017-10-19 16:08:58 -0700689// Verify that an unwind stops when a frame is in given suffix.
690TEST_F(UnwinderTest, map_ignore_suffixes) {
691 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
692 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
693 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
694 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
695
696 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700697 regs_.set_pc(0x1000);
698 regs_.set_sp(0x10000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700699 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
700 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
701 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
702
703 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700704 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700705 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800706 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700707
708 ASSERT_EQ(2U, unwinder.NumFrames());
709 // Make sure the elf was not initialized.
710 MapInfo* map_info = maps_.Find(0x53000);
711 ASSERT_TRUE(map_info != nullptr);
712 EXPECT_TRUE(map_info->elf == nullptr);
713
714 auto* frame = &unwinder.frames()[0];
715 EXPECT_EQ(0U, frame->num);
716 EXPECT_EQ(0U, frame->rel_pc);
717 EXPECT_EQ(0x1000U, frame->pc);
718 EXPECT_EQ(0x10000U, frame->sp);
719 EXPECT_EQ("Frame0", frame->function_name);
720 EXPECT_EQ(0U, frame->function_offset);
721 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
722 EXPECT_EQ(0U, frame->map_offset);
723 EXPECT_EQ(0x1000U, frame->map_start);
724 EXPECT_EQ(0x8000U, frame->map_end);
725 EXPECT_EQ(0U, frame->map_load_bias);
726 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
727
728 frame = &unwinder.frames()[1];
729 EXPECT_EQ(1U, frame->num);
730 EXPECT_EQ(0x400U, frame->rel_pc);
731 EXPECT_EQ(0x43400U, frame->pc);
732 EXPECT_EQ(0x10010U, frame->sp);
733 EXPECT_EQ("Frame1", frame->function_name);
734 EXPECT_EQ(1U, frame->function_offset);
735 EXPECT_EQ("/fake/fake.apk", frame->map_name);
736 EXPECT_EQ(0x1d000U, frame->map_offset);
737 EXPECT_EQ(0x43000U, frame->map_start);
738 EXPECT_EQ(0x44000U, frame->map_end);
739 EXPECT_EQ(0U, frame->map_load_bias);
740 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
741}
742
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700743// Verify that an unwind stops when the sp and pc don't change.
744TEST_F(UnwinderTest, sp_pc_do_not_change) {
745 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
746 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
747 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
748 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
749 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
750
Yabin Cui11e96fe2018-03-14 18:16:22 -0700751 regs_.set_pc(0x1000);
752 regs_.set_sp(0x10000);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700753 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
754 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
755 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
756 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
757 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
758 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
759
760 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
761 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800762 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700763
764 ASSERT_EQ(3U, unwinder.NumFrames());
765
766 auto* frame = &unwinder.frames()[0];
767 EXPECT_EQ(0U, frame->num);
768 EXPECT_EQ(0U, frame->rel_pc);
769 EXPECT_EQ(0x1000U, frame->pc);
770 EXPECT_EQ(0x10000U, frame->sp);
771 EXPECT_EQ("Frame0", frame->function_name);
772 EXPECT_EQ(0U, frame->function_offset);
773 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
774 EXPECT_EQ(0U, frame->map_offset);
775 EXPECT_EQ(0x1000U, frame->map_start);
776 EXPECT_EQ(0x8000U, frame->map_end);
777 EXPECT_EQ(0U, frame->map_load_bias);
778 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
779
780 frame = &unwinder.frames()[1];
781 EXPECT_EQ(1U, frame->num);
782 EXPECT_EQ(0x400U, frame->rel_pc);
783 EXPECT_EQ(0x33400U, frame->pc);
784 EXPECT_EQ(0x10010U, frame->sp);
785 EXPECT_EQ("Frame1", frame->function_name);
786 EXPECT_EQ(1U, frame->function_offset);
787 EXPECT_EQ("/fake/compressed.so", frame->map_name);
788 EXPECT_EQ(0U, frame->map_offset);
789 EXPECT_EQ(0x33000U, frame->map_start);
790 EXPECT_EQ(0x34000U, frame->map_end);
791 EXPECT_EQ(0U, frame->map_load_bias);
792 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
793
794 frame = &unwinder.frames()[2];
795 EXPECT_EQ(2U, frame->num);
796 EXPECT_EQ(0x500U, frame->rel_pc);
797 EXPECT_EQ(0x33500U, frame->pc);
798 EXPECT_EQ(0x10020U, frame->sp);
799 EXPECT_EQ("Frame2", frame->function_name);
800 EXPECT_EQ(2U, frame->function_offset);
801 EXPECT_EQ("/fake/compressed.so", frame->map_name);
802 EXPECT_EQ(0U, frame->map_offset);
803 EXPECT_EQ(0x33000U, frame->map_start);
804 EXPECT_EQ(0x34000U, frame->map_end);
805 EXPECT_EQ(0U, frame->map_load_bias);
806 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
807}
808
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800809TEST_F(UnwinderTest, dex_pc_in_map) {
810 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700811 regs_.set_pc(0x1000);
812 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800813 regs_.FakeSetDexPc(0xa3400);
814
815 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
816 unwinder.Unwind();
817 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
818
819 ASSERT_EQ(2U, unwinder.NumFrames());
820
821 auto* frame = &unwinder.frames()[0];
822 EXPECT_EQ(0U, frame->num);
823 EXPECT_EQ(0x400U, frame->rel_pc);
824 EXPECT_EQ(0xa3400U, frame->pc);
825 EXPECT_EQ(0x10000U, frame->sp);
826 EXPECT_EQ("", frame->function_name);
827 EXPECT_EQ(0U, frame->function_offset);
828 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
829 EXPECT_EQ(0U, frame->map_offset);
830 EXPECT_EQ(0xa3000U, frame->map_start);
831 EXPECT_EQ(0xa4000U, frame->map_end);
832 EXPECT_EQ(0U, frame->map_load_bias);
833 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
834
835 frame = &unwinder.frames()[1];
836 EXPECT_EQ(1U, frame->num);
837 EXPECT_EQ(0U, frame->rel_pc);
838 EXPECT_EQ(0x1000U, frame->pc);
839 EXPECT_EQ(0x10000U, frame->sp);
840 EXPECT_EQ("Frame0", frame->function_name);
841 EXPECT_EQ(0U, frame->function_offset);
842 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
843 EXPECT_EQ(0U, frame->map_offset);
844 EXPECT_EQ(0x1000U, frame->map_start);
845 EXPECT_EQ(0x8000U, frame->map_end);
846 EXPECT_EQ(0U, frame->map_load_bias);
847 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
848}
849
850TEST_F(UnwinderTest, dex_pc_not_in_map) {
851 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700852 regs_.set_pc(0x1000);
853 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800854 regs_.FakeSetDexPc(0x50000);
855
856 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
857 unwinder.Unwind();
858 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
859
860 ASSERT_EQ(2U, unwinder.NumFrames());
861
862 auto* frame = &unwinder.frames()[0];
863 EXPECT_EQ(0U, frame->num);
864 EXPECT_EQ(0x50000U, frame->rel_pc);
865 EXPECT_EQ(0x50000U, frame->pc);
866 EXPECT_EQ(0x10000U, frame->sp);
867 EXPECT_EQ("", frame->function_name);
868 EXPECT_EQ(0U, frame->function_offset);
869 EXPECT_EQ("", frame->map_name);
870 EXPECT_EQ(0U, frame->map_offset);
871 EXPECT_EQ(0U, frame->map_start);
872 EXPECT_EQ(0U, frame->map_end);
873 EXPECT_EQ(0U, frame->map_load_bias);
874 EXPECT_EQ(0, frame->map_flags);
875
876 frame = &unwinder.frames()[1];
877 EXPECT_EQ(1U, frame->num);
878 EXPECT_EQ(0U, frame->rel_pc);
879 EXPECT_EQ(0x1000U, frame->pc);
880 EXPECT_EQ(0x10000U, frame->sp);
881 EXPECT_EQ("Frame0", frame->function_name);
882 EXPECT_EQ(0U, frame->function_offset);
883 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
884 EXPECT_EQ(0U, frame->map_offset);
885 EXPECT_EQ(0x1000U, frame->map_start);
886 EXPECT_EQ(0x8000U, frame->map_end);
887 EXPECT_EQ(0U, frame->map_load_bias);
888 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
889}
890
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800891TEST_F(UnwinderTest, dex_pc_multiple_frames) {
892 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
893 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700894 regs_.set_pc(0x1000);
895 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800896 regs_.FakeSetDexPc(0xa3400);
897 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
898 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
899
900 Unwinder unwinder(64, &maps_, &regs_, process_memory_);
901 unwinder.Unwind();
902 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
903
904 ASSERT_EQ(3U, unwinder.NumFrames());
905
906 auto* frame = &unwinder.frames()[0];
907 EXPECT_EQ(0U, frame->num);
908 EXPECT_EQ(0x400U, frame->rel_pc);
909 EXPECT_EQ(0xa3400U, frame->pc);
910 EXPECT_EQ(0x10000U, frame->sp);
911 EXPECT_EQ("", frame->function_name);
912 EXPECT_EQ(0U, frame->function_offset);
913 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
914 EXPECT_EQ(0U, frame->map_offset);
915 EXPECT_EQ(0xa3000U, frame->map_start);
916 EXPECT_EQ(0xa4000U, frame->map_end);
917 EXPECT_EQ(0U, frame->map_load_bias);
918 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
919
920 frame = &unwinder.frames()[1];
921 EXPECT_EQ(1U, frame->num);
922 EXPECT_EQ(0U, frame->rel_pc);
923 EXPECT_EQ(0x1000U, frame->pc);
924 EXPECT_EQ(0x10000U, frame->sp);
925 EXPECT_EQ("Frame0", frame->function_name);
926 EXPECT_EQ(0U, frame->function_offset);
927 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
928 EXPECT_EQ(0U, frame->map_offset);
929 EXPECT_EQ(0x1000U, frame->map_start);
930 EXPECT_EQ(0x8000U, frame->map_end);
931 EXPECT_EQ(0U, frame->map_load_bias);
932 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
933
934 frame = &unwinder.frames()[2];
935 EXPECT_EQ(2U, frame->num);
936 EXPECT_EQ(0x400U, frame->rel_pc);
937 EXPECT_EQ(0x33400U, frame->pc);
938 EXPECT_EQ(0x10010U, frame->sp);
939 EXPECT_EQ("Frame1", frame->function_name);
940 EXPECT_EQ(1U, frame->function_offset);
941 EXPECT_EQ("/fake/compressed.so", frame->map_name);
942 EXPECT_EQ(0U, frame->map_offset);
943 EXPECT_EQ(0x33000U, frame->map_start);
944 EXPECT_EQ(0x34000U, frame->map_end);
945 EXPECT_EQ(0U, frame->map_load_bias);
946 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
947}
948
Christopher Ferris9d0ad232018-10-12 16:33:42 -0700949TEST_F(UnwinderTest, dex_pc_max_frames) {
950 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
951 regs_.set_pc(0x1000);
952 regs_.set_sp(0x10000);
953 regs_.FakeSetDexPc(0xa3400);
954
955 Unwinder unwinder(1, &maps_, &regs_, process_memory_);
956 unwinder.Unwind();
957 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
958
959 ASSERT_EQ(1U, unwinder.NumFrames());
960
961 auto* frame = &unwinder.frames()[0];
962 EXPECT_EQ(0U, frame->num);
963 EXPECT_EQ(0x400U, frame->rel_pc);
964 EXPECT_EQ(0xa3400U, frame->pc);
965 EXPECT_EQ(0x10000U, frame->sp);
966 EXPECT_EQ("", frame->function_name);
967 EXPECT_EQ(0U, frame->function_offset);
968 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
969 EXPECT_EQ(0U, frame->map_offset);
970 EXPECT_EQ(0xa3000U, frame->map_start);
971 EXPECT_EQ(0xa4000U, frame->map_end);
972 EXPECT_EQ(0U, frame->map_load_bias);
973 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
974}
975
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700976// Verify format frame code.
977TEST_F(UnwinderTest, format_frame_static) {
978 FrameData frame;
979 frame.num = 1;
980 frame.rel_pc = 0x1000;
981 frame.pc = 0x4000;
982 frame.sp = 0x1000;
983 frame.function_name = "function";
984 frame.function_offset = 100;
985 frame.map_name = "/fake/libfake.so";
986 frame.map_offset = 0x2000;
987 frame.map_start = 0x3000;
988 frame.map_end = 0x6000;
989 frame.map_flags = PROT_READ;
990
991 EXPECT_EQ(" #01 pc 0000000000001000 (offset 0x2000) /fake/libfake.so (function+100)",
992 Unwinder::FormatFrame(frame, false));
993 EXPECT_EQ(" #01 pc 00001000 (offset 0x2000) /fake/libfake.so (function+100)",
994 Unwinder::FormatFrame(frame, true));
995
996 frame.map_offset = 0;
997 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
998 Unwinder::FormatFrame(frame, false));
999 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)",
1000 Unwinder::FormatFrame(frame, true));
1001
1002 frame.function_offset = 0;
1003 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
1004 Unwinder::FormatFrame(frame, false));
1005 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", Unwinder::FormatFrame(frame, true));
1006
1007 frame.function_name = "";
1008 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", Unwinder::FormatFrame(frame, false));
1009 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", Unwinder::FormatFrame(frame, true));
1010
1011 frame.map_name = "";
1012 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", Unwinder::FormatFrame(frame, false));
1013 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", Unwinder::FormatFrame(frame, true));
1014
1015 frame.map_start = 0;
1016 frame.map_end = 0;
1017 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", Unwinder::FormatFrame(frame, false));
1018 EXPECT_EQ(" #01 pc 00001000 <unknown>", Unwinder::FormatFrame(frame, true));
1019}
1020
Christopher Ferris02fdb562017-12-08 15:04:49 -08001021static std::string ArchToString(ArchEnum arch) {
1022 if (arch == ARCH_ARM) {
1023 return "Arm";
1024 } else if (arch == ARCH_ARM64) {
1025 return "Arm64";
1026 } else if (arch == ARCH_X86) {
1027 return "X86";
1028 } else if (arch == ARCH_X86_64) {
1029 return "X86_64";
1030 } else {
1031 return "Unknown";
1032 }
1033}
1034
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001035// Verify format frame code.
1036TEST_F(UnwinderTest, format_frame) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001037 std::vector<Regs*> reg_list;
1038 RegsArm* arm = new RegsArm;
1039 arm->set_pc(0x2300);
1040 arm->set_sp(0x10000);
1041 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001042
Christopher Ferris02fdb562017-12-08 15:04:49 -08001043 RegsArm64* arm64 = new RegsArm64;
1044 arm64->set_pc(0x2300);
1045 arm64->set_sp(0x10000);
1046 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001047
Christopher Ferris02fdb562017-12-08 15:04:49 -08001048 RegsX86* x86 = new RegsX86;
1049 x86->set_pc(0x2300);
1050 x86->set_sp(0x10000);
1051 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001052
Christopher Ferris02fdb562017-12-08 15:04:49 -08001053 RegsX86_64* x86_64 = new RegsX86_64;
1054 x86_64->set_pc(0x2300);
1055 x86_64->set_sp(0x10000);
1056 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001057
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001058 RegsMips* mips = new RegsMips;
1059 mips->set_pc(0x2300);
1060 mips->set_sp(0x10000);
1061 reg_list.push_back(mips);
1062
1063 RegsMips64* mips64 = new RegsMips64;
1064 mips64->set_pc(0x2300);
1065 mips64->set_sp(0x10000);
1066 reg_list.push_back(mips64);
1067
Christopher Ferris02fdb562017-12-08 15:04:49 -08001068 for (auto regs : reg_list) {
1069 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001070
Christopher Ferris02fdb562017-12-08 15:04:49 -08001071 Unwinder unwinder(64, &maps_, regs, process_memory_);
1072 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001073
Christopher Ferris02fdb562017-12-08 15:04:49 -08001074 ASSERT_EQ(1U, unwinder.NumFrames());
1075 std::string expected;
1076 switch (regs->Arch()) {
1077 case ARCH_ARM:
1078 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001079 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001080 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1081 break;
1082 case ARCH_ARM64:
1083 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001084 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001085 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1086 break;
1087 default:
1088 expected = "";
1089 }
1090 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1091 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1092 delete regs;
1093 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001094}
1095
1096} // namespace unwindstack