blob: 2dc511848d4d2479c78407b956949d636e5adfd2 [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) {
Florian Mayer3d67d342019-02-27 18:00:37 +000052 const auto& map_info = *--maps_->end();
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080053 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");
Florian Mayer3d67d342019-02-27 18:00:37 +000088 const auto& 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);
Florian Mayer3d67d342019-02-27 18:00:37 +0000101 const auto& info2 = *--maps_->end();
102 info2->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
Florian Mayerc479e4e2019-01-23 13:35:40 +0000752// Verify that a speculative frame does not cause a crash when it wasn't
753// really added due to a filter.
754TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
755 regs_.set_pc(0x23000);
756 regs_.set_sp(0x10000);
757 regs_.FakeSetReturnAddress(0x23100);
758 regs_.FakeSetReturnAddressValid(true);
759
760 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
761
762 std::vector<std::string> skip_names{"libanother.so"};
763 unwinder.Unwind(&skip_names);
764 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
765
766 ASSERT_EQ(0U, unwinder.NumFrames());
767}
768
Christopher Ferrise69f4702017-10-19 16:08:58 -0700769// Verify that an unwind stops when a frame is in given suffix.
770TEST_F(UnwinderTest, map_ignore_suffixes) {
771 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
772 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
773 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
774 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
775
776 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700777 regs_.set_pc(0x1000);
778 regs_.set_sp(0x10000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700779 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
780 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
781 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
782
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800783 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700784 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700785 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800786 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700787
788 ASSERT_EQ(2U, unwinder.NumFrames());
789 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800790 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700791 ASSERT_TRUE(map_info != nullptr);
792 EXPECT_TRUE(map_info->elf == nullptr);
793
794 auto* frame = &unwinder.frames()[0];
795 EXPECT_EQ(0U, frame->num);
796 EXPECT_EQ(0U, frame->rel_pc);
797 EXPECT_EQ(0x1000U, frame->pc);
798 EXPECT_EQ(0x10000U, frame->sp);
799 EXPECT_EQ("Frame0", frame->function_name);
800 EXPECT_EQ(0U, frame->function_offset);
801 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800802 EXPECT_EQ(0U, frame->map_elf_start_offset);
803 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700804 EXPECT_EQ(0x1000U, frame->map_start);
805 EXPECT_EQ(0x8000U, frame->map_end);
806 EXPECT_EQ(0U, frame->map_load_bias);
807 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
808
809 frame = &unwinder.frames()[1];
810 EXPECT_EQ(1U, frame->num);
811 EXPECT_EQ(0x400U, frame->rel_pc);
812 EXPECT_EQ(0x43400U, frame->pc);
813 EXPECT_EQ(0x10010U, frame->sp);
814 EXPECT_EQ("Frame1", frame->function_name);
815 EXPECT_EQ(1U, frame->function_offset);
816 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800817 EXPECT_EQ(0U, frame->map_elf_start_offset);
818 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700819 EXPECT_EQ(0x43000U, frame->map_start);
820 EXPECT_EQ(0x44000U, frame->map_end);
821 EXPECT_EQ(0U, frame->map_load_bias);
822 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
823}
824
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700825// Verify that an unwind stops when the sp and pc don't change.
826TEST_F(UnwinderTest, sp_pc_do_not_change) {
827 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
828 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
829 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
830 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
831 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
832
Yabin Cui11e96fe2018-03-14 18:16:22 -0700833 regs_.set_pc(0x1000);
834 regs_.set_sp(0x10000);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700835 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
836 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
837 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
838 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
839 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
840 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
841
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800842 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700843 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800844 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700845
846 ASSERT_EQ(3U, unwinder.NumFrames());
847
848 auto* frame = &unwinder.frames()[0];
849 EXPECT_EQ(0U, frame->num);
850 EXPECT_EQ(0U, frame->rel_pc);
851 EXPECT_EQ(0x1000U, frame->pc);
852 EXPECT_EQ(0x10000U, frame->sp);
853 EXPECT_EQ("Frame0", frame->function_name);
854 EXPECT_EQ(0U, frame->function_offset);
855 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800856 EXPECT_EQ(0U, frame->map_elf_start_offset);
857 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700858 EXPECT_EQ(0x1000U, frame->map_start);
859 EXPECT_EQ(0x8000U, frame->map_end);
860 EXPECT_EQ(0U, frame->map_load_bias);
861 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
862
863 frame = &unwinder.frames()[1];
864 EXPECT_EQ(1U, frame->num);
865 EXPECT_EQ(0x400U, frame->rel_pc);
866 EXPECT_EQ(0x33400U, frame->pc);
867 EXPECT_EQ(0x10010U, frame->sp);
868 EXPECT_EQ("Frame1", frame->function_name);
869 EXPECT_EQ(1U, frame->function_offset);
870 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800871 EXPECT_EQ(0U, frame->map_elf_start_offset);
872 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700873 EXPECT_EQ(0x33000U, frame->map_start);
874 EXPECT_EQ(0x34000U, frame->map_end);
875 EXPECT_EQ(0U, frame->map_load_bias);
876 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
877
878 frame = &unwinder.frames()[2];
879 EXPECT_EQ(2U, frame->num);
880 EXPECT_EQ(0x500U, frame->rel_pc);
881 EXPECT_EQ(0x33500U, frame->pc);
882 EXPECT_EQ(0x10020U, frame->sp);
883 EXPECT_EQ("Frame2", frame->function_name);
884 EXPECT_EQ(2U, frame->function_offset);
885 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800886 EXPECT_EQ(0U, frame->map_elf_start_offset);
887 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700888 EXPECT_EQ(0x33000U, frame->map_start);
889 EXPECT_EQ(0x34000U, frame->map_end);
890 EXPECT_EQ(0U, frame->map_load_bias);
891 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
892}
893
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800894TEST_F(UnwinderTest, dex_pc_in_map) {
895 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700896 regs_.set_pc(0x1000);
897 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800898 regs_.FakeSetDexPc(0xa3400);
899
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800900 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800901 unwinder.Unwind();
902 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
903
904 ASSERT_EQ(2U, 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);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800914 EXPECT_EQ(0U, frame->map_elf_start_offset);
915 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800916 EXPECT_EQ(0xa3000U, frame->map_start);
917 EXPECT_EQ(0xa4000U, frame->map_end);
918 EXPECT_EQ(0U, frame->map_load_bias);
919 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
920
921 frame = &unwinder.frames()[1];
922 EXPECT_EQ(1U, frame->num);
923 EXPECT_EQ(0U, frame->rel_pc);
924 EXPECT_EQ(0x1000U, frame->pc);
925 EXPECT_EQ(0x10000U, frame->sp);
926 EXPECT_EQ("Frame0", frame->function_name);
927 EXPECT_EQ(0U, frame->function_offset);
928 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800929 EXPECT_EQ(0U, frame->map_elf_start_offset);
930 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800931 EXPECT_EQ(0x1000U, frame->map_start);
932 EXPECT_EQ(0x8000U, frame->map_end);
933 EXPECT_EQ(0U, frame->map_load_bias);
934 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
935}
936
937TEST_F(UnwinderTest, dex_pc_not_in_map) {
938 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700939 regs_.set_pc(0x1000);
940 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800941 regs_.FakeSetDexPc(0x50000);
942
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800943 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800944 unwinder.Unwind();
945 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
946
947 ASSERT_EQ(2U, unwinder.NumFrames());
948
949 auto* frame = &unwinder.frames()[0];
950 EXPECT_EQ(0U, frame->num);
951 EXPECT_EQ(0x50000U, frame->rel_pc);
952 EXPECT_EQ(0x50000U, frame->pc);
953 EXPECT_EQ(0x10000U, frame->sp);
954 EXPECT_EQ("", frame->function_name);
955 EXPECT_EQ(0U, frame->function_offset);
956 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800957 EXPECT_EQ(0U, frame->map_elf_start_offset);
958 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800959 EXPECT_EQ(0U, frame->map_start);
960 EXPECT_EQ(0U, frame->map_end);
961 EXPECT_EQ(0U, frame->map_load_bias);
962 EXPECT_EQ(0, frame->map_flags);
963
964 frame = &unwinder.frames()[1];
965 EXPECT_EQ(1U, frame->num);
966 EXPECT_EQ(0U, frame->rel_pc);
967 EXPECT_EQ(0x1000U, frame->pc);
968 EXPECT_EQ(0x10000U, frame->sp);
969 EXPECT_EQ("Frame0", frame->function_name);
970 EXPECT_EQ(0U, frame->function_offset);
971 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800972 EXPECT_EQ(0U, frame->map_elf_start_offset);
973 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800974 EXPECT_EQ(0x1000U, frame->map_start);
975 EXPECT_EQ(0x8000U, frame->map_end);
976 EXPECT_EQ(0U, frame->map_load_bias);
977 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
978}
979
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800980TEST_F(UnwinderTest, dex_pc_multiple_frames) {
981 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
982 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700983 regs_.set_pc(0x1000);
984 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800985 regs_.FakeSetDexPc(0xa3400);
986 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
987 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
988
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800989 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -0800990 unwinder.Unwind();
991 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
992
993 ASSERT_EQ(3U, unwinder.NumFrames());
994
995 auto* frame = &unwinder.frames()[0];
996 EXPECT_EQ(0U, frame->num);
997 EXPECT_EQ(0x400U, frame->rel_pc);
998 EXPECT_EQ(0xa3400U, frame->pc);
999 EXPECT_EQ(0x10000U, frame->sp);
1000 EXPECT_EQ("", frame->function_name);
1001 EXPECT_EQ(0U, frame->function_offset);
1002 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001003 EXPECT_EQ(0U, frame->map_elf_start_offset);
1004 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001005 EXPECT_EQ(0xa3000U, frame->map_start);
1006 EXPECT_EQ(0xa4000U, frame->map_end);
1007 EXPECT_EQ(0U, frame->map_load_bias);
1008 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1009
1010 frame = &unwinder.frames()[1];
1011 EXPECT_EQ(1U, frame->num);
1012 EXPECT_EQ(0U, frame->rel_pc);
1013 EXPECT_EQ(0x1000U, frame->pc);
1014 EXPECT_EQ(0x10000U, frame->sp);
1015 EXPECT_EQ("Frame0", frame->function_name);
1016 EXPECT_EQ(0U, frame->function_offset);
1017 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001018 EXPECT_EQ(0U, frame->map_elf_start_offset);
1019 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001020 EXPECT_EQ(0x1000U, frame->map_start);
1021 EXPECT_EQ(0x8000U, frame->map_end);
1022 EXPECT_EQ(0U, frame->map_load_bias);
1023 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1024
1025 frame = &unwinder.frames()[2];
1026 EXPECT_EQ(2U, frame->num);
1027 EXPECT_EQ(0x400U, frame->rel_pc);
1028 EXPECT_EQ(0x33400U, frame->pc);
1029 EXPECT_EQ(0x10010U, frame->sp);
1030 EXPECT_EQ("Frame1", frame->function_name);
1031 EXPECT_EQ(1U, frame->function_offset);
1032 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001033 EXPECT_EQ(0U, frame->map_elf_start_offset);
1034 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001035 EXPECT_EQ(0x33000U, frame->map_start);
1036 EXPECT_EQ(0x34000U, frame->map_end);
1037 EXPECT_EQ(0U, frame->map_load_bias);
1038 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1039}
1040
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001041TEST_F(UnwinderTest, dex_pc_max_frames) {
1042 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1043 regs_.set_pc(0x1000);
1044 regs_.set_sp(0x10000);
1045 regs_.FakeSetDexPc(0xa3400);
1046
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001047 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001048 unwinder.Unwind();
1049 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
1050
1051 ASSERT_EQ(1U, unwinder.NumFrames());
1052
1053 auto* frame = &unwinder.frames()[0];
1054 EXPECT_EQ(0U, frame->num);
1055 EXPECT_EQ(0x400U, frame->rel_pc);
1056 EXPECT_EQ(0xa3400U, frame->pc);
1057 EXPECT_EQ(0x10000U, frame->sp);
1058 EXPECT_EQ("", frame->function_name);
1059 EXPECT_EQ(0U, frame->function_offset);
1060 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001061 EXPECT_EQ(0U, frame->map_elf_start_offset);
1062 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001063 EXPECT_EQ(0xa3000U, frame->map_start);
1064 EXPECT_EQ(0xa4000U, frame->map_end);
1065 EXPECT_EQ(0U, frame->map_load_bias);
1066 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1067}
1068
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001069// Verify format frame code.
1070TEST_F(UnwinderTest, format_frame_static) {
1071 FrameData frame;
1072 frame.num = 1;
1073 frame.rel_pc = 0x1000;
1074 frame.pc = 0x4000;
1075 frame.sp = 0x1000;
1076 frame.function_name = "function";
1077 frame.function_offset = 100;
1078 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001079 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001080 frame.map_start = 0x3000;
1081 frame.map_end = 0x6000;
1082 frame.map_flags = PROT_READ;
1083
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001084 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001085 Unwinder::FormatFrame(frame, false));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001086 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001087 Unwinder::FormatFrame(frame, true));
1088
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001089 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001090 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
1091 Unwinder::FormatFrame(frame, false));
1092 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)",
1093 Unwinder::FormatFrame(frame, true));
1094
1095 frame.function_offset = 0;
1096 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
1097 Unwinder::FormatFrame(frame, false));
1098 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", Unwinder::FormatFrame(frame, true));
1099
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001100 // Verify the function name is demangled.
1101 frame.function_name = "_ZN4funcEv";
1102 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())",
1103 Unwinder::FormatFrame(frame, false));
1104 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", Unwinder::FormatFrame(frame, true));
1105
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001106 frame.function_name = "";
1107 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", Unwinder::FormatFrame(frame, false));
1108 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", Unwinder::FormatFrame(frame, true));
1109
1110 frame.map_name = "";
1111 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", Unwinder::FormatFrame(frame, false));
1112 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", Unwinder::FormatFrame(frame, true));
1113
1114 frame.map_start = 0;
1115 frame.map_end = 0;
1116 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", Unwinder::FormatFrame(frame, false));
1117 EXPECT_EQ(" #01 pc 00001000 <unknown>", Unwinder::FormatFrame(frame, true));
1118}
1119
Christopher Ferris02fdb562017-12-08 15:04:49 -08001120static std::string ArchToString(ArchEnum arch) {
1121 if (arch == ARCH_ARM) {
1122 return "Arm";
1123 } else if (arch == ARCH_ARM64) {
1124 return "Arm64";
1125 } else if (arch == ARCH_X86) {
1126 return "X86";
1127 } else if (arch == ARCH_X86_64) {
1128 return "X86_64";
1129 } else {
1130 return "Unknown";
1131 }
1132}
1133
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001134// Verify format frame code.
1135TEST_F(UnwinderTest, format_frame) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001136 std::vector<Regs*> reg_list;
1137 RegsArm* arm = new RegsArm;
1138 arm->set_pc(0x2300);
1139 arm->set_sp(0x10000);
1140 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001141
Christopher Ferris02fdb562017-12-08 15:04:49 -08001142 RegsArm64* arm64 = new RegsArm64;
1143 arm64->set_pc(0x2300);
1144 arm64->set_sp(0x10000);
1145 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001146
Christopher Ferris02fdb562017-12-08 15:04:49 -08001147 RegsX86* x86 = new RegsX86;
1148 x86->set_pc(0x2300);
1149 x86->set_sp(0x10000);
1150 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001151
Christopher Ferris02fdb562017-12-08 15:04:49 -08001152 RegsX86_64* x86_64 = new RegsX86_64;
1153 x86_64->set_pc(0x2300);
1154 x86_64->set_sp(0x10000);
1155 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001156
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001157 RegsMips* mips = new RegsMips;
1158 mips->set_pc(0x2300);
1159 mips->set_sp(0x10000);
1160 reg_list.push_back(mips);
1161
1162 RegsMips64* mips64 = new RegsMips64;
1163 mips64->set_pc(0x2300);
1164 mips64->set_sp(0x10000);
1165 reg_list.push_back(mips64);
1166
Christopher Ferris02fdb562017-12-08 15:04:49 -08001167 for (auto regs : reg_list) {
1168 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001169
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001170 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001171 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001172
Christopher Ferris02fdb562017-12-08 15:04:49 -08001173 ASSERT_EQ(1U, unwinder.NumFrames());
1174 std::string expected;
1175 switch (regs->Arch()) {
1176 case ARCH_ARM:
1177 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001178 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001179 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1180 break;
1181 case ARCH_ARM64:
1182 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001183 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001184 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1185 break;
1186 default:
1187 expected = "";
1188 }
1189 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1190 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1191 delete regs;
1192 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001193}
1194
1195} // namespace unwindstack