blob: f6350216fdc0101fd032133b0c620c1509ae222e [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 Ferris78133452019-03-14 13:44:38 -070061 ElfInterfaceFake* interface_fake = new ElfInterfaceFake(nullptr);
62 interface_fake->FakeSetBuildID("FAKE");
63 elf->FakeSetInterface(interface_fake);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080064 AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070065
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080066 AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070067
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080068 AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
69 "/dev/fake_device");
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070070
Christopher Ferris02fdb562017-12-08 15:04:49 -080071 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070072 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080073 AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070074
Christopher Ferris02fdb562017-12-08 15:04:49 -080075 elf = new ElfFake(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -070076 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080077 AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -070078
Christopher Ferris02fdb562017-12-08 15:04:49 -080079 elf = new ElfFake(new MemoryFake);
Christopher Ferrise69f4702017-10-19 16:08:58 -070080 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080081 AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
Christopher Ferrise69f4702017-10-19 16:08:58 -070082
Christopher Ferris02fdb562017-12-08 15:04:49 -080083 elf = new ElfFake(new MemoryFake);
Christopher Ferris02a6c442019-03-11 14:43:33 -070084 ElfInterfaceFake* interface = new ElfInterfaceFake(nullptr);
85 interface->FakeSetSoname("lib_fake.so");
86 elf->FakeSetInterface(interface);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080087 AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
Christopher Ferris02a6c442019-03-11 14:43:33 -070088 MapInfo* map_info = maps_->Find(0x43000);
89 ASSERT_TRUE(map_info != nullptr);
90 map_info->elf_start_offset = 0x1d000;
Christopher Ferrise69f4702017-10-19 16:08:58 -070091
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080092 AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
Christopher Ferris02fdb562017-12-08 15:04:49 -080093
Christopher Ferrisa09c4a62018-12-13 16:08:50 -080094 AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
Florian Mayer3d67d342019-02-27 18:00:37 +000095 const auto& info = *--maps_->end();
Christopher Ferrise762f1f2018-02-06 14:51:48 -080096 info->load_bias = 0;
Christopher Ferrise762f1f2018-02-06 14:51:48 -080097
Christopher Ferrise4df5f52018-02-12 13:24:18 -080098 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -080099 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
100 elf->FakeSetLoadBias(0x5000);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800101 AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
102 elf);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800103
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800104 elf = new ElfFake(new MemoryFake);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800105 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800106 AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_offset.oat",
107 elf);
Florian Mayer3d67d342019-02-27 18:00:37 +0000108 const auto& info2 = *--maps_->end();
109 info2->elf_offset = 0x8000;
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800110
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700111 elf = new ElfFake(new MemoryFake);
112 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
113 AddMapInfo(0xc0000, 0xc1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/unreadable.so", elf);
114 const auto& info3 = *--maps_->end();
115 info3->memory_backed_elf = true;
116
117 elf = new ElfFake(new MemoryFake);
118 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
119 AddMapInfo(0xc1000, 0xc2000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "[vdso]", elf);
120 const auto& info4 = *--maps_->end();
121 info4->memory_backed_elf = true;
122
123 elf = new ElfFake(new MemoryFake);
124 elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
125 AddMapInfo(0xc2000, 0xc3000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "", elf);
126 const auto& info5 = *--maps_->end();
127 info5->memory_backed_elf = true;
128
Christopher Ferris02fdb562017-12-08 15:04:49 -0800129 process_memory_.reset(new MemoryFake);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700130 }
131
132 void SetUp() override {
133 ElfInterfaceFake::FakeClear();
Christopher Ferrisd06001d2017-11-30 18:56:01 -0800134 regs_.FakeSetArch(ARCH_ARM);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700135 regs_.FakeSetReturnAddressValid(false);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700136 }
137
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800138 static std::unique_ptr<Maps> maps_;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700139 static RegsFake regs_;
140 static std::shared_ptr<Memory> process_memory_;
141};
142
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800143std::unique_ptr<Maps> UnwinderTest::maps_;
Yabin Cui11e96fe2018-03-14 18:16:22 -0700144RegsFake UnwinderTest::regs_(5);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700145std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
146
147TEST_F(UnwinderTest, multiple_frames) {
148 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
149 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
150 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
151
Yabin Cui11e96fe2018-03-14 18:16:22 -0700152 regs_.set_pc(0x1000);
153 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700154 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
155 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
156 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
157
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800158 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700159 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800160 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700161 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700162
163 ASSERT_EQ(3U, unwinder.NumFrames());
164
165 auto* frame = &unwinder.frames()[0];
166 EXPECT_EQ(0U, frame->num);
167 EXPECT_EQ(0U, frame->rel_pc);
168 EXPECT_EQ(0x1000U, frame->pc);
169 EXPECT_EQ(0x10000U, frame->sp);
170 EXPECT_EQ("Frame0", frame->function_name);
171 EXPECT_EQ(0U, frame->function_offset);
172 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800173 EXPECT_EQ(0U, frame->map_elf_start_offset);
174 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700175 EXPECT_EQ(0x1000U, frame->map_start);
176 EXPECT_EQ(0x8000U, frame->map_end);
177 EXPECT_EQ(0U, frame->map_load_bias);
178 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
179
180 frame = &unwinder.frames()[1];
181 EXPECT_EQ(1U, frame->num);
182 EXPECT_EQ(0x100U, frame->rel_pc);
183 EXPECT_EQ(0x1100U, frame->pc);
184 EXPECT_EQ(0x10010U, frame->sp);
185 EXPECT_EQ("Frame1", frame->function_name);
186 EXPECT_EQ(1U, frame->function_offset);
187 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800188 EXPECT_EQ(0U, frame->map_elf_start_offset);
189 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700190 EXPECT_EQ(0x1000U, frame->map_start);
191 EXPECT_EQ(0x8000U, frame->map_end);
192 EXPECT_EQ(0U, frame->map_load_bias);
193 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
194
195 frame = &unwinder.frames()[2];
196 EXPECT_EQ(2U, frame->num);
197 EXPECT_EQ(0x200U, frame->rel_pc);
198 EXPECT_EQ(0x1200U, frame->pc);
199 EXPECT_EQ(0x10020U, frame->sp);
200 EXPECT_EQ("Frame2", frame->function_name);
201 EXPECT_EQ(2U, frame->function_offset);
202 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800203 EXPECT_EQ(0U, frame->map_elf_start_offset);
204 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700205 EXPECT_EQ(0x1000U, frame->map_start);
206 EXPECT_EQ(0x8000U, frame->map_end);
207 EXPECT_EQ(0U, frame->map_load_bias);
208 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
209}
210
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800211TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
212 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
213 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
214 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
215
Yabin Cui11e96fe2018-03-14 18:16:22 -0700216 regs_.set_pc(0x1000);
217 regs_.set_sp(0x10000);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800218 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
219 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
220 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
221
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800222 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800223 unwinder.SetResolveNames(false);
224 unwinder.Unwind();
225 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700226 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800227
228 ASSERT_EQ(3U, unwinder.NumFrames());
229
230 auto* frame = &unwinder.frames()[0];
231 EXPECT_EQ(0U, frame->num);
232 EXPECT_EQ(0U, frame->rel_pc);
233 EXPECT_EQ(0x1000U, frame->pc);
234 EXPECT_EQ(0x10000U, frame->sp);
235 EXPECT_EQ("", frame->function_name);
236 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000237 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800238 EXPECT_EQ(0U, frame->map_elf_start_offset);
239 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800240 EXPECT_EQ(0x1000U, frame->map_start);
241 EXPECT_EQ(0x8000U, frame->map_end);
242 EXPECT_EQ(0U, frame->map_load_bias);
243 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
244
245 frame = &unwinder.frames()[1];
246 EXPECT_EQ(1U, frame->num);
247 EXPECT_EQ(0x100U, frame->rel_pc);
248 EXPECT_EQ(0x1100U, frame->pc);
249 EXPECT_EQ(0x10010U, frame->sp);
250 EXPECT_EQ("", frame->function_name);
251 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000252 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800253 EXPECT_EQ(0U, frame->map_elf_start_offset);
254 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800255 EXPECT_EQ(0x1000U, frame->map_start);
256 EXPECT_EQ(0x8000U, frame->map_end);
257 EXPECT_EQ(0U, frame->map_load_bias);
258 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
259
260 frame = &unwinder.frames()[2];
261 EXPECT_EQ(2U, frame->num);
262 EXPECT_EQ(0x200U, frame->rel_pc);
263 EXPECT_EQ(0x1200U, frame->pc);
264 EXPECT_EQ(0x10020U, frame->sp);
265 EXPECT_EQ("", frame->function_name);
266 EXPECT_EQ(0U, frame->function_offset);
David Srbeckye62f4c42018-03-16 18:44:04 +0000267 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800268 EXPECT_EQ(0U, frame->map_elf_start_offset);
269 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4b3a6a2018-02-20 13:58:40 -0800270 EXPECT_EQ(0x1000U, frame->map_start);
271 EXPECT_EQ(0x8000U, frame->map_end);
272 EXPECT_EQ(0U, frame->map_load_bias);
273 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
274}
275
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800276TEST_F(UnwinderTest, non_zero_load_bias) {
277 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
278
Yabin Cui11e96fe2018-03-14 18:16:22 -0700279 regs_.set_pc(0xa5500);
280 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800281 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
282
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800283 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800284 unwinder.Unwind();
285 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700286 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800287
288 ASSERT_EQ(1U, unwinder.NumFrames());
289
290 auto* frame = &unwinder.frames()[0];
291 EXPECT_EQ(0U, frame->num);
292 EXPECT_EQ(0x5500U, frame->rel_pc);
293 EXPECT_EQ(0xa5500U, frame->pc);
294 EXPECT_EQ(0x10000U, frame->sp);
295 EXPECT_EQ("Frame0", frame->function_name);
296 EXPECT_EQ(0U, frame->function_offset);
297 EXPECT_EQ("/fake/fake_load_bias.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800298 EXPECT_EQ(0U, frame->map_elf_start_offset);
299 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800300 EXPECT_EQ(0xa5000U, frame->map_start);
301 EXPECT_EQ(0xa6000U, frame->map_end);
302 EXPECT_EQ(0x5000U, frame->map_load_bias);
303 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
304}
305
306TEST_F(UnwinderTest, non_zero_elf_offset) {
307 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
308
Yabin Cui11e96fe2018-03-14 18:16:22 -0700309 regs_.set_pc(0xa7500);
310 regs_.set_sp(0x10000);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800311 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
312
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800313 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800314 unwinder.Unwind();
315 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700316 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800317
318 ASSERT_EQ(1U, unwinder.NumFrames());
319
320 auto* frame = &unwinder.frames()[0];
321 EXPECT_EQ(0U, frame->num);
322 EXPECT_EQ(0x8500U, frame->rel_pc);
323 EXPECT_EQ(0xa7500U, 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_offset.oat", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800328 EXPECT_EQ(0U, frame->map_elf_start_offset);
329 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise4df5f52018-02-12 13:24:18 -0800330 EXPECT_EQ(0xa7000U, frame->map_start);
331 EXPECT_EQ(0xa8000U, frame->map_end);
332 EXPECT_EQ(0U, frame->map_load_bias);
333 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
334}
335
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700336TEST_F(UnwinderTest, non_zero_map_offset) {
337 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
338
Yabin Cui11e96fe2018-03-14 18:16:22 -0700339 regs_.set_pc(0x43000);
340 regs_.set_sp(0x10000);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700341 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
342
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800343 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700344 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800345 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700346 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700347
348 ASSERT_EQ(1U, unwinder.NumFrames());
349
350 auto* frame = &unwinder.frames()[0];
351 EXPECT_EQ(0U, frame->num);
352 EXPECT_EQ(0U, frame->rel_pc);
353 EXPECT_EQ(0x43000U, frame->pc);
354 EXPECT_EQ(0x10000U, frame->sp);
355 EXPECT_EQ("Frame0", frame->function_name);
356 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700357 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
358 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
359 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
360 EXPECT_EQ(0x43000U, frame->map_start);
361 EXPECT_EQ(0x44000U, frame->map_end);
362 EXPECT_EQ(0U, frame->map_load_bias);
363 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
364}
365
366TEST_F(UnwinderTest, disable_embedded_soname) {
367 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
368
369 regs_.set_pc(0x43000);
370 regs_.set_sp(0x10000);
371 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
372
373 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
374 unwinder.SetEmbeddedSoname(false);
375 unwinder.Unwind();
376 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700377 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris02a6c442019-03-11 14:43:33 -0700378
379 ASSERT_EQ(1U, unwinder.NumFrames());
380
381 auto* frame = &unwinder.frames()[0];
382 EXPECT_EQ(0U, frame->num);
383 EXPECT_EQ(0U, frame->rel_pc);
384 EXPECT_EQ(0x43000U, frame->pc);
385 EXPECT_EQ(0x10000U, frame->sp);
386 EXPECT_EQ("Frame0", frame->function_name);
387 EXPECT_EQ(0U, frame->function_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700388 EXPECT_EQ("/fake/fake.apk", frame->map_name);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700389 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800390 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrisc5a3baa2017-10-17 18:42:03 -0700391 EXPECT_EQ(0x43000U, frame->map_start);
392 EXPECT_EQ(0x44000U, frame->map_end);
393 EXPECT_EQ(0U, frame->map_load_bias);
394 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
395}
396
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700397// Verify that no attempt to continue after the step indicates it is done.
398TEST_F(UnwinderTest, no_frames_after_finished) {
399 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
400 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
401 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
402 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
403 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
404
Yabin Cui11e96fe2018-03-14 18:16:22 -0700405 regs_.set_pc(0x1000);
406 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700407 ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
408 ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
409 ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
410
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800411 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700412 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800413 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700414 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700415
416 ASSERT_EQ(1U, unwinder.NumFrames());
417
418 auto* frame = &unwinder.frames()[0];
419 EXPECT_EQ(0U, frame->num);
420 EXPECT_EQ(0U, frame->rel_pc);
421 EXPECT_EQ(0x1000U, frame->pc);
422 EXPECT_EQ(0x10000U, frame->sp);
423 EXPECT_EQ("Frame0", frame->function_name);
424 EXPECT_EQ(0U, frame->function_offset);
425 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800426 EXPECT_EQ(0U, frame->map_elf_start_offset);
427 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700428 EXPECT_EQ(0x1000U, frame->map_start);
429 EXPECT_EQ(0x8000U, frame->map_end);
430 EXPECT_EQ(0U, frame->map_load_bias);
431 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
432}
433
434// Verify the maximum frames to save.
435TEST_F(UnwinderTest, max_frames) {
436 for (size_t i = 0; i < 30; i++) {
437 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
438 ElfInterfaceFake::FakePushStepData(StepData(0x1102 + i * 0x100, 0x10010 + i * 0x10, false));
439 }
440
Yabin Cui11e96fe2018-03-14 18:16:22 -0700441 regs_.set_pc(0x1000);
442 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700443
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800444 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700445 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800446 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700447 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700448
449 ASSERT_EQ(20U, unwinder.NumFrames());
450
451 for (size_t i = 0; i < 20; i++) {
452 auto* frame = &unwinder.frames()[i];
453 EXPECT_EQ(i, frame->num);
454 EXPECT_EQ(i * 0x100, frame->rel_pc) << "Failed at frame " << i;
455 EXPECT_EQ(0x1000 + i * 0x100, frame->pc) << "Failed at frame " << i;
456 EXPECT_EQ(0x10000 + 0x10 * i, frame->sp) << "Failed at frame " << i;
457 EXPECT_EQ("Frame" + std::to_string(i), frame->function_name) << "Failed at frame " << i;
458 EXPECT_EQ(i, frame->function_offset) << "Failed at frame " << i;
459 EXPECT_EQ("/system/fake/libc.so", frame->map_name) << "Failed at frame " << i;
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800460 EXPECT_EQ(0U, frame->map_elf_start_offset) << "Failed at frame " << i;
461 EXPECT_EQ(0U, frame->map_exact_offset) << "Failed at frame " << i;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700462 EXPECT_EQ(0x1000U, frame->map_start) << "Failed at frame " << i;
463 EXPECT_EQ(0x8000U, frame->map_end) << "Failed at frame " << i;
464 EXPECT_EQ(0U, frame->map_load_bias) << "Failed at frame " << i;
465 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags) << "Failed at frame " << i;
466 }
467}
468
469// Verify that initial map names frames are removed.
470TEST_F(UnwinderTest, verify_frames_skipped) {
471 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
472 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
473 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
474
Yabin Cui11e96fe2018-03-14 18:16:22 -0700475 regs_.set_pc(0x20000);
476 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700477 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
478 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
479 ElfInterfaceFake::FakePushStepData(StepData(0x20002, 0x10030, false));
480 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10040, false));
481 ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
482 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x10060, false));
483 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
484 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
485
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800486 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700487 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
488 unwinder.Unwind(&skip_libs);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800489 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700490 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700491
492 ASSERT_EQ(3U, unwinder.NumFrames());
493
494 auto* frame = &unwinder.frames()[0];
495 EXPECT_EQ(0U, frame->num);
496 EXPECT_EQ(0U, frame->rel_pc);
497 EXPECT_EQ(0x1000U, frame->pc);
498 EXPECT_EQ(0x10050U, frame->sp);
499 EXPECT_EQ("Frame0", frame->function_name);
500 EXPECT_EQ(0U, frame->function_offset);
501 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800502 EXPECT_EQ(0U, frame->map_elf_start_offset);
503 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700504 EXPECT_EQ(0x1000U, frame->map_start);
505 EXPECT_EQ(0x8000U, frame->map_end);
506 EXPECT_EQ(0U, frame->map_load_bias);
507 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
508
509 frame = &unwinder.frames()[1];
510 EXPECT_EQ(1U, frame->num);
511 EXPECT_EQ(0x1000U, frame->rel_pc);
512 EXPECT_EQ(0x21000U, frame->pc);
513 EXPECT_EQ(0x10060U, frame->sp);
514 EXPECT_EQ("Frame1", frame->function_name);
515 EXPECT_EQ(1U, frame->function_offset);
516 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800517 EXPECT_EQ(0U, frame->map_elf_start_offset);
518 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700519 EXPECT_EQ(0x20000U, frame->map_start);
520 EXPECT_EQ(0x22000U, frame->map_end);
521 EXPECT_EQ(0U, frame->map_load_bias);
522 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
523
524 frame = &unwinder.frames()[2];
525 EXPECT_EQ(2U, frame->num);
526 EXPECT_EQ(0U, frame->rel_pc);
527 EXPECT_EQ(0x23000U, frame->pc);
528 EXPECT_EQ(0x10070U, frame->sp);
529 EXPECT_EQ("Frame2", frame->function_name);
530 EXPECT_EQ(2U, frame->function_offset);
531 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800532 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700533 EXPECT_EQ(0x23000U, frame->map_start);
534 EXPECT_EQ(0x24000U, frame->map_end);
535 EXPECT_EQ(0U, frame->map_load_bias);
536 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
537}
538
539// Verify SP in a non-existant map is okay.
540TEST_F(UnwinderTest, sp_not_in_map) {
541 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
542 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
543
Yabin Cui11e96fe2018-03-14 18:16:22 -0700544 regs_.set_pc(0x1000);
545 regs_.set_sp(0x63000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700546 ElfInterfaceFake::FakePushStepData(StepData(0x21002, 0x50020, false));
547 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
548
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800549 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700550 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800551 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700552 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700553
554 ASSERT_EQ(2U, unwinder.NumFrames());
555
556 auto* frame = &unwinder.frames()[0];
557 EXPECT_EQ(0U, frame->num);
558 EXPECT_EQ(0U, frame->rel_pc);
559 EXPECT_EQ(0x1000U, frame->pc);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700560 EXPECT_EQ(0x63000U, frame->sp);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700561 EXPECT_EQ("Frame0", frame->function_name);
562 EXPECT_EQ(0U, frame->function_offset);
563 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800564 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700565 EXPECT_EQ(0x1000U, frame->map_start);
566 EXPECT_EQ(0x8000U, frame->map_end);
567 EXPECT_EQ(0U, frame->map_load_bias);
568 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
569
570 frame = &unwinder.frames()[1];
571 EXPECT_EQ(1U, frame->num);
572 EXPECT_EQ(0x1000U, frame->rel_pc);
573 EXPECT_EQ(0x21000U, frame->pc);
574 EXPECT_EQ(0x50020U, frame->sp);
575 EXPECT_EQ("Frame1", frame->function_name);
576 EXPECT_EQ(1U, frame->function_offset);
577 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800578 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700579 EXPECT_EQ(0x20000U, frame->map_start);
580 EXPECT_EQ(0x22000U, frame->map_end);
581 EXPECT_EQ(0U, frame->map_load_bias);
582 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
583}
584
585// Verify PC in a device stops the unwind.
586TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
587 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
588 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
589 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
590
Yabin Cui11e96fe2018-03-14 18:16:22 -0700591 regs_.set_pc(0x13000);
592 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700593 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
594 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
595 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
596
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800597 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700598 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800599 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700600 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700601
602 ASSERT_EQ(1U, unwinder.NumFrames());
603}
604
605// Verify SP in a device stops the unwind.
606TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
607 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
608 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
609 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
610
Yabin Cui11e96fe2018-03-14 18:16:22 -0700611 regs_.set_pc(0x1000);
612 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700613 ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
614 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
615 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
616
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800617 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700618 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800619 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700620 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700621
622 ASSERT_EQ(1U, unwinder.NumFrames());
623}
624
625// Verify a no map info frame gets a frame.
626TEST_F(UnwinderTest, pc_without_map) {
627 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
628
Yabin Cui11e96fe2018-03-14 18:16:22 -0700629 regs_.set_pc(0x41000);
630 regs_.set_sp(0x13000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700631
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800632 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700633 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800634 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700635 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700636
637 ASSERT_EQ(1U, unwinder.NumFrames());
638
639 auto* frame = &unwinder.frames()[0];
640 EXPECT_EQ(0U, frame->num);
641 EXPECT_EQ(0x41000U, frame->rel_pc);
642 EXPECT_EQ(0x41000U, frame->pc);
643 EXPECT_EQ(0x13000U, frame->sp);
644 EXPECT_EQ("", frame->function_name);
645 EXPECT_EQ(0U, frame->function_offset);
646 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800647 EXPECT_EQ(0U, frame->map_elf_start_offset);
648 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700649 EXPECT_EQ(0U, frame->map_start);
650 EXPECT_EQ(0U, frame->map_end);
651 EXPECT_EQ(0U, frame->map_load_bias);
652 EXPECT_EQ(0, frame->map_flags);
653}
654
655// Verify that a speculative frame is added.
656TEST_F(UnwinderTest, speculative_frame) {
657 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
658 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
659
660 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700661 regs_.set_pc(0);
662 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700663 regs_.FakeSetReturnAddress(0x1202);
664 regs_.FakeSetReturnAddressValid(true);
665
666 ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
667 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
668
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800669 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700670 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800671 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700672 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700673
674 ASSERT_EQ(3U, unwinder.NumFrames());
675
676 auto* frame = &unwinder.frames()[0];
677 EXPECT_EQ(0U, frame->num);
678 EXPECT_EQ(0U, frame->rel_pc);
679 EXPECT_EQ(0U, frame->pc);
680 EXPECT_EQ(0x10000U, frame->sp);
681 EXPECT_EQ("", frame->function_name);
682 EXPECT_EQ(0U, frame->function_offset);
683 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800684 EXPECT_EQ(0U, frame->map_elf_start_offset);
685 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700686 EXPECT_EQ(0U, frame->map_start);
687 EXPECT_EQ(0U, frame->map_end);
688 EXPECT_EQ(0U, frame->map_load_bias);
689 EXPECT_EQ(0, frame->map_flags);
690
691 frame = &unwinder.frames()[1];
692 EXPECT_EQ(1U, frame->num);
693 EXPECT_EQ(0x200U, frame->rel_pc);
694 EXPECT_EQ(0x1200U, frame->pc);
695 EXPECT_EQ(0x10000U, frame->sp);
696 EXPECT_EQ("Frame0", frame->function_name);
697 EXPECT_EQ(0U, frame->function_offset);
698 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800699 EXPECT_EQ(0U, frame->map_elf_start_offset);
700 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700701 EXPECT_EQ(0x1000U, frame->map_start);
702 EXPECT_EQ(0x8000U, frame->map_end);
703 EXPECT_EQ(0U, frame->map_load_bias);
704 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
705
706 frame = &unwinder.frames()[2];
707 EXPECT_EQ(2U, frame->num);
708 EXPECT_EQ(0x100U, frame->rel_pc);
709 EXPECT_EQ(0x23100U, frame->pc);
710 EXPECT_EQ(0x10020U, frame->sp);
711 EXPECT_EQ("Frame1", frame->function_name);
712 EXPECT_EQ(1U, frame->function_offset);
713 EXPECT_EQ("/fake/libanother.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800714 EXPECT_EQ(0U, frame->map_elf_start_offset);
715 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700716 EXPECT_EQ(0x23000U, frame->map_start);
717 EXPECT_EQ(0x24000U, frame->map_end);
718 EXPECT_EQ(0U, frame->map_load_bias);
719 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
720}
721
722// Verify that a speculative frame is added then removed because no other
723// frames are added.
724TEST_F(UnwinderTest, speculative_frame_removed) {
725 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
726 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
727
728 // Fake as if code called a nullptr function.
Christopher Ferris065f1562018-12-13 09:33:45 -0800729 regs_.set_pc(0x20000);
730 regs_.set_sp(0x10000);
731 ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
732 regs_.FakeSetReturnAddress(0x12);
733 regs_.FakeSetReturnAddressValid(true);
734
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800735 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris065f1562018-12-13 09:33:45 -0800736 unwinder.Unwind();
737 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700738 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris065f1562018-12-13 09:33:45 -0800739
740 ASSERT_EQ(2U, unwinder.NumFrames());
741
742 auto* frame = &unwinder.frames()[0];
743 EXPECT_EQ(0U, frame->num);
744 EXPECT_EQ(0U, frame->rel_pc);
745 EXPECT_EQ(0x20000U, frame->pc);
746 EXPECT_EQ(0x10000U, frame->sp);
747 EXPECT_EQ("Frame0", frame->function_name);
748 EXPECT_EQ(0U, frame->function_offset);
749 EXPECT_EQ("/system/fake/libunwind.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800750 EXPECT_EQ(0U, frame->map_elf_start_offset);
751 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800752 EXPECT_EQ(0x20000U, frame->map_start);
753 EXPECT_EQ(0x22000U, frame->map_end);
754 EXPECT_EQ(0U, frame->map_load_bias);
755 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
756
757 frame = &unwinder.frames()[1];
758 EXPECT_EQ(1U, frame->num);
759 EXPECT_EQ(0U, frame->rel_pc);
760 EXPECT_EQ(0U, frame->pc);
761 EXPECT_EQ(0x10010U, frame->sp);
762 EXPECT_EQ("", frame->function_name);
763 EXPECT_EQ(0U, frame->function_offset);
764 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800765 EXPECT_EQ(0U, frame->map_elf_start_offset);
766 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800767 EXPECT_EQ(0U, frame->map_start);
768 EXPECT_EQ(0U, frame->map_end);
769 EXPECT_EQ(0U, frame->map_load_bias);
770 EXPECT_EQ(0, frame->map_flags);
771}
772
773// Verify that a speculative frame is added and left if there are only
774// two frames and the pc is in the middle nowhere.
775TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
776 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
777 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
778
779 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700780 regs_.set_pc(0);
781 regs_.set_sp(0x10000);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700782 regs_.FakeSetReturnAddress(0x1202);
783 regs_.FakeSetReturnAddressValid(true);
784
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800785 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700786 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800787 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700788 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700789
Christopher Ferris065f1562018-12-13 09:33:45 -0800790 ASSERT_EQ(2U, unwinder.NumFrames());
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700791
792 auto* frame = &unwinder.frames()[0];
793 EXPECT_EQ(0U, frame->num);
794 EXPECT_EQ(0U, frame->rel_pc);
795 EXPECT_EQ(0U, frame->pc);
796 EXPECT_EQ(0x10000U, frame->sp);
797 EXPECT_EQ("", frame->function_name);
798 EXPECT_EQ(0U, frame->function_offset);
799 EXPECT_EQ("", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800800 EXPECT_EQ(0U, frame->map_elf_start_offset);
801 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700802 EXPECT_EQ(0U, frame->map_start);
803 EXPECT_EQ(0U, frame->map_end);
804 EXPECT_EQ(0U, frame->map_load_bias);
805 EXPECT_EQ(0, frame->map_flags);
Christopher Ferris065f1562018-12-13 09:33:45 -0800806
807 frame = &unwinder.frames()[1];
808 EXPECT_EQ(1U, frame->num);
809 EXPECT_EQ(0x200U, frame->rel_pc);
810 EXPECT_EQ(0x1200U, frame->pc);
811 EXPECT_EQ(0x10000U, frame->sp);
812 EXPECT_EQ("Frame0", frame->function_name);
813 EXPECT_EQ(0U, frame->function_offset);
814 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800815 EXPECT_EQ(0U, frame->map_elf_start_offset);
816 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris065f1562018-12-13 09:33:45 -0800817 EXPECT_EQ(0x1000U, frame->map_start);
818 EXPECT_EQ(0x8000U, frame->map_end);
819 EXPECT_EQ(0U, frame->map_load_bias);
820 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -0700821}
822
Florian Mayerc479e4e2019-01-23 13:35:40 +0000823// Verify that a speculative frame does not cause a crash when it wasn't
824// really added due to a filter.
825TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
826 regs_.set_pc(0x23000);
827 regs_.set_sp(0x10000);
828 regs_.FakeSetReturnAddress(0x23100);
829 regs_.FakeSetReturnAddressValid(true);
830
831 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
832
833 std::vector<std::string> skip_names{"libanother.so"};
834 unwinder.Unwind(&skip_names);
835 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700836 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Florian Mayerc479e4e2019-01-23 13:35:40 +0000837
838 ASSERT_EQ(0U, unwinder.NumFrames());
839}
840
Christopher Ferrise69f4702017-10-19 16:08:58 -0700841// Verify that an unwind stops when a frame is in given suffix.
842TEST_F(UnwinderTest, map_ignore_suffixes) {
843 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
844 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
845 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
846 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
847
848 // Fake as if code called a nullptr function.
Yabin Cui11e96fe2018-03-14 18:16:22 -0700849 regs_.set_pc(0x1000);
850 regs_.set_sp(0x10000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700851 ElfInterfaceFake::FakePushStepData(StepData(0x43402, 0x10010, false));
852 ElfInterfaceFake::FakePushStepData(StepData(0x53502, 0x10020, false));
853 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
854
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800855 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferris1cb84ce2017-10-24 15:36:00 -0700856 std::vector<std::string> suffixes{"oat"};
Christopher Ferrise69f4702017-10-19 16:08:58 -0700857 unwinder.Unwind(nullptr, &suffixes);
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800858 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700859 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise69f4702017-10-19 16:08:58 -0700860
861 ASSERT_EQ(2U, unwinder.NumFrames());
862 // Make sure the elf was not initialized.
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800863 MapInfo* map_info = maps_->Find(0x53000);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700864 ASSERT_TRUE(map_info != nullptr);
865 EXPECT_TRUE(map_info->elf == nullptr);
866
867 auto* frame = &unwinder.frames()[0];
868 EXPECT_EQ(0U, frame->num);
869 EXPECT_EQ(0U, frame->rel_pc);
870 EXPECT_EQ(0x1000U, frame->pc);
871 EXPECT_EQ(0x10000U, frame->sp);
872 EXPECT_EQ("Frame0", frame->function_name);
873 EXPECT_EQ(0U, frame->function_offset);
874 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800875 EXPECT_EQ(0U, frame->map_elf_start_offset);
876 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700877 EXPECT_EQ(0x1000U, frame->map_start);
878 EXPECT_EQ(0x8000U, frame->map_end);
879 EXPECT_EQ(0U, frame->map_load_bias);
880 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
881
882 frame = &unwinder.frames()[1];
883 EXPECT_EQ(1U, frame->num);
884 EXPECT_EQ(0x400U, frame->rel_pc);
885 EXPECT_EQ(0x43400U, frame->pc);
886 EXPECT_EQ(0x10010U, frame->sp);
887 EXPECT_EQ("Frame1", frame->function_name);
888 EXPECT_EQ(1U, frame->function_offset);
Christopher Ferris02a6c442019-03-11 14:43:33 -0700889 EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_name);
890 EXPECT_EQ(0x1d000U, frame->map_elf_start_offset);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800891 EXPECT_EQ(0x1d000U, frame->map_exact_offset);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700892 EXPECT_EQ(0x43000U, frame->map_start);
893 EXPECT_EQ(0x44000U, frame->map_end);
894 EXPECT_EQ(0U, frame->map_load_bias);
895 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
896}
897
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700898// Verify that an unwind stops when the sp and pc don't change.
899TEST_F(UnwinderTest, sp_pc_do_not_change) {
900 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
901 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
902 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
903 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
904 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
905
Yabin Cui11e96fe2018-03-14 18:16:22 -0700906 regs_.set_pc(0x1000);
907 regs_.set_sp(0x10000);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700908 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
909 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
910 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
911 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
912 ElfInterfaceFake::FakePushStepData(StepData(0x33502, 0x10020, false));
913 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
914
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800915 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700916 unwinder.Unwind();
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800917 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700918 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700919
920 ASSERT_EQ(3U, unwinder.NumFrames());
921
922 auto* frame = &unwinder.frames()[0];
923 EXPECT_EQ(0U, frame->num);
924 EXPECT_EQ(0U, frame->rel_pc);
925 EXPECT_EQ(0x1000U, frame->pc);
926 EXPECT_EQ(0x10000U, frame->sp);
927 EXPECT_EQ("Frame0", frame->function_name);
928 EXPECT_EQ(0U, frame->function_offset);
929 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800930 EXPECT_EQ(0U, frame->map_elf_start_offset);
931 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700932 EXPECT_EQ(0x1000U, frame->map_start);
933 EXPECT_EQ(0x8000U, frame->map_end);
934 EXPECT_EQ(0U, frame->map_load_bias);
935 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
936
937 frame = &unwinder.frames()[1];
938 EXPECT_EQ(1U, frame->num);
939 EXPECT_EQ(0x400U, frame->rel_pc);
940 EXPECT_EQ(0x33400U, frame->pc);
941 EXPECT_EQ(0x10010U, frame->sp);
942 EXPECT_EQ("Frame1", frame->function_name);
943 EXPECT_EQ(1U, frame->function_offset);
944 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800945 EXPECT_EQ(0U, frame->map_elf_start_offset);
946 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700947 EXPECT_EQ(0x33000U, frame->map_start);
948 EXPECT_EQ(0x34000U, frame->map_end);
949 EXPECT_EQ(0U, frame->map_load_bias);
950 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
951
952 frame = &unwinder.frames()[2];
953 EXPECT_EQ(2U, frame->num);
954 EXPECT_EQ(0x500U, frame->rel_pc);
955 EXPECT_EQ(0x33500U, frame->pc);
956 EXPECT_EQ(0x10020U, frame->sp);
957 EXPECT_EQ("Frame2", frame->function_name);
958 EXPECT_EQ(2U, frame->function_offset);
959 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800960 EXPECT_EQ(0U, frame->map_elf_start_offset);
961 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisfda7edd2017-10-31 16:10:42 -0700962 EXPECT_EQ(0x33000U, frame->map_start);
963 EXPECT_EQ(0x34000U, frame->map_end);
964 EXPECT_EQ(0U, frame->map_load_bias);
965 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
966}
967
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800968TEST_F(UnwinderTest, dex_pc_in_map) {
969 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -0700970 regs_.set_pc(0x1000);
971 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800972 regs_.FakeSetDexPc(0xa3400);
973
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800974 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800975 unwinder.Unwind();
976 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -0700977 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800978
979 ASSERT_EQ(2U, unwinder.NumFrames());
980
981 auto* frame = &unwinder.frames()[0];
982 EXPECT_EQ(0U, frame->num);
983 EXPECT_EQ(0x400U, frame->rel_pc);
984 EXPECT_EQ(0xa3400U, frame->pc);
985 EXPECT_EQ(0x10000U, frame->sp);
986 EXPECT_EQ("", frame->function_name);
987 EXPECT_EQ(0U, frame->function_offset);
988 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -0800989 EXPECT_EQ(0U, frame->map_elf_start_offset);
990 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -0800991 EXPECT_EQ(0xa3000U, frame->map_start);
992 EXPECT_EQ(0xa4000U, frame->map_end);
993 EXPECT_EQ(0U, frame->map_load_bias);
994 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
995
996 frame = &unwinder.frames()[1];
997 EXPECT_EQ(1U, frame->num);
998 EXPECT_EQ(0U, frame->rel_pc);
999 EXPECT_EQ(0x1000U, frame->pc);
1000 EXPECT_EQ(0x10000U, frame->sp);
1001 EXPECT_EQ("Frame0", frame->function_name);
1002 EXPECT_EQ(0U, frame->function_offset);
1003 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001004 EXPECT_EQ(0U, frame->map_elf_start_offset);
1005 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001006 EXPECT_EQ(0x1000U, frame->map_start);
1007 EXPECT_EQ(0x8000U, frame->map_end);
1008 EXPECT_EQ(0U, frame->map_load_bias);
1009 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1010}
1011
1012TEST_F(UnwinderTest, dex_pc_not_in_map) {
1013 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001014 regs_.set_pc(0x1000);
1015 regs_.set_sp(0x10000);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001016 regs_.FakeSetDexPc(0x50000);
1017
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001018 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001019 unwinder.Unwind();
1020 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001021 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001022
1023 ASSERT_EQ(2U, unwinder.NumFrames());
1024
1025 auto* frame = &unwinder.frames()[0];
1026 EXPECT_EQ(0U, frame->num);
1027 EXPECT_EQ(0x50000U, frame->rel_pc);
1028 EXPECT_EQ(0x50000U, frame->pc);
1029 EXPECT_EQ(0x10000U, frame->sp);
1030 EXPECT_EQ("", frame->function_name);
1031 EXPECT_EQ(0U, frame->function_offset);
1032 EXPECT_EQ("", 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 Ferrise762f1f2018-02-06 14:51:48 -08001035 EXPECT_EQ(0U, frame->map_start);
1036 EXPECT_EQ(0U, frame->map_end);
1037 EXPECT_EQ(0U, frame->map_load_bias);
1038 EXPECT_EQ(0, frame->map_flags);
1039
1040 frame = &unwinder.frames()[1];
1041 EXPECT_EQ(1U, frame->num);
1042 EXPECT_EQ(0U, frame->rel_pc);
1043 EXPECT_EQ(0x1000U, frame->pc);
1044 EXPECT_EQ(0x10000U, frame->sp);
1045 EXPECT_EQ("Frame0", frame->function_name);
1046 EXPECT_EQ(0U, frame->function_offset);
1047 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001048 EXPECT_EQ(0U, frame->map_elf_start_offset);
1049 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrise762f1f2018-02-06 14:51:48 -08001050 EXPECT_EQ(0x1000U, frame->map_start);
1051 EXPECT_EQ(0x8000U, frame->map_end);
1052 EXPECT_EQ(0U, frame->map_load_bias);
1053 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1054}
1055
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001056TEST_F(UnwinderTest, dex_pc_multiple_frames) {
1057 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1058 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
Yabin Cui11e96fe2018-03-14 18:16:22 -07001059 regs_.set_pc(0x1000);
1060 regs_.set_sp(0x10000);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001061 regs_.FakeSetDexPc(0xa3400);
1062 ElfInterfaceFake::FakePushStepData(StepData(0x33402, 0x10010, false));
1063 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1064
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001065 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001066 unwinder.Unwind();
1067 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001068 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001069
1070 ASSERT_EQ(3U, unwinder.NumFrames());
1071
1072 auto* frame = &unwinder.frames()[0];
1073 EXPECT_EQ(0U, frame->num);
1074 EXPECT_EQ(0x400U, frame->rel_pc);
1075 EXPECT_EQ(0xa3400U, frame->pc);
1076 EXPECT_EQ(0x10000U, frame->sp);
1077 EXPECT_EQ("", frame->function_name);
1078 EXPECT_EQ(0U, frame->function_offset);
1079 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001080 EXPECT_EQ(0U, frame->map_elf_start_offset);
1081 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001082 EXPECT_EQ(0xa3000U, frame->map_start);
1083 EXPECT_EQ(0xa4000U, frame->map_end);
1084 EXPECT_EQ(0U, frame->map_load_bias);
1085 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1086
1087 frame = &unwinder.frames()[1];
1088 EXPECT_EQ(1U, frame->num);
1089 EXPECT_EQ(0U, frame->rel_pc);
1090 EXPECT_EQ(0x1000U, frame->pc);
1091 EXPECT_EQ(0x10000U, frame->sp);
1092 EXPECT_EQ("Frame0", frame->function_name);
1093 EXPECT_EQ(0U, frame->function_offset);
1094 EXPECT_EQ("/system/fake/libc.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001095 EXPECT_EQ(0U, frame->map_elf_start_offset);
1096 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001097 EXPECT_EQ(0x1000U, frame->map_start);
1098 EXPECT_EQ(0x8000U, frame->map_end);
1099 EXPECT_EQ(0U, frame->map_load_bias);
1100 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1101
1102 frame = &unwinder.frames()[2];
1103 EXPECT_EQ(2U, frame->num);
1104 EXPECT_EQ(0x400U, frame->rel_pc);
1105 EXPECT_EQ(0x33400U, frame->pc);
1106 EXPECT_EQ(0x10010U, frame->sp);
1107 EXPECT_EQ("Frame1", frame->function_name);
1108 EXPECT_EQ(1U, frame->function_offset);
1109 EXPECT_EQ("/fake/compressed.so", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001110 EXPECT_EQ(0U, frame->map_elf_start_offset);
1111 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferrisa8c39732018-02-12 08:46:19 -08001112 EXPECT_EQ(0x33000U, frame->map_start);
1113 EXPECT_EQ(0x34000U, frame->map_end);
1114 EXPECT_EQ(0U, frame->map_load_bias);
1115 EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags);
1116}
1117
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001118TEST_F(UnwinderTest, dex_pc_max_frames) {
1119 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1120 regs_.set_pc(0x1000);
1121 regs_.set_sp(0x10000);
1122 regs_.FakeSetDexPc(0xa3400);
1123
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001124 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001125 unwinder.Unwind();
1126 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001127 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001128
1129 ASSERT_EQ(1U, unwinder.NumFrames());
1130
1131 auto* frame = &unwinder.frames()[0];
1132 EXPECT_EQ(0U, frame->num);
1133 EXPECT_EQ(0x400U, frame->rel_pc);
1134 EXPECT_EQ(0xa3400U, frame->pc);
1135 EXPECT_EQ(0x10000U, frame->sp);
1136 EXPECT_EQ("", frame->function_name);
1137 EXPECT_EQ(0U, frame->function_offset);
1138 EXPECT_EQ("/fake/fake.vdex", frame->map_name);
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001139 EXPECT_EQ(0U, frame->map_elf_start_offset);
1140 EXPECT_EQ(0U, frame->map_exact_offset);
Christopher Ferris9d0ad232018-10-12 16:33:42 -07001141 EXPECT_EQ(0xa3000U, frame->map_start);
1142 EXPECT_EQ(0xa4000U, frame->map_end);
1143 EXPECT_EQ(0U, frame->map_load_bias);
1144 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1145}
1146
Christopher Ferris4ae266c2019-04-03 09:27:12 -07001147TEST_F(UnwinderTest, elf_from_memory_not_file) {
1148 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1149
1150 regs_.set_pc(0xc0050);
1151 regs_.set_sp(0x10000);
1152 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1153
1154 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1155 unwinder.Unwind();
1156 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1157 EXPECT_TRUE(unwinder.elf_from_memory_not_file());
1158
1159 ASSERT_EQ(1U, unwinder.NumFrames());
1160
1161 auto* frame = &unwinder.frames()[0];
1162 EXPECT_EQ(0U, frame->num);
1163 EXPECT_EQ(0x50U, frame->rel_pc);
1164 EXPECT_EQ(0xc0050U, frame->pc);
1165 EXPECT_EQ(0x10000U, frame->sp);
1166 EXPECT_EQ("Frame0", frame->function_name);
1167 EXPECT_EQ(0U, frame->function_offset);
1168 EXPECT_EQ("/fake/unreadable.so", frame->map_name);
1169 EXPECT_EQ(0U, frame->map_elf_start_offset);
1170 EXPECT_EQ(0U, frame->map_exact_offset);
1171 EXPECT_EQ(0xc0000U, frame->map_start);
1172 EXPECT_EQ(0xc1000U, frame->map_end);
1173 EXPECT_EQ(0U, frame->map_load_bias);
1174 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1175}
1176
1177TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
1178 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1179
1180 regs_.set_pc(0xc1050);
1181 regs_.set_sp(0x10000);
1182 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1183
1184 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1185 unwinder.Unwind();
1186 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1187 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1188
1189 ASSERT_EQ(1U, unwinder.NumFrames());
1190
1191 auto* frame = &unwinder.frames()[0];
1192 EXPECT_EQ(0U, frame->num);
1193 EXPECT_EQ(0x50U, frame->rel_pc);
1194 EXPECT_EQ(0xc1050U, frame->pc);
1195 EXPECT_EQ(0x10000U, frame->sp);
1196 EXPECT_EQ("Frame0", frame->function_name);
1197 EXPECT_EQ(0U, frame->function_offset);
1198 EXPECT_EQ("[vdso]", frame->map_name);
1199 EXPECT_EQ(0U, frame->map_elf_start_offset);
1200 EXPECT_EQ(0U, frame->map_exact_offset);
1201 EXPECT_EQ(0xc1000U, frame->map_start);
1202 EXPECT_EQ(0xc2000U, frame->map_end);
1203 EXPECT_EQ(0U, frame->map_load_bias);
1204 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1205}
1206
1207TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
1208 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1209
1210 regs_.set_pc(0xc2050);
1211 regs_.set_sp(0x10000);
1212 ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1213
1214 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1215 unwinder.Unwind();
1216 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1217 EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1218
1219 ASSERT_EQ(1U, unwinder.NumFrames());
1220
1221 auto* frame = &unwinder.frames()[0];
1222 EXPECT_EQ(0U, frame->num);
1223 EXPECT_EQ(0x50U, frame->rel_pc);
1224 EXPECT_EQ(0xc2050U, frame->pc);
1225 EXPECT_EQ(0x10000U, frame->sp);
1226 EXPECT_EQ("Frame0", frame->function_name);
1227 EXPECT_EQ(0U, frame->function_offset);
1228 EXPECT_EQ("", frame->map_name);
1229 EXPECT_EQ(0U, frame->map_elf_start_offset);
1230 EXPECT_EQ(0U, frame->map_exact_offset);
1231 EXPECT_EQ(0xc2000U, frame->map_start);
1232 EXPECT_EQ(0xc3000U, frame->map_end);
1233 EXPECT_EQ(0U, frame->map_load_bias);
1234 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1235}
1236
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001237// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001238TEST_F(UnwinderTest, format_frame) {
1239 RegsFake regs_arm(10);
1240 regs_arm.FakeSetArch(ARCH_ARM);
1241 Unwinder unwinder32(10, maps_.get(), &regs_arm, process_memory_);
1242
1243 RegsFake regs_arm64(10);
1244 regs_arm64.FakeSetArch(ARCH_ARM64);
1245 Unwinder unwinder64(10, maps_.get(), &regs_arm64, process_memory_);
1246
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001247 FrameData frame;
1248 frame.num = 1;
1249 frame.rel_pc = 0x1000;
1250 frame.pc = 0x4000;
1251 frame.sp = 0x1000;
1252 frame.function_name = "function";
1253 frame.function_offset = 100;
1254 frame.map_name = "/fake/libfake.so";
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001255 frame.map_elf_start_offset = 0x2000;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001256 frame.map_start = 0x3000;
1257 frame.map_end = 0x6000;
1258 frame.map_flags = PROT_READ;
1259
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001260 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001261 unwinder64.FormatFrame(frame));
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001262 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (offset 0x2000) (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001263 unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001264
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001265 frame.map_elf_start_offset = 0;
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001266 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function+100)",
Christopher Ferris78133452019-03-14 13:44:38 -07001267 unwinder64.FormatFrame(frame));
1268 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001269
1270 frame.function_offset = 0;
1271 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (function)",
Christopher Ferris78133452019-03-14 13:44:38 -07001272 unwinder64.FormatFrame(frame));
1273 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function)", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001274
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001275 // Verify the function name is demangled.
1276 frame.function_name = "_ZN4funcEv";
Christopher Ferris78133452019-03-14 13:44:38 -07001277 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so (func())", unwinder64.FormatFrame(frame));
1278 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (func())", unwinder32.FormatFrame(frame));
Christopher Ferriseb0772f2018-12-05 15:57:02 -08001279
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001280 frame.function_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001281 EXPECT_EQ(" #01 pc 0000000000001000 /fake/libfake.so", unwinder64.FormatFrame(frame));
1282 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001283
1284 frame.map_name = "";
Christopher Ferris78133452019-03-14 13:44:38 -07001285 EXPECT_EQ(" #01 pc 0000000000001000 <anonymous:3000>", unwinder64.FormatFrame(frame));
1286 EXPECT_EQ(" #01 pc 00001000 <anonymous:3000>", unwinder32.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001287
1288 frame.map_start = 0;
1289 frame.map_end = 0;
Christopher Ferris78133452019-03-14 13:44:38 -07001290 EXPECT_EQ(" #01 pc 0000000000001000 <unknown>", unwinder64.FormatFrame(frame));
1291 EXPECT_EQ(" #01 pc 00001000 <unknown>", unwinder32.FormatFrame(frame));
1292}
1293
1294TEST_F(UnwinderTest, format_frame_build_id) {
1295 RegsFake regs(10);
1296 regs.FakeSetArch(ARCH_ARM);
1297 Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1298
1299 FrameData frame;
1300 frame.num = 1;
1301 frame.rel_pc = 0x1000;
1302 frame.pc = 0x4000;
1303 frame.sp = 0x1000;
1304 frame.function_name = "function";
1305 frame.function_offset = 100;
1306 frame.map_name = "/fake/libfake.so";
1307 frame.map_elf_start_offset = 0;
1308 frame.map_start = 0x3000;
1309 frame.map_end = 0x6000;
1310 frame.map_flags = PROT_READ;
1311
1312 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100)", unwinder.FormatFrame(frame));
1313 unwinder.SetDisplayBuildID(true);
1314 EXPECT_EQ(" #01 pc 00001000 /fake/libfake.so (function+100) (BuildId: 46414b45)",
1315 unwinder.FormatFrame(frame));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001316}
1317
Christopher Ferris02fdb562017-12-08 15:04:49 -08001318static std::string ArchToString(ArchEnum arch) {
1319 if (arch == ARCH_ARM) {
1320 return "Arm";
1321 } else if (arch == ARCH_ARM64) {
1322 return "Arm64";
1323 } else if (arch == ARCH_X86) {
1324 return "X86";
1325 } else if (arch == ARCH_X86_64) {
1326 return "X86_64";
1327 } else {
1328 return "Unknown";
1329 }
1330}
1331
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001332// Verify format frame code.
Christopher Ferris78133452019-03-14 13:44:38 -07001333TEST_F(UnwinderTest, format_frame_by_arch) {
Christopher Ferris02fdb562017-12-08 15:04:49 -08001334 std::vector<Regs*> reg_list;
1335 RegsArm* arm = new RegsArm;
1336 arm->set_pc(0x2300);
1337 arm->set_sp(0x10000);
1338 reg_list.push_back(arm);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001339
Christopher Ferris02fdb562017-12-08 15:04:49 -08001340 RegsArm64* arm64 = new RegsArm64;
1341 arm64->set_pc(0x2300);
1342 arm64->set_sp(0x10000);
1343 reg_list.push_back(arm64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001344
Christopher Ferris02fdb562017-12-08 15:04:49 -08001345 RegsX86* x86 = new RegsX86;
1346 x86->set_pc(0x2300);
1347 x86->set_sp(0x10000);
1348 reg_list.push_back(x86);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001349
Christopher Ferris02fdb562017-12-08 15:04:49 -08001350 RegsX86_64* x86_64 = new RegsX86_64;
1351 x86_64->set_pc(0x2300);
1352 x86_64->set_sp(0x10000);
1353 reg_list.push_back(x86_64);
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001354
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001355 RegsMips* mips = new RegsMips;
1356 mips->set_pc(0x2300);
1357 mips->set_sp(0x10000);
1358 reg_list.push_back(mips);
1359
1360 RegsMips64* mips64 = new RegsMips64;
1361 mips64->set_pc(0x2300);
1362 mips64->set_sp(0x10000);
1363 reg_list.push_back(mips64);
1364
Christopher Ferris02fdb562017-12-08 15:04:49 -08001365 for (auto regs : reg_list) {
1366 ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001367
Christopher Ferrisa09c4a62018-12-13 16:08:50 -08001368 Unwinder unwinder(64, maps_.get(), regs, process_memory_);
Christopher Ferris02fdb562017-12-08 15:04:49 -08001369 unwinder.Unwind();
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001370
Christopher Ferris02fdb562017-12-08 15:04:49 -08001371 ASSERT_EQ(1U, unwinder.NumFrames());
1372 std::string expected;
1373 switch (regs->Arch()) {
1374 case ARCH_ARM:
1375 case ARCH_X86:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001376 case ARCH_MIPS:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001377 expected = " #00 pc 00001300 /system/fake/libc.so (Frame0+10)";
1378 break;
1379 case ARCH_ARM64:
1380 case ARCH_X86_64:
Douglas Leung61b1a1a2017-11-08 10:53:53 +01001381 case ARCH_MIPS64:
Christopher Ferris02fdb562017-12-08 15:04:49 -08001382 expected = " #00 pc 0000000000001300 /system/fake/libc.so (Frame0+10)";
1383 break;
1384 default:
1385 expected = "";
1386 }
1387 EXPECT_EQ(expected, unwinder.FormatFrame(0))
1388 << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1389 delete regs;
1390 }
Christopher Ferrisf6f691b2017-09-25 19:23:07 -07001391}
1392
1393} // namespace unwindstack