blob: 49aeeb378b448a88c8091847865de6dbf29f7178 [file] [log] [blame]
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <elf.h>
18#include <stdint.h>
19#include <sys/mman.h>
20
21#include <memory>
22#include <set>
23#include <string>
24
25#include <gtest/gtest.h>
26
27#include <unwindstack/Elf.h>
28#include <unwindstack/Maps.h>
29#include <unwindstack/Memory.h>
30#include <unwindstack/Regs.h>
Christopher Ferris02fdb562017-12-08 15:04:49 -080031#include <unwindstack/RegsArm.h>
32#include <unwindstack/RegsArm64.h>
33#include <unwindstack/RegsX86.h>
34#include <unwindstack/RegsX86_64.h>
Douglas Leung61b1a1a2017-11-08 10:53:53 +010035#include <unwindstack/RegsMips.h>
36#include <unwindstack/RegsMips64.h>
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070037#include <unwindstack/Unwinder.h>
38
39#include "ElfFake.h"
40#include "MemoryFake.h"
41#include "RegsFake.h"
42
43namespace unwindstack {
44
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070045class UnwinderTest : public ::testing::Test {
46 protected:
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080047 static void AddMapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
48 const char* name, Elf* elf = nullptr) {
49 std::string str_name(name);
50 maps_->Add(start, end, offset, flags, name, static_cast<uint64_t>(-1));
51 if (elf != nullptr) {
52 MapInfo* map_info = *--maps_->end();
53 map_info->elf.reset(elf);
54 }
55 }
56
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070057 static void SetUpTestCase() {
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080058 maps_.reset(new Maps);
59
Christopher Ferris02fdb562017-12-08 15:04:49 -080060 ElfFake* elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070061 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080062 AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070063
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080064 AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070065
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080066 AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
67 "/dev/fake_device");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070068
Christopher Ferris02fdb562017-12-08 15:04:49 -080069 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070070 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080071 AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070072
Christopher Ferris02fdb562017-12-08 15:04:49 -080073 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070074 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080075 AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070076
Christopher Ferris02fdb562017-12-08 15:04:49 -080077 elf = new ElfFake(new MemoryFake);
Christopher Ferrise69f4702017-10-19 16:08:58 -070078 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080079 AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070080
Christopher Ferris02fdb562017-12-08 15:04:49 -080081 elf = new ElfFake(new MemoryFake);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070082 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080083 AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070084
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080085 AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
Christopher Ferris02fdb562017-12-08 15:04:49 -080086
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080087 AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
88 MapInfo* info = *--maps_->end();
Christopher Ferrise762f1f2018-02-06 14:51:48 -080089 info->load_bias = 0;
Christopher Ferrise762f1f2018-02-06 14:51:48 -080090
Christopher Ferrise4df5f52018-02-12 13:24:18 -080091 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -080092 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
93 elf->FakeSetLoadBias(0x5000);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080094 AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
95 elf);
Christopher Ferrise4df5f52018-02-12 13:24:18 -080096
Christopher Ferrise4df5f52018-02-12 13:24:18 -080097 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -080098 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080099 AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_offset.oat",
100 elf);
101 info = *--maps_->end();
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800102 info->elf_offset = 0x8000;
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800103
Christopher Ferris02fdb562017-12-08 15:04:49 -0800104 process_memory_.reset(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700105 }
106
107 void SetUp() override {
108 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800109 regs_.FakeSetArch(ARCH_ARM);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700110 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700111 }
112
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800113 static std::unique_ptr<Maps> maps_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700114 static RegsFake regs_;
115 static std::shared_ptr<Memory> process_memory_;
116};
117
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800118std::unique_ptr<Maps> UnwinderTest::maps_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700119RegsFake UnwinderTest::regs_(5);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700120std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
121
122TEST_F(UnwinderTest, multiple_frames) {
123 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
124 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
125 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
126
Yabin Cui11e96fe2018-03-14 18:16:22 -0700127 regs_.set_pc(0x1000);
128 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700129 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
130 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
131 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
132
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800133 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700134 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800135 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700136
137 ASSERT_EQ(3U, unwinder.NumFrames());
138
139 auto* frame = &unwinder.frames()[0];
140 EXPECT_EQ(0U, frame->num);
141 EXPECT_EQ(0U, frame->rel_pc);
142 EXPECT_EQ(0x1000U, frame->pc);
143 EXPECT_EQ(0x10000U, frame->sp);
144 EXPECT_EQ("Frame0", frame->function_name);
145 EXPECT_EQ(0U, frame->function_offset);
146 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800147 EXPECT_EQ(0U, frame->map_elf_start_offset);
148 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700149 EXPECT_EQ(0x1000U, frame->map_start);
150 EXPECT_EQ(0x8000U, frame->map_end);
151 EXPECT_EQ(0U, frame->map_load_bias);
152 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
153
154 frame = &unwinder.frames()[1];
155 EXPECT_EQ(1U, frame->num);
156 EXPECT_EQ(0x100U, frame->rel_pc);
157 EXPECT_EQ(0x1100U, frame->pc);
158 EXPECT_EQ(0x10010U, frame->sp);
159 EXPECT_EQ("Frame1", frame->function_name);
160 EXPECT_EQ(1U, frame->function_offset);
161 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800162 EXPECT_EQ(0U, frame->map_elf_start_offset);
163 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700164 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 frame = &unwinder.frames()[2];
170 EXPECT_EQ(2U, frame->num);
171 EXPECT_EQ(0x200U, frame->rel_pc);
172 EXPECT_EQ(0x1200U, frame->pc);
173 EXPECT_EQ(0x10020U, frame->sp);
174 EXPECT_EQ("Frame2", frame->function_name);
175 EXPECT_EQ(2U, frame->function_offset);
176 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800177 EXPECT_EQ(0U, frame->map_elf_start_offset);
178 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700179 EXPECT_EQ(0x1000U, frame->map_start);
180 EXPECT_EQ(0x8000U, frame->map_end);
181 EXPECT_EQ(0U, frame->map_load_bias);
182 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
183}
184
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800185TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
186 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
187 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
188 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
189
Yabin Cui11e96fe2018-03-14 18:16:22 -0700190 regs_.set_pc(0x1000);
191 regs_.set_sp(0x10000);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800192 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
193 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
194 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
195
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800196 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800197 unwinder.SetResolveNames(false);
198 unwinder.Unwind();
199 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
200
201 ASSERT_EQ(3U, unwinder.NumFrames());
202
203 auto* frame = &unwinder.frames()[0];
204 EXPECT_EQ(0U, frame->num);
205 EXPECT_EQ(0U, frame->rel_pc);
206 EXPECT_EQ(0x1000U, frame->pc);
207 EXPECT_EQ(0x10000U, frame->sp);
208 EXPECT_EQ("", frame->function_name);
209 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000210 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800211 EXPECT_EQ(0U, frame->map_elf_start_offset);
212 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800213 EXPECT_EQ(0x1000U, frame->map_start);
214 EXPECT_EQ(0x8000U, frame->map_end);
215 EXPECT_EQ(0U, frame->map_load_bias);
216 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
217
218 frame = &unwinder.frames()[1];
219 EXPECT_EQ(1U, frame->num);
220 EXPECT_EQ(0x100U, frame->rel_pc);
221 EXPECT_EQ(0x1100U, frame->pc);
222 EXPECT_EQ(0x10010U, frame->sp);
223 EXPECT_EQ("", frame->function_name);
224 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000225 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800226 EXPECT_EQ(0U, frame->map_elf_start_offset);
227 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800228 EXPECT_EQ(0x1000U, frame->map_start);
229 EXPECT_EQ(0x8000U, frame->map_end);
230 EXPECT_EQ(0U, frame->map_load_bias);
231 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
232
233 frame = &unwinder.frames()[2];
234 EXPECT_EQ(2U, frame->num);
235 EXPECT_EQ(0x200U, frame->rel_pc);
236 EXPECT_EQ(0x1200U, frame->pc);
237 EXPECT_EQ(0x10020U, frame->sp);
238 EXPECT_EQ("", frame->function_name);
239 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000240 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800241 EXPECT_EQ(0U, frame->map_elf_start_offset);
242 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800243 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
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800249TEST_F(UnwinderTest, non_zero_load_bias) {
250 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
251
Yabin Cui11e96fe2018-03-14 18:16:22 -0700252 regs_.set_pc(0xa5500);
253 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800254 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
255
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800256 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800257 unwinder.Unwind();
258 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
259
260 ASSERT_EQ(1U, unwinder.NumFrames());
261
262 auto* frame = &unwinder.frames()[0];
263 EXPECT_EQ(0U, frame->num);
264 EXPECT_EQ(0x5500U, frame->rel_pc);
265 EXPECT_EQ(0xa5500U, frame->pc);
266 EXPECT_EQ(0x10000U, frame->sp);
267 EXPECT_EQ("Frame0", frame->function_name);
268 EXPECT_EQ(0U, frame->function_offset);
269 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800270 EXPECT_EQ(0U, frame->map_elf_start_offset);
271 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800272 EXPECT_EQ(0xa5000U, frame->map_start);
273 EXPECT_EQ(0xa6000U, frame->map_end);
274 EXPECT_EQ(0x5000U, frame->map_load_bias);
275 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
276}
277
278TEST_F(UnwinderTest, non_zero_elf_offset) {
279 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
280
Yabin Cui11e96fe2018-03-14 18:16:22 -0700281 regs_.set_pc(0xa7500);
282 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800283 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
284
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800285 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800286 unwinder.Unwind();
287 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
288
289 ASSERT_EQ(1U, unwinder.NumFrames());
290
291 auto* frame = &unwinder.frames()[0];
292 EXPECT_EQ(0U, frame->num);
293 EXPECT_EQ(0x8500U, frame->rel_pc);
294 EXPECT_EQ(0xa7500U, frame->pc);
295 EXPECT_EQ(0x10000U, frame->sp);
296 EXPECT_EQ("Frame0", frame->function_name);
297 EXPECT_EQ(0U, frame->function_offset);
298 EXPECT_EQ("/fake/fake_offset.oat", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800299 EXPECT_EQ(0U, frame->map_elf_start_offset);
300 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800301 EXPECT_EQ(0xa7000U, frame->map_start);
302 EXPECT_EQ(0xa8000U, frame->map_end);
303 EXPECT_EQ(0U, frame->map_load_bias);
304 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
305}
306
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700307TEST_F(UnwinderTest, non_zero_map_offset) {
308 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
309
Yabin Cui11e96fe2018-03-14 18:16:22 -0700310 regs_.set_pc(0x43000);
311 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700312 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
313
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800314 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700315 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800316 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700317
318 ASSERT_EQ(1U, unwinder.NumFrames());
319
320 auto* frame = &unwinder.frames()[0];
321 EXPECT_EQ(0U, frame->num);
322 EXPECT_EQ(0U, frame->rel_pc);
323 EXPECT_EQ(0x43000U, frame->pc);
324 EXPECT_EQ(0x10000U, frame->sp);
325 EXPECT_EQ("Frame0", frame->function_name);
326 EXPECT_EQ(0U, frame->function_offset);
327 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800328 EXPECT_EQ(0U, frame->map_elf_start_offset);
329 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700330 EXPECT_EQ(0x43000U, frame->map_start);
331 EXPECT_EQ(0x44000U, frame->map_end);
332 EXPECT_EQ(0U, frame->map_load_bias);
333 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
334}
335
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700336// Verify that no attempt to continue after the step indicates it is done.
337TEST_F(UnwinderTest, no_frames_after_finished) {
338 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
339 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
340 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
341 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
342 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
343
Yabin Cui11e96fe2018-03-14 18:16:22 -0700344 regs_.set_pc(0x1000);
345 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700346 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
347 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
348 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
349
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800350 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700351 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800352 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700353
354 ASSERT_EQ(1U, unwinder.NumFrames());
355
356 auto* frame = &unwinder.frames()[0];
357 EXPECT_EQ(0U, frame->num);
358 EXPECT_EQ(0U, frame->rel_pc);
359 EXPECT_EQ(0x1000U, frame->pc);
360 EXPECT_EQ(0x10000U, frame->sp);
361 EXPECT_EQ("Frame0", frame->function_name);
362 EXPECT_EQ(0U, frame->function_offset);
363 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800364 EXPECT_EQ(0U, frame->map_elf_start_offset);
365 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700366 EXPECT_EQ(0x1000U, frame->map_start);
367 EXPECT_EQ(0x8000U, frame->map_end);
368 EXPECT_EQ(0U, frame->map_load_bias);
369 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
370}
371
372// Verify the maximum frames to save.
373TEST_F(UnwinderTest, max_frames) {
374 for (size_t i = 0; i < 30; i++) {
375 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
376 ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
377 }
378
Yabin Cui11e96fe2018-03-14 18:16:22 -0700379 regs_.set_pc(0x1000);
380 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700381
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800382 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700383 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800384 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700385
386 ASSERT_EQ(20U, unwinder.NumFrames());
387
388 for (size_t i = 0; i < 20; i++) {
389 auto* frame = &unwinder.frames()[i];
390 EXPECT_EQ(i, frame->num);
391 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
392 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
393 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
394 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
395 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
396 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800397 EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
398 EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700399 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
400 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
401 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
402 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
403 }
404}
405
406// Verify that initial map names frames are removed.
407TEST_F(UnwinderTest, verify_frames_skipped) {
408 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
409 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
410 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
411
Yabin Cui11e96fe2018-03-14 18:16:22 -0700412 regs_.set_pc(0x20000);
413 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700414 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
415 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
416 ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false));
417 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
418 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
419 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
420 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
421 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
422
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800423 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700424 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
425 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800426 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700427
428 ASSERT_EQ(3U, unwinder.NumFrames());
429
430 auto* frame = &unwinder.frames()[0];
431 EXPECT_EQ(0U, frame->num);
432 EXPECT_EQ(0U, frame->rel_pc);
433 EXPECT_EQ(0x1000U, frame->pc);
434 EXPECT_EQ(0x10050U, frame->sp);
435 EXPECT_EQ("Frame0", frame->function_name);
436 EXPECT_EQ(0U, frame->function_offset);
437 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800438 EXPECT_EQ(0U, frame->map_elf_start_offset);
439 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700440 EXPECT_EQ(0x1000U, frame->map_start);
441 EXPECT_EQ(0x8000U, frame->map_end);
442 EXPECT_EQ(0U, frame->map_load_bias);
443 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
444
445 frame = &unwinder.frames()[1];
446 EXPECT_EQ(1U, frame->num);
447 EXPECT_EQ(0x1000U, frame->rel_pc);
448 EXPECT_EQ(0x21000U, frame->pc);
449 EXPECT_EQ(0x10060U, frame->sp);
450 EXPECT_EQ("Frame1", frame->function_name);
451 EXPECT_EQ(1U, frame->function_offset);
452 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800453 EXPECT_EQ(0U, frame->map_elf_start_offset);
454 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700455 EXPECT_EQ(0x20000U, frame->map_start);
456 EXPECT_EQ(0x22000U, frame->map_end);
457 EXPECT_EQ(0U, frame->map_load_bias);
458 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
459
460 frame = &unwinder.frames()[2];
461 EXPECT_EQ(2U, frame->num);
462 EXPECT_EQ(0U, frame->rel_pc);
463 EXPECT_EQ(0x23000U, frame->pc);
464 EXPECT_EQ(0x10070U, frame->sp);
465 EXPECT_EQ("Frame2", frame->function_name);
466 EXPECT_EQ(2U, frame->function_offset);
467 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800468 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700469 EXPECT_EQ(0x23000U, frame->map_start);
470 EXPECT_EQ(0x24000U, frame->map_end);
471 EXPECT_EQ(0U, frame->map_load_bias);
472 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
473}
474
475// Verify SP in a non-existant map is okay.
476TEST_F(UnwinderTest, sp_not_in_map) {
477 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
478 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
479
Yabin Cui11e96fe2018-03-14 18:16:22 -0700480 regs_.set_pc(0x1000);
481 regs_.set_sp(0x63000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700482 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
483 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
484
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800485 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700486 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800487 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700488
489 ASSERT_EQ(2U, unwinder.NumFrames());
490
491 auto* frame = &unwinder.frames()[0];
492 EXPECT_EQ(0U, frame->num);
493 EXPECT_EQ(0U, frame->rel_pc);
494 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700495 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700496 EXPECT_EQ("Frame0", frame->function_name);
497 EXPECT_EQ(0U, frame->function_offset);
498 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800499 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700500 EXPECT_EQ(0x1000U, frame->map_start);
501 EXPECT_EQ(0x8000U, frame->map_end);
502 EXPECT_EQ(0U, frame->map_load_bias);
503 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
504
505 frame = &unwinder.frames()[1];
506 EXPECT_EQ(1U, frame->num);
507 EXPECT_EQ(0x1000U, frame->rel_pc);
508 EXPECT_EQ(0x21000U, frame->pc);
509 EXPECT_EQ(0x50020U, frame->sp);
510 EXPECT_EQ("Frame1", frame->function_name);
511 EXPECT_EQ(1U, frame->function_offset);
512 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800513 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700514 EXPECT_EQ(0x20000U, frame->map_start);
515 EXPECT_EQ(0x22000U, frame->map_end);
516 EXPECT_EQ(0U, frame->map_load_bias);
517 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
518}
519
520// Verify PC in a device stops the unwind.
521TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
522 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
523 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
524 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
525
Yabin Cui11e96fe2018-03-14 18:16:22 -0700526 regs_.set_pc(0x13000);
527 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700528 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
529 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
530 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
531
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800532 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700533 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800534 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700535
536 ASSERT_EQ(1U, unwinder.NumFrames());
537}
538
539// Verify SP in a device stops the unwind.
540TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
541 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
542 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
543 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
544
Yabin Cui11e96fe2018-03-14 18:16:22 -0700545 regs_.set_pc(0x1000);
546 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700547 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
548 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
549 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
550
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800551 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700552 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800553 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700554
555 ASSERT_EQ(1U, unwinder.NumFrames());
556}
557
558// Verify a no map info frame gets a frame.
559TEST_F(UnwinderTest, pc_without_map) {
560 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
561
Yabin Cui11e96fe2018-03-14 18:16:22 -0700562 regs_.set_pc(0x41000);
563 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700564
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800565 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700566 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800567 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700568
569 ASSERT_EQ(1U, unwinder.NumFrames());
570
571 auto* frame = &unwinder.frames()[0];
572 EXPECT_EQ(0U, frame->num);
573 EXPECT_EQ(0x41000U, frame->rel_pc);
574 EXPECT_EQ(0x41000U, frame->pc);
575 EXPECT_EQ(0x13000U, frame->sp);
576 EXPECT_EQ("", frame->function_name);
577 EXPECT_EQ(0U, frame->function_offset);
578 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800579 EXPECT_EQ(0U, frame->map_elf_start_offset);
580 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700581 EXPECT_EQ(0U, frame->map_start);
582 EXPECT_EQ(0U, frame->map_end);
583 EXPECT_EQ(0U, frame->map_load_bias);
584 EXPECT_EQ(0, frame->map_flags);
585}
586
587// Verify that a speculative frame is added.
588TEST_F(UnwinderTest, speculative_frame) {
589 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
590 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
591
592 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700593 regs_.set_pc(0);
594 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700595 regs_.FakeSetReturnAddress(0x1202);
596 regs_.FakeSetReturnAddressValid(true);
597
598 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
599 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
600
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800601 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700602 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800603 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700604
605 ASSERT_EQ(3U, unwinder.NumFrames());
606
607 auto* frame = &unwinder.frames()[0];
608 EXPECT_EQ(0U, frame->num);
609 EXPECT_EQ(0U, frame->rel_pc);
610 EXPECT_EQ(0U, frame->pc);
611 EXPECT_EQ(0x10000U, frame->sp);
612 EXPECT_EQ("", frame->function_name);
613 EXPECT_EQ(0U, frame->function_offset);
614 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800615 EXPECT_EQ(0U, frame->map_elf_start_offset);
616 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700617 EXPECT_EQ(0U, frame->map_start);
618 EXPECT_EQ(0U, frame->map_end);
619 EXPECT_EQ(0U, frame->map_load_bias);
620 EXPECT_EQ(0, frame->map_flags);
621
622 frame = &unwinder.frames()[1];
623 EXPECT_EQ(1U, frame->num);
624 EXPECT_EQ(0x200U, frame->rel_pc);
625 EXPECT_EQ(0x1200U, frame->pc);
626 EXPECT_EQ(0x10000U, frame->sp);
627 EXPECT_EQ("Frame0", frame->function_name);
628 EXPECT_EQ(0U, frame->function_offset);
629 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800630 EXPECT_EQ(0U, frame->map_elf_start_offset);
631 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700632 EXPECT_EQ(0x1000U, frame->map_start);
633 EXPECT_EQ(0x8000U, frame->map_end);
634 EXPECT_EQ(0U, frame->map_load_bias);
635 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
636
637 frame = &unwinder.frames()[2];
638 EXPECT_EQ(2U, frame->num);
639 EXPECT_EQ(0x100U, frame->rel_pc);
640 EXPECT_EQ(0x23100U, frame->pc);
641 EXPECT_EQ(0x10020U, frame->sp);
642 EXPECT_EQ("Frame1", frame->function_name);
643 EXPECT_EQ(1U, frame->function_offset);
644 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800645 EXPECT_EQ(0U, frame->map_elf_start_offset);
646 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700647 EXPECT_EQ(0x23000U, frame->map_start);
648 EXPECT_EQ(0x24000U, frame->map_end);
649 EXPECT_EQ(0U, frame->map_load_bias);
650 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
651}
652
653// Verify that a speculative frame is added then removed because no other
654// frames are added.
655TEST_F(UnwinderTest, speculative_frame_removed) {
656 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
657 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
658
659 // Fake as if code called a nullptr function.
Christopher Ferris065f1562018-12-13 09:33:45 -0800660 regs_.set_pc(0x20000);
661 regs_.set_sp(0x10000);
662 ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
663 regs_.FakeSetReturnAddress(0x12);
664 regs_.FakeSetReturnAddressValid(true);
665
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800666 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris065f1562018-12-13 09:33:45 -0800667 unwinder.Unwind();
668 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
669
670 ASSERT_EQ(2U, unwinder.NumFrames());
671
672 auto* frame = &unwinder.frames()[0];
673 EXPECT_EQ(0U, frame->num);
674 EXPECT_EQ(0U, frame->rel_pc);
675 EXPECT_EQ(0x20000U, frame->pc);
676 EXPECT_EQ(0x10000U, frame->sp);
677 EXPECT_EQ("Frame0", frame->function_name);
678 EXPECT_EQ(0U, frame->function_offset);
679 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800680 EXPECT_EQ(0U, frame->map_elf_start_offset);
681 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800682 EXPECT_EQ(0x20000U, frame->map_start);
683 EXPECT_EQ(0x22000U, frame->map_end);
684 EXPECT_EQ(0U, frame->map_load_bias);
685 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
686
687 frame = &unwinder.frames()[1];
688 EXPECT_EQ(1U, frame->num);
689 EXPECT_EQ(0U, frame->rel_pc);
690 EXPECT_EQ(0U, frame->pc);
691 EXPECT_EQ(0x10010U, frame->sp);
692 EXPECT_EQ("", frame->function_name);
693 EXPECT_EQ(0U, frame->function_offset);
694 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800695 EXPECT_EQ(0U, frame->map_elf_start_offset);
696 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800697 EXPECT_EQ(0U, frame->map_start);
698 EXPECT_EQ(0U, frame->map_end);
699 EXPECT_EQ(0U, frame->map_load_bias);
700 EXPECT_EQ(0, frame->map_flags);
701}
702
703// Verify that a speculative frame is added and left if there are only
704// two frames and the pc is in the middle nowhere.
705TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
706 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
707 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
708
709 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700710 regs_.set_pc(0);
711 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700712 regs_.FakeSetReturnAddress(0x1202);
713 regs_.FakeSetReturnAddressValid(true);
714
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800715 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700716 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800717 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700718
Christopher Ferris065f1562018-12-13 09:33:45 -0800719 ASSERT_EQ(2U, unwinder.NumFrames());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700720
721 auto* frame = &unwinder.frames()[0];
722 EXPECT_EQ(0U, frame->num);
723 EXPECT_EQ(0U, frame->rel_pc);
724 EXPECT_EQ(0U, frame->pc);
725 EXPECT_EQ(0x10000U, frame->sp);
726 EXPECT_EQ("", frame->function_name);
727 EXPECT_EQ(0U, frame->function_offset);
728 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800729 EXPECT_EQ(0U, frame->map_elf_start_offset);
730 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700731 EXPECT_EQ(0U, frame->map_start);
732 EXPECT_EQ(0U, frame->map_end);
733 EXPECT_EQ(0U, frame->map_load_bias);
734 EXPECT_EQ(0, frame->map_flags);
Christopher Ferris065f1562018-12-13 09:33:45 -0800735
736 frame = &unwinder.frames()[1];
737 EXPECT_EQ(1U, frame->num);
738 EXPECT_EQ(0x200U, frame->rel_pc);
739 EXPECT_EQ(0x1200U, frame->pc);
740 EXPECT_EQ(0x10000U, frame->sp);
741 EXPECT_EQ("Frame0", frame->function_name);
742 EXPECT_EQ(0U, frame->function_offset);
743 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800744 EXPECT_EQ(0U, frame->map_elf_start_offset);
745 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800746 EXPECT_EQ(0x1000U, frame->map_start);
747 EXPECT_EQ(0x8000U, frame->map_end);
748 EXPECT_EQ(0U, frame->map_load_bias);
749 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700750}
751
Christopher Ferrise69f4702017-10-19 16:08:58 -0700752// Verify that an unwind stops when a frame is in given suffix.
753TEST_F(UnwinderTest, map_ignore_suffixes) {
754 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
755 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
756 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
757 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
758
759 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700760 regs_.set_pc(0x1000);
761 regs_.set_sp(0x10000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700762 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
763 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
764 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
765
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800766 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700767 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700768 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800769 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700770
771 ASSERT_EQ(2U, unwinder.NumFrames());
772 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800773 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700774 ASSERT_TRUE(map_info != nullptr);
775 EXPECT_TRUE(map_info->elf == nullptr);
776
777 auto* frame = &unwinder.frames()[0];
778 EXPECT_EQ(0U, frame->num);
779 EXPECT_EQ(0U, frame->rel_pc);
780 EXPECT_EQ(0x1000U, frame->pc);
781 EXPECT_EQ(0x10000U, frame->sp);
782 EXPECT_EQ("Frame0", frame->function_name);
783 EXPECT_EQ(0U, frame->function_offset);
784 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800785 EXPECT_EQ(0U, frame->map_elf_start_offset);
786 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700787 EXPECT_EQ(0x1000U, frame->map_start);
788 EXPECT_EQ(0x8000U, frame->map_end);
789 EXPECT_EQ(0U, frame->map_load_bias);
790 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
791
792 frame = &unwinder.frames()[1];
793 EXPECT_EQ(1U, frame->num);
794 EXPECT_EQ(0x400U, frame->rel_pc);
795 EXPECT_EQ(0x43400U, frame->pc);
796 EXPECT_EQ(0x10010U, frame->sp);
797 EXPECT_EQ("Frame1", frame->function_name);
798 EXPECT_EQ(1U, frame->function_offset);
799 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800800 EXPECT_EQ(0U, frame->map_elf_start_offset);
801 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700802 EXPECT_EQ(0x43000U, frame->map_start);
803 EXPECT_EQ(0x44000U, frame->map_end);
804 EXPECT_EQ(0U, frame->map_load_bias);
805 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
806}
807
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700808// Verify that an unwind stops when the sp and pc don't change.
809TEST_F(UnwinderTest, sp_pc_do_not_change) {
810 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
811 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
812 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
813 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
814 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
815
Yabin Cui11e96fe2018-03-14 18:16:22 -0700816 regs_.set_pc(0x1000);
817 regs_.set_sp(0x10000);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700818 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
819 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
820 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
821 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
822 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
823 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
824
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800825 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700826 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800827 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700828
829 ASSERT_EQ(3U, unwinder.NumFrames());
830
831 auto* frame = &unwinder.frames()[0];
832 EXPECT_EQ(0U, frame->num);
833 EXPECT_EQ(0U, frame->rel_pc);
834 EXPECT_EQ(0x1000U, frame->pc);
835 EXPECT_EQ(0x10000U, frame->sp);
836 EXPECT_EQ("Frame0", frame->function_name);
837 EXPECT_EQ(0U, frame->function_offset);
838 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800839 EXPECT_EQ(0U, frame->map_elf_start_offset);
840 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700841 EXPECT_EQ(0x1000U, frame->map_start);
842 EXPECT_EQ(0x8000U, frame->map_end);
843 EXPECT_EQ(0U, frame->map_load_bias);
844 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
845
846 frame = &unwinder.frames()[1];
847 EXPECT_EQ(1U, frame->num);
848 EXPECT_EQ(0x400U, frame->rel_pc);
849 EXPECT_EQ(0x33400U, frame->pc);
850 EXPECT_EQ(0x10010U, frame->sp);
851 EXPECT_EQ("Frame1", frame->function_name);
852 EXPECT_EQ(1U, frame->function_offset);
853 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800854 EXPECT_EQ(0U, frame->map_elf_start_offset);
855 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700856 EXPECT_EQ(0x33000U, frame->map_start);
857 EXPECT_EQ(0x34000U, frame->map_end);
858 EXPECT_EQ(0U, frame->map_load_bias);
859 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
860
861 frame = &unwinder.frames()[2];
862 EXPECT_EQ(2U, frame->num);
863 EXPECT_EQ(0x500U, frame->rel_pc);
864 EXPECT_EQ(0x33500U, frame->pc);
865 EXPECT_EQ(0x10020U, frame->sp);
866 EXPECT_EQ("Frame2", frame->function_name);
867 EXPECT_EQ(2U, frame->function_offset);
868 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800869 EXPECT_EQ(0U, frame->map_elf_start_offset);
870 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700871 EXPECT_EQ(0x33000U, frame->map_start);
872 EXPECT_EQ(0x34000U, frame->map_end);
873 EXPECT_EQ(0U, frame->map_load_bias);
874 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
875}
876
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800877TEST_F(UnwinderTest, dex_pc_in_map) {
878 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700879 regs_.set_pc(0x1000);
880 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800881 regs_.FakeSetDexPc(0xa3400);
882
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800883 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800884 unwinder.Unwind();
885 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
886
887 ASSERT_EQ(2U, unwinder.NumFrames());
888
889 auto* frame = &unwinder.frames()[0];
890 EXPECT_EQ(0U, frame->num);
891 EXPECT_EQ(0x400U, frame->rel_pc);
892 EXPECT_EQ(0xa3400U, frame->pc);
893 EXPECT_EQ(0x10000U, frame->sp);
894 EXPECT_EQ("", frame->function_name);
895 EXPECT_EQ(0U, frame->function_offset);
896 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800897 EXPECT_EQ(0U, frame->map_elf_start_offset);
898 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800899 EXPECT_EQ(0xa3000U, frame->map_start);
900 EXPECT_EQ(0xa4000U, frame->map_end);
901 EXPECT_EQ(0U, frame->map_load_bias);
902 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
903
904 frame = &unwinder.frames()[1];
905 EXPECT_EQ(1U, frame->num);
906 EXPECT_EQ(0U, frame->rel_pc);
907 EXPECT_EQ(0x1000U, frame->pc);
908 EXPECT_EQ(0x10000U, frame->sp);
909 EXPECT_EQ("Frame0", frame->function_name);
910 EXPECT_EQ(0U, frame->function_offset);
911 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800912 EXPECT_EQ(0U, frame->map_elf_start_offset);
913 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800914 EXPECT_EQ(0x1000U, frame->map_start);
915 EXPECT_EQ(0x8000U, frame->map_end);
916 EXPECT_EQ(0U, frame->map_load_bias);
917 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
918}
919
920TEST_F(UnwinderTest, dex_pc_not_in_map) {
921 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700922 regs_.set_pc(0x1000);
923 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800924 regs_.FakeSetDexPc(0x50000);
925
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800926 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800927 unwinder.Unwind();
928 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
929
930 ASSERT_EQ(2U, unwinder.NumFrames());
931
932 auto* frame = &unwinder.frames()[0];
933 EXPECT_EQ(0U, frame->num);
934 EXPECT_EQ(0x50000U, frame->rel_pc);
935 EXPECT_EQ(0x50000U, frame->pc);
936 EXPECT_EQ(0x10000U, frame->sp);
937 EXPECT_EQ("", frame->function_name);
938 EXPECT_EQ(0U, frame->function_offset);
939 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800940 EXPECT_EQ(0U, frame->map_elf_start_offset);
941 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800942 EXPECT_EQ(0U, frame->map_start);
943 EXPECT_EQ(0U, frame->map_end);
944 EXPECT_EQ(0U, frame->map_load_bias);
945 EXPECT_EQ(0, frame->map_flags);
946
947 frame = &unwinder.frames()[1];
948 EXPECT_EQ(1U, frame->num);
949 EXPECT_EQ(0U, frame->rel_pc);
950 EXPECT_EQ(0x1000U, frame->pc);
951 EXPECT_EQ(0x10000U, frame->sp);
952 EXPECT_EQ("Frame0", frame->function_name);
953 EXPECT_EQ(0U, frame->function_offset);
954 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800955 EXPECT_EQ(0U, frame->map_elf_start_offset);
956 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800957 EXPECT_EQ(0x1000U, frame->map_start);
958 EXPECT_EQ(0x8000U, frame->map_end);
959 EXPECT_EQ(0U, frame->map_load_bias);
960 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
961}
962
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800963TEST_F(UnwinderTest, dex_pc_multiple_frames) {
964 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
965 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700966 regs_.set_pc(0x1000);
967 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800968 regs_.FakeSetDexPc(0xa3400);
969 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
970 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
971
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800972 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800973 unwinder.Unwind();
974 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
975
976 ASSERT_EQ(3U, unwinder.NumFrames());
977
978 auto* frame = &unwinder.frames()[0];
979 EXPECT_EQ(0U, frame->num);
980 EXPECT_EQ(0x400U, frame->rel_pc);
981 EXPECT_EQ(0xa3400U, frame->pc);
982 EXPECT_EQ(0x10000U, frame->sp);
983 EXPECT_EQ("", frame->function_name);
984 EXPECT_EQ(0U, frame->function_offset);
985 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800986 EXPECT_EQ(0U, frame->map_elf_start_offset);
987 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800988 EXPECT_EQ(0xa3000U, frame->map_start);
989 EXPECT_EQ(0xa4000U, frame->map_end);
990 EXPECT_EQ(0U, frame->map_load_bias);
991 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
992
993 frame = &unwinder.frames()[1];
994 EXPECT_EQ(1U, frame->num);
995 EXPECT_EQ(0U, frame->rel_pc);
996 EXPECT_EQ(0x1000U, frame->pc);
997 EXPECT_EQ(0x10000U, frame->sp);
998 EXPECT_EQ("Frame0", frame->function_name);
999 EXPECT_EQ(0U, frame->function_offset);
1000 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001001 EXPECT_EQ(0U, frame->map_elf_start_offset);
1002 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001003 EXPECT_EQ(0x1000U, frame->map_start);
1004 EXPECT_EQ(0x8000U, frame->map_end);
1005 EXPECT_EQ(0U, frame->map_load_bias);
1006 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1007
1008 frame = &unwinder.frames()[2];
1009 EXPECT_EQ(2U, frame->num);
1010 EXPECT_EQ(0x400U, frame->rel_pc);
1011 EXPECT_EQ(0x33400U, frame->pc);
1012 EXPECT_EQ(0x10010U, frame->sp);
1013 EXPECT_EQ("Frame1", frame->function_name);
1014 EXPECT_EQ(1U, frame->function_offset);
1015 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001016 EXPECT_EQ(0U, frame->map_elf_start_offset);
1017 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001018 EXPECT_EQ(0x33000U, frame->map_start);
1019 EXPECT_EQ(0x34000U, frame->map_end);
1020 EXPECT_EQ(0U, frame->map_load_bias);
1021 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1022}
1023
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001024TEST_F(UnwinderTest, dex_pc_max_frames) {
1025 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1026 regs_.set_pc(0x1000);
1027 regs_.set_sp(0x10000);
1028 regs_.FakeSetDexPc(0xa3400);
1029
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001030 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001031 unwinder.Unwind();
1032 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
1033
1034 ASSERT_EQ(1U, unwinder.NumFrames());
1035
1036 auto* frame = &unwinder.frames()[0];
1037 EXPECT_EQ(0U, frame->num);
1038 EXPECT_EQ(0x400U, frame->rel_pc);
1039 EXPECT_EQ(0xa3400U, frame->pc);
1040 EXPECT_EQ(0x10000U, frame->sp);
1041 EXPECT_EQ("", frame->function_name);
1042 EXPECT_EQ(0U, frame->function_offset);
1043 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001044 EXPECT_EQ(0U, frame->map_elf_start_offset);
1045 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001046 EXPECT_EQ(0xa3000U, frame->map_start);
1047 EXPECT_EQ(0xa4000U, frame->map_end);
1048 EXPECT_EQ(0U, frame->map_load_bias);
1049 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1050}
1051
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001052// Verify format frame code.
1053TEST_F(UnwinderTest, format_frame_static) {
1054 FrameData frame;
1055 frame.num = 1;
1056 frame.rel_pc = 0x1000;
1057 frame.pc = 0x4000;
1058 frame.sp = 0x1000;
1059 frame.function_name = "function";
1060 frame.function_offset = 100;
1061 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001062 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001063 frame.map_start = 0x3000;
1064 frame.map_end = 0x6000;
1065 frame.map_flags = PROT_READ;
1066
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001067 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001068 Unwinder::FormatFrame(frame, false));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001069 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001070 Unwinder::FormatFrame(frame, true));
1071
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001072 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001073 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
1074 Unwinder::FormatFrame(frame, false));
1075 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)",
1076 Unwinder::FormatFrame(frame, true));
1077
1078 frame.function_offset = 0;
1079 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
1080 Unwinder::FormatFrame(frame, false));
1081 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", Unwinder::FormatFrame(frame, true));
1082
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001083 // Verify the function name is demangled.
1084 frame.function_name = "_ZN4funcEv";
1085 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())",
1086 Unwinder::FormatFrame(frame, false));
1087 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", Unwinder::FormatFrame(frame, true));
1088
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001089 frame.function_name = "";
1090 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", Unwinder::FormatFrame(frame, false));
1091 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", Unwinder::FormatFrame(frame, true));
1092
1093 frame.map_name = "";
1094 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", Unwinder::FormatFrame(frame, false));
1095 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", Unwinder::FormatFrame(frame, true));
1096
1097 frame.map_start = 0;
1098 frame.map_end = 0;
1099 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", Unwinder::FormatFrame(frame, false));
1100 EXPECT_EQ(" #01 pc 00001000 <unknown>", Unwinder::FormatFrame(frame, true));
1101}
1102
Christopher Ferris02fdb562017-12-08 15:04:49 -08001103static std::string ArchToString(ArchEnum arch) {
1104 if (arch == ARCH_ARM) {
1105 return "Arm";
1106 } else if (arch == ARCH_ARM64) {
1107 return "Arm64";
1108 } else if (arch == ARCH_X86) {
1109 return "X86";
1110 } else if (arch == ARCH_X86_64) {
1111 return "X86_64";
1112 } else {
1113 return "Unknown";
1114 }
1115}
1116
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001117// Verify format frame code.
1118TEST_F(UnwinderTest, format_frame) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001119 std::vector<Regs*> reg_list;
1120 RegsArm* arm = new RegsArm;
1121 arm->set_pc(0x2300);
1122 arm->set_sp(0x10000);
1123 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001124
Christopher Ferris02fdb562017-12-08 15:04:49 -08001125 RegsArm64* arm64 = new RegsArm64;
1126 arm64->set_pc(0x2300);
1127 arm64->set_sp(0x10000);
1128 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001129
Christopher Ferris02fdb562017-12-08 15:04:49 -08001130 RegsX86* x86 = new RegsX86;
1131 x86->set_pc(0x2300);
1132 x86->set_sp(0x10000);
1133 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001134
Christopher Ferris02fdb562017-12-08 15:04:49 -08001135 RegsX86_64* x86_64 = new RegsX86_64;
1136 x86_64->set_pc(0x2300);
1137 x86_64->set_sp(0x10000);
1138 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001139
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001140 RegsMips* mips = new RegsMips;
1141 mips->set_pc(0x2300);
1142 mips->set_sp(0x10000);
1143 reg_list.push_back(mips);
1144
1145 RegsMips64* mips64 = new RegsMips64;
1146 mips64->set_pc(0x2300);
1147 mips64->set_sp(0x10000);
1148 reg_list.push_back(mips64);
1149
Christopher Ferris02fdb562017-12-08 15:04:49 -08001150 for (auto regs : reg_list) {
1151 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001152
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001153 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001154 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001155
Christopher Ferris02fdb562017-12-08 15:04:49 -08001156 ASSERT_EQ(1U, unwinder.NumFrames());
1157 std::string expected;
1158 switch (regs->Arch()) {
1159 case ARCH_ARM:
1160 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001161 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001162 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1163 break;
1164 case ARCH_ARM64:
1165 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001166 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001167 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1168 break;
1169 default:
1170 expected = "";
1171 }
1172 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1173 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1174 delete regs;
1175 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001176}
1177
1178} // namespace unwindstack