xref: /aosp_15_r20/system/unwinding/libunwindstack/tests/UnwinderTest.cpp (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker  *
4*eb293b8fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker  *
8*eb293b8fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker  *
10*eb293b8fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker  * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker  */
16*eb293b8fSAndroid Build Coastguard Worker 
17*eb293b8fSAndroid Build Coastguard Worker #include <elf.h>
18*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h>
19*eb293b8fSAndroid Build Coastguard Worker #include <sys/mman.h>
20*eb293b8fSAndroid Build Coastguard Worker 
21*eb293b8fSAndroid Build Coastguard Worker #include <memory>
22*eb293b8fSAndroid Build Coastguard Worker #include <set>
23*eb293b8fSAndroid Build Coastguard Worker #include <string>
24*eb293b8fSAndroid Build Coastguard Worker 
25*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
26*eb293b8fSAndroid Build Coastguard Worker 
27*eb293b8fSAndroid Build Coastguard Worker #include <android-base/silent_death_test.h>
28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Elf.h>
29*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Maps.h>
30*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h>
31*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Regs.h>
32*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/RegsArm.h>
33*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/RegsArm64.h>
34*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/RegsRiscv64.h>
35*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/RegsX86.h>
36*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/RegsX86_64.h>
37*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Unwinder.h>
38*eb293b8fSAndroid Build Coastguard Worker 
39*eb293b8fSAndroid Build Coastguard Worker #include "ElfFake.h"
40*eb293b8fSAndroid Build Coastguard Worker #include "ElfTestUtils.h"
41*eb293b8fSAndroid Build Coastguard Worker #include "utils/MemoryFake.h"
42*eb293b8fSAndroid Build Coastguard Worker #include "utils/RegsFake.h"
43*eb293b8fSAndroid Build Coastguard Worker 
44*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
45*eb293b8fSAndroid Build Coastguard Worker 
46*eb293b8fSAndroid Build Coastguard Worker class UnwinderTest : public ::testing::Test {
47*eb293b8fSAndroid Build Coastguard Worker  protected:
AddMapInfo(uint64_t start,uint64_t end,uint64_t offset,uint64_t flags,const char * name,Elf * elf=nullptr)48*eb293b8fSAndroid Build Coastguard Worker   static MapInfo* AddMapInfo(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags,
49*eb293b8fSAndroid Build Coastguard Worker                              const char* name, Elf* elf = nullptr) {
50*eb293b8fSAndroid Build Coastguard Worker     std::string str_name(name);
51*eb293b8fSAndroid Build Coastguard Worker     maps_->Add(start, end, offset, flags, name);
52*eb293b8fSAndroid Build Coastguard Worker     MapInfo* map_info = maps_->Find(start).get();
53*eb293b8fSAndroid Build Coastguard Worker     if (elf != nullptr) {
54*eb293b8fSAndroid Build Coastguard Worker       map_info->set_elf(elf);
55*eb293b8fSAndroid Build Coastguard Worker     }
56*eb293b8fSAndroid Build Coastguard Worker     return map_info;
57*eb293b8fSAndroid Build Coastguard Worker   }
58*eb293b8fSAndroid Build Coastguard Worker 
SetUpTestSuite()59*eb293b8fSAndroid Build Coastguard Worker   static void SetUpTestSuite() {
60*eb293b8fSAndroid Build Coastguard Worker     maps_.reset(new Maps);
61*eb293b8fSAndroid Build Coastguard Worker 
62*eb293b8fSAndroid Build Coastguard Worker     memory_ = new MemoryFake;
63*eb293b8fSAndroid Build Coastguard Worker     process_memory_.reset(memory_);
64*eb293b8fSAndroid Build Coastguard Worker 
65*eb293b8fSAndroid Build Coastguard Worker     ElfFake* elf;
66*eb293b8fSAndroid Build Coastguard Worker     ElfInterfaceFake* interface;
67*eb293b8fSAndroid Build Coastguard Worker     MapInfo* map_info;
68*eb293b8fSAndroid Build Coastguard Worker 
69*eb293b8fSAndroid Build Coastguard Worker     std::shared_ptr<Memory> empty;
70*eb293b8fSAndroid Build Coastguard Worker     std::shared_ptr<Memory> elf_memory(new MemoryFake);
71*eb293b8fSAndroid Build Coastguard Worker 
72*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
73*eb293b8fSAndroid Build Coastguard Worker     interface = new ElfInterfaceFake(empty);
74*eb293b8fSAndroid Build Coastguard Worker     interface->FakeSetBuildID("FAKE");
75*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(interface);
76*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so", elf);
77*eb293b8fSAndroid Build Coastguard Worker 
78*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0x10000, 0x12000, 0, PROT_READ | PROT_WRITE, "[stack]");
79*eb293b8fSAndroid Build Coastguard Worker 
80*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0x13000, 0x15000, 0, PROT_READ | PROT_WRITE | MAPS_FLAGS_DEVICE_MAP,
81*eb293b8fSAndroid Build Coastguard Worker                "/dev/fake_device");
82*eb293b8fSAndroid Build Coastguard Worker 
83*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
84*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
85*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so", elf);
86*eb293b8fSAndroid Build Coastguard Worker 
87*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
88*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
89*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so", elf);
90*eb293b8fSAndroid Build Coastguard Worker 
91*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
92*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
93*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so", elf);
94*eb293b8fSAndroid Build Coastguard Worker 
95*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
96*eb293b8fSAndroid Build Coastguard Worker     interface = new ElfInterfaceFake(empty);
97*eb293b8fSAndroid Build Coastguard Worker     interface->FakeSetSoname("lib_fake.so");
98*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(interface);
99*eb293b8fSAndroid Build Coastguard Worker     map_info = AddMapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk", elf);
100*eb293b8fSAndroid Build Coastguard Worker     map_info->set_elf_start_offset(0x1d000);
101*eb293b8fSAndroid Build Coastguard Worker 
102*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
103*eb293b8fSAndroid Build Coastguard Worker 
104*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0xa3000, 0xa4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.vdex");
105*eb293b8fSAndroid Build Coastguard Worker 
106*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
107*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
108*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetLoadBias(0x5000);
109*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0xa5000, 0xa6000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake_load_bias.so",
110*eb293b8fSAndroid Build Coastguard Worker                elf);
111*eb293b8fSAndroid Build Coastguard Worker 
112*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
113*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
114*eb293b8fSAndroid Build Coastguard Worker     map_info = AddMapInfo(0xa7000, 0xa8000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
115*eb293b8fSAndroid Build Coastguard Worker                           "/fake/fake_offset.oat", elf);
116*eb293b8fSAndroid Build Coastguard Worker     map_info->set_elf_offset(0x8000);
117*eb293b8fSAndroid Build Coastguard Worker 
118*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
119*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
120*eb293b8fSAndroid Build Coastguard Worker     map_info = AddMapInfo(0xc0000, 0xc1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
121*eb293b8fSAndroid Build Coastguard Worker                           "/fake/unreadable.so", elf);
122*eb293b8fSAndroid Build Coastguard Worker     map_info->set_memory_backed_elf(true);
123*eb293b8fSAndroid Build Coastguard Worker 
124*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
125*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
126*eb293b8fSAndroid Build Coastguard Worker     map_info = AddMapInfo(0xc1000, 0xc2000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "[vdso]", elf);
127*eb293b8fSAndroid Build Coastguard Worker     map_info->set_memory_backed_elf(true);
128*eb293b8fSAndroid Build Coastguard Worker 
129*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
130*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
131*eb293b8fSAndroid Build Coastguard Worker     map_info = AddMapInfo(0xc2000, 0xc3000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "", elf);
132*eb293b8fSAndroid Build Coastguard Worker     map_info->set_memory_backed_elf(true);
133*eb293b8fSAndroid Build Coastguard Worker 
134*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
135*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(new ElfInterfaceFake(empty));
136*eb293b8fSAndroid Build Coastguard Worker     map_info = AddMapInfo(0xc3000, 0xc4000, 0, PROT_READ | PROT_WRITE | PROT_EXEC,
137*eb293b8fSAndroid Build Coastguard Worker                           "/memfd:/jit-cache", elf);
138*eb293b8fSAndroid Build Coastguard Worker     map_info->set_memory_backed_elf(true);
139*eb293b8fSAndroid Build Coastguard Worker 
140*eb293b8fSAndroid Build Coastguard Worker     map_info =
141*eb293b8fSAndroid Build Coastguard Worker         AddMapInfo(0xd0000, 0xd1000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/fake.apk");
142*eb293b8fSAndroid Build Coastguard Worker     map_info->set_elf_start_offset(0x1000);
143*eb293b8fSAndroid Build Coastguard Worker 
144*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
145*eb293b8fSAndroid Build Coastguard Worker     interface = new ElfInterfaceFake(empty);
146*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetInterface(interface);
147*eb293b8fSAndroid Build Coastguard Worker     interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x1800);
148*eb293b8fSAndroid Build Coastguard Worker     interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x1900);
149*eb293b8fSAndroid Build Coastguard Worker     interface->FakeSetDataOffset(0x1000);
150*eb293b8fSAndroid Build Coastguard Worker     interface->FakeSetDataVaddrStart(0x1000);
151*eb293b8fSAndroid Build Coastguard Worker     interface->FakeSetDataVaddrEnd(0x8000);
152*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0xf0000, 0xf1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/global.so", elf);
153*eb293b8fSAndroid Build Coastguard Worker     AddMapInfo(0xf1000, 0xf9000, 0x1000, PROT_READ | PROT_WRITE, "/fake/global.so");
154*eb293b8fSAndroid Build Coastguard Worker     // dex debug data
155*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf180c, 0xf3000);
156*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf3000, 0xf4000);
157*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf3004, 0xf4000);
158*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf3008, 0xf5000);
159*eb293b8fSAndroid Build Coastguard Worker     // jit debug data
160*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf1900, 1);
161*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf1904, 0);
162*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf1908, 0xf6000);
163*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf190c, 0xf6000);
164*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf6000, 0);
165*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf6004, 0);
166*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf6008, 0xf7000);
167*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData32(0xf600c, 0);
168*eb293b8fSAndroid Build Coastguard Worker     memory_->SetData64(0xf6010, 0x1000);
169*eb293b8fSAndroid Build Coastguard Worker 
170*eb293b8fSAndroid Build Coastguard Worker     elf = new ElfFake(elf_memory);
171*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetValid(false);
172*eb293b8fSAndroid Build Coastguard Worker     elf->FakeSetLoadBias(0x300);
173*eb293b8fSAndroid Build Coastguard Worker     map_info = AddMapInfo(0x100000, 0x101000, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC,
174*eb293b8fSAndroid Build Coastguard Worker                           "/fake/jit.so", elf);
175*eb293b8fSAndroid Build Coastguard Worker     map_info->set_elf_start_offset(0x100);
176*eb293b8fSAndroid Build Coastguard Worker     map_info->set_offset(0x200);
177*eb293b8fSAndroid Build Coastguard Worker   }
178*eb293b8fSAndroid Build Coastguard Worker 
SetUp()179*eb293b8fSAndroid Build Coastguard Worker   void SetUp() override {
180*eb293b8fSAndroid Build Coastguard Worker     ElfInterfaceFake::FakeClear();
181*eb293b8fSAndroid Build Coastguard Worker     regs_.FakeSetArch(ARCH_ARM);
182*eb293b8fSAndroid Build Coastguard Worker     regs_.FakeSetReturnAddressValid(false);
183*eb293b8fSAndroid Build Coastguard Worker   }
184*eb293b8fSAndroid Build Coastguard Worker 
185*eb293b8fSAndroid Build Coastguard Worker   static std::unique_ptr<Maps> maps_;
186*eb293b8fSAndroid Build Coastguard Worker   static RegsFake regs_;
187*eb293b8fSAndroid Build Coastguard Worker   static MemoryFake* memory_;
188*eb293b8fSAndroid Build Coastguard Worker   static std::shared_ptr<Memory> process_memory_;
189*eb293b8fSAndroid Build Coastguard Worker };
190*eb293b8fSAndroid Build Coastguard Worker 
191*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<Maps> UnwinderTest::maps_;
192*eb293b8fSAndroid Build Coastguard Worker RegsFake UnwinderTest::regs_(5);
193*eb293b8fSAndroid Build Coastguard Worker MemoryFake* UnwinderTest::memory_;
194*eb293b8fSAndroid Build Coastguard Worker std::shared_ptr<Memory> UnwinderTest::process_memory_(nullptr);
195*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,multiple_frames)196*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, multiple_frames) {
197*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
198*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
199*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
200*eb293b8fSAndroid Build Coastguard Worker 
201*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
202*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
203*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
204*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
205*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
206*eb293b8fSAndroid Build Coastguard Worker 
207*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
208*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
209*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
210*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
211*eb293b8fSAndroid Build Coastguard Worker 
212*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, unwinder.NumFrames());
213*eb293b8fSAndroid Build Coastguard Worker 
214*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
215*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
216*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
217*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
218*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
219*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
220*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
221*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
222*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
223*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
224*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
225*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
226*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
227*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
228*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
229*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
230*eb293b8fSAndroid Build Coastguard Worker 
231*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
232*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
233*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100U, frame->rel_pc);
234*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1100U, frame->pc);
235*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10010U, frame->sp);
236*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame1", frame->function_name);
237*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->function_offset);
238*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
239*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
240*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
241*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
242*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
243*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
244*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
245*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
246*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
247*eb293b8fSAndroid Build Coastguard Worker 
248*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[2];
249*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->num);
250*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x200U, frame->rel_pc);
251*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1200U, frame->pc);
252*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10020U, frame->sp);
253*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame2", frame->function_name);
254*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->function_offset);
255*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
256*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
257*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
258*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
259*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
260*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
261*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
262*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
263*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
264*eb293b8fSAndroid Build Coastguard Worker }
265*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,multiple_frames_dont_resolve_names)266*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
267*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
268*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
269*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
270*eb293b8fSAndroid Build Coastguard Worker 
271*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
272*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
273*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x1104, 0x10010, false));
274*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x1204, 0x10020, false));
275*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
276*eb293b8fSAndroid Build Coastguard Worker 
277*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
278*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetResolveNames(false);
279*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
280*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
281*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
282*eb293b8fSAndroid Build Coastguard Worker 
283*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, unwinder.NumFrames());
284*eb293b8fSAndroid Build Coastguard Worker 
285*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
286*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
287*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
288*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
289*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
290*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
291*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
292*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
293*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
294*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
295*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
296*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
297*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
298*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
299*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
300*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
301*eb293b8fSAndroid Build Coastguard Worker 
302*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
303*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
304*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100U, frame->rel_pc);
305*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1100U, frame->pc);
306*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10010U, frame->sp);
307*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
308*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
309*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
310*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
311*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
312*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
313*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
314*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
315*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
316*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
317*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
318*eb293b8fSAndroid Build Coastguard Worker 
319*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[2];
320*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->num);
321*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x200U, frame->rel_pc);
322*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1200U, frame->pc);
323*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10020U, frame->sp);
324*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
325*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
326*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
327*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
328*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
329*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
330*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
331*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
332*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
333*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
334*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
335*eb293b8fSAndroid Build Coastguard Worker }
336*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,non_zero_load_bias)337*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, non_zero_load_bias) {
338*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
339*eb293b8fSAndroid Build Coastguard Worker 
340*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0xa5500);
341*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
342*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
343*eb293b8fSAndroid Build Coastguard Worker 
344*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
345*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
346*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
347*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
348*eb293b8fSAndroid Build Coastguard Worker 
349*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
350*eb293b8fSAndroid Build Coastguard Worker 
351*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
352*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
353*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x5500U, frame->rel_pc);
354*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa5500U, frame->pc);
355*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
356*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
357*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
358*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
359*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake_load_bias.so", frame->map_info->name());
360*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake_load_bias.so", frame->map_info->GetFullName());
361*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
362*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
363*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa5000U, frame->map_info->start());
364*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa6000U, frame->map_info->end());
365*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x5000U, frame->map_info->GetLoadBias());
366*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
367*eb293b8fSAndroid Build Coastguard Worker }
368*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,non_zero_elf_offset)369*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, non_zero_elf_offset) {
370*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
371*eb293b8fSAndroid Build Coastguard Worker 
372*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0xa7500);
373*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
374*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
375*eb293b8fSAndroid Build Coastguard Worker 
376*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
377*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
378*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
379*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
380*eb293b8fSAndroid Build Coastguard Worker 
381*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
382*eb293b8fSAndroid Build Coastguard Worker 
383*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
384*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
385*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8500U, frame->rel_pc);
386*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa7500U, frame->pc);
387*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
388*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
389*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
390*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
391*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake_offset.oat", frame->map_info->name());
392*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake_offset.oat", frame->map_info->GetFullName());
393*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
394*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
395*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa7000U, frame->map_info->start());
396*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa8000U, frame->map_info->end());
397*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
398*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
399*eb293b8fSAndroid Build Coastguard Worker }
400*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,non_zero_map_offset)401*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, non_zero_map_offset) {
402*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
403*eb293b8fSAndroid Build Coastguard Worker 
404*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x43000);
405*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
406*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
407*eb293b8fSAndroid Build Coastguard Worker 
408*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
409*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
410*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
411*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
412*eb293b8fSAndroid Build Coastguard Worker 
413*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
414*eb293b8fSAndroid Build Coastguard Worker 
415*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
416*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
417*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
418*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x43000U, frame->pc);
419*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
420*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
421*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
422*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
423*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.apk", frame->map_info->name());
424*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_info->GetFullName());
425*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1d000U, frame->map_info->elf_start_offset());
426*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1d000U, frame->map_info->offset());
427*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x43000U, frame->map_info->start());
428*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x44000U, frame->map_info->end());
429*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
430*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
431*eb293b8fSAndroid Build Coastguard Worker }
432*eb293b8fSAndroid Build Coastguard Worker 
433*eb293b8fSAndroid Build Coastguard Worker // Verify that no attempt to continue after the step indicates it is done.
TEST_F(UnwinderTest,no_frames_after_finished)434*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, no_frames_after_finished) {
435*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
436*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
437*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
438*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
439*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
440*eb293b8fSAndroid Build Coastguard Worker 
441*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
442*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
443*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x1000, 0x10000, true));
444*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x1102, 0x10010, false));
445*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x1202, 0x10020, false));
446*eb293b8fSAndroid Build Coastguard Worker 
447*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
448*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
449*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
450*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
451*eb293b8fSAndroid Build Coastguard Worker 
452*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
453*eb293b8fSAndroid Build Coastguard Worker 
454*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
455*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
456*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
457*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
458*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
459*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
460*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
461*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
462*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
463*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
464*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
465*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
466*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
467*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
468*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
469*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
470*eb293b8fSAndroid Build Coastguard Worker }
471*eb293b8fSAndroid Build Coastguard Worker 
472*eb293b8fSAndroid Build Coastguard Worker // Verify the maximum frames to save.
TEST_F(UnwinderTest,max_frames)473*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, max_frames) {
474*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 30; i++) {
475*eb293b8fSAndroid Build Coastguard Worker     ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame" + std::to_string(i), i));
476*eb293b8fSAndroid Build Coastguard Worker     ElfInterfaceFake::FakePushStepData(StepData(0x1104 + i * 0x100, 0x10010 + i * 0x10, false));
477*eb293b8fSAndroid Build Coastguard Worker   }
478*eb293b8fSAndroid Build Coastguard Worker 
479*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
480*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
481*eb293b8fSAndroid Build Coastguard Worker 
482*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
483*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
484*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
485*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
486*eb293b8fSAndroid Build Coastguard Worker 
487*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(20U, unwinder.NumFrames());
488*eb293b8fSAndroid Build Coastguard Worker 
489*eb293b8fSAndroid Build Coastguard Worker   for (size_t i = 0; i < 20; i++) {
490*eb293b8fSAndroid Build Coastguard Worker     auto* frame = &unwinder.frames()[i];
491*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(i, frame->num);
492*eb293b8fSAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message() << "Failed at frame " << i);
493*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(i * 0x100, frame->rel_pc);
494*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(0x1000 + i * 0x100, frame->pc);
495*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(0x10000 + 0x10 * i, frame->sp);
496*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ("Frame" + std::to_string(i), frame->function_name);
497*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(i, frame->function_offset);
498*eb293b8fSAndroid Build Coastguard Worker     ASSERT_TRUE(frame->map_info != nullptr);
499*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
500*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
501*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(0U, frame->map_info->elf_start_offset());
502*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(0U, frame->map_info->offset());
503*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(0x1000U, frame->map_info->start());
504*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(0x8000U, frame->map_info->end());
505*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(0U, frame->map_info->GetLoadBias());
506*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
507*eb293b8fSAndroid Build Coastguard Worker   }
508*eb293b8fSAndroid Build Coastguard Worker }
509*eb293b8fSAndroid Build Coastguard Worker 
510*eb293b8fSAndroid Build Coastguard Worker // Verify that initial map names frames are removed.
TEST_F(UnwinderTest,verify_frames_skipped)511*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, verify_frames_skipped) {
512*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
513*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
514*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
515*eb293b8fSAndroid Build Coastguard Worker 
516*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x20000);
517*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
518*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x23004, 0x10010, false));
519*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
520*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x20004, 0x10030, false));
521*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10040, false));
522*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x1002, 0x10050, false));
523*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x10060, false));
524*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10070, false));
525*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
526*eb293b8fSAndroid Build Coastguard Worker 
527*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
528*eb293b8fSAndroid Build Coastguard Worker   std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
529*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind(&skip_libs);
530*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
531*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
532*eb293b8fSAndroid Build Coastguard Worker 
533*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, unwinder.NumFrames());
534*eb293b8fSAndroid Build Coastguard Worker 
535*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
536*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
537*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
538*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
539*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10050U, frame->sp);
540*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
541*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
542*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
543*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
544*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
545*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
546*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
547*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
548*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
549*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
550*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
551*eb293b8fSAndroid Build Coastguard Worker 
552*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
553*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
554*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->rel_pc);
555*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x21000U, frame->pc);
556*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10060U, frame->sp);
557*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame1", frame->function_name);
558*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->function_offset);
559*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
560*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libunwind.so", frame->map_info->name());
561*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libunwind.so", frame->map_info->GetFullName());
562*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
563*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
564*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x20000U, frame->map_info->start());
565*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x22000U, frame->map_info->end());
566*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
567*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
568*eb293b8fSAndroid Build Coastguard Worker 
569*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[2];
570*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->num);
571*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
572*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x23000U, frame->pc);
573*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10070U, frame->sp);
574*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame2", frame->function_name);
575*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->function_offset);
576*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
577*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/libanother.so", frame->map_info->name());
578*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/libanother.so", frame->map_info->GetFullName());
579*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
580*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x23000U, frame->map_info->start());
581*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x24000U, frame->map_info->end());
582*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
583*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
584*eb293b8fSAndroid Build Coastguard Worker }
585*eb293b8fSAndroid Build Coastguard Worker 
586*eb293b8fSAndroid Build Coastguard Worker // Verify SP in a non-existant map is okay.
TEST_F(UnwinderTest,sp_not_in_map)587*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, sp_not_in_map) {
588*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
589*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
590*eb293b8fSAndroid Build Coastguard Worker 
591*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
592*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x63000);
593*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x21004, 0x50020, false));
594*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
595*eb293b8fSAndroid Build Coastguard Worker 
596*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
597*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
598*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
599*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
600*eb293b8fSAndroid Build Coastguard Worker 
601*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, unwinder.NumFrames());
602*eb293b8fSAndroid Build Coastguard Worker 
603*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
604*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
605*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
606*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
607*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x63000U, frame->sp);
608*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
609*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
610*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
611*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
612*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
613*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
614*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
615*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
616*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
617*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
618*eb293b8fSAndroid Build Coastguard Worker 
619*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
620*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
621*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->rel_pc);
622*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x21000U, frame->pc);
623*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50020U, frame->sp);
624*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame1", frame->function_name);
625*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->function_offset);
626*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
627*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libunwind.so", frame->map_info->name());
628*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libunwind.so", frame->map_info->GetFullName());
629*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
630*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x20000U, frame->map_info->start());
631*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x22000U, frame->map_info->end());
632*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
633*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
634*eb293b8fSAndroid Build Coastguard Worker }
635*eb293b8fSAndroid Build Coastguard Worker 
636*eb293b8fSAndroid Build Coastguard Worker // Verify PC in a device stops the unwind.
TEST_F(UnwinderTest,pc_in_device_stops_unwind)637*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
638*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
639*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
640*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
641*eb293b8fSAndroid Build Coastguard Worker 
642*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x13000);
643*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
644*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
645*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
646*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
647*eb293b8fSAndroid Build Coastguard Worker 
648*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
649*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
650*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
651*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
652*eb293b8fSAndroid Build Coastguard Worker 
653*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
654*eb293b8fSAndroid Build Coastguard Worker }
655*eb293b8fSAndroid Build Coastguard Worker 
656*eb293b8fSAndroid Build Coastguard Worker // Verify SP in a device stops the unwind.
TEST_F(UnwinderTest,sp_in_device_stops_unwind)657*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
658*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
659*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
660*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
661*eb293b8fSAndroid Build Coastguard Worker 
662*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
663*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x13000);
664*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x23002, 0x10010, false));
665*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x23102, 0x10020, false));
666*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
667*eb293b8fSAndroid Build Coastguard Worker 
668*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
669*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
670*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
671*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
672*eb293b8fSAndroid Build Coastguard Worker 
673*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
674*eb293b8fSAndroid Build Coastguard Worker }
675*eb293b8fSAndroid Build Coastguard Worker 
676*eb293b8fSAndroid Build Coastguard Worker // Verify a no map info frame gets a frame.
TEST_F(UnwinderTest,pc_without_map)677*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, pc_without_map) {
678*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
679*eb293b8fSAndroid Build Coastguard Worker 
680*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x41000);
681*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x13000);
682*eb293b8fSAndroid Build Coastguard Worker 
683*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
684*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
685*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
686*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
687*eb293b8fSAndroid Build Coastguard Worker 
688*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
689*eb293b8fSAndroid Build Coastguard Worker 
690*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
691*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
692*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x41000U, frame->rel_pc);
693*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x41000U, frame->pc);
694*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x13000U, frame->sp);
695*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
696*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
697*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info == nullptr);
698*eb293b8fSAndroid Build Coastguard Worker }
699*eb293b8fSAndroid Build Coastguard Worker 
700*eb293b8fSAndroid Build Coastguard Worker // Verify that a speculative frame is added.
TEST_F(UnwinderTest,speculative_frame)701*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, speculative_frame) {
702*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
703*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
704*eb293b8fSAndroid Build Coastguard Worker 
705*eb293b8fSAndroid Build Coastguard Worker   // Fake as if code called a nullptr function.
706*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0);
707*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
708*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddress(0x1204);
709*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddressValid(true);
710*eb293b8fSAndroid Build Coastguard Worker 
711*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x23104, 0x10020, false));
712*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
713*eb293b8fSAndroid Build Coastguard Worker 
714*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
715*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
716*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
717*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
718*eb293b8fSAndroid Build Coastguard Worker 
719*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, unwinder.NumFrames());
720*eb293b8fSAndroid Build Coastguard Worker 
721*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
722*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
723*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
724*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->pc);
725*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
726*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
727*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
728*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info == nullptr);
729*eb293b8fSAndroid Build Coastguard Worker 
730*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
731*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
732*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x200U, frame->rel_pc);
733*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1200U, frame->pc);
734*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
735*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
736*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
737*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
738*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
739*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
740*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
741*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
742*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
743*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
744*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
745*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
746*eb293b8fSAndroid Build Coastguard Worker 
747*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[2];
748*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->num);
749*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100U, frame->rel_pc);
750*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x23100U, frame->pc);
751*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10020U, frame->sp);
752*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame1", frame->function_name);
753*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->function_offset);
754*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
755*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/libanother.so", frame->map_info->name());
756*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/libanother.so", frame->map_info->GetFullName());
757*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
758*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
759*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x23000U, frame->map_info->start());
760*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x24000U, frame->map_info->end());
761*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
762*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
763*eb293b8fSAndroid Build Coastguard Worker }
764*eb293b8fSAndroid Build Coastguard Worker 
765*eb293b8fSAndroid Build Coastguard Worker // Verify that a speculative frame is added then removed because no other
766*eb293b8fSAndroid Build Coastguard Worker // frames are added.
TEST_F(UnwinderTest,speculative_frame_removed)767*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, speculative_frame_removed) {
768*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
769*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
770*eb293b8fSAndroid Build Coastguard Worker 
771*eb293b8fSAndroid Build Coastguard Worker   // Fake as if code called a nullptr function.
772*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x20000);
773*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
774*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0x10010, false));
775*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddress(0x12);
776*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddressValid(true);
777*eb293b8fSAndroid Build Coastguard Worker 
778*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
779*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
780*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
781*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
782*eb293b8fSAndroid Build Coastguard Worker 
783*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, unwinder.NumFrames());
784*eb293b8fSAndroid Build Coastguard Worker 
785*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
786*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
787*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
788*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x20000U, frame->pc);
789*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
790*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
791*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
792*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
793*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libunwind.so", frame->map_info->name());
794*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libunwind.so", frame->map_info->GetFullName());
795*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
796*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
797*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x20000U, frame->map_info->start());
798*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x22000U, frame->map_info->end());
799*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
800*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
801*eb293b8fSAndroid Build Coastguard Worker 
802*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
803*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
804*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
805*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->pc);
806*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10010U, frame->sp);
807*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
808*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
809*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info == nullptr);
810*eb293b8fSAndroid Build Coastguard Worker }
811*eb293b8fSAndroid Build Coastguard Worker 
812*eb293b8fSAndroid Build Coastguard Worker // Verify that a speculative frame is added and left if there are only
813*eb293b8fSAndroid Build Coastguard Worker // two frames and the pc is in the middle nowhere.
TEST_F(UnwinderTest,speculative_frame_not_removed_pc_bad)814*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
815*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
816*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
817*eb293b8fSAndroid Build Coastguard Worker 
818*eb293b8fSAndroid Build Coastguard Worker   // Fake as if code called a nullptr function.
819*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0);
820*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
821*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddress(0x1204);
822*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddressValid(true);
823*eb293b8fSAndroid Build Coastguard Worker 
824*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
825*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
826*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
827*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
828*eb293b8fSAndroid Build Coastguard Worker 
829*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, unwinder.NumFrames());
830*eb293b8fSAndroid Build Coastguard Worker 
831*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
832*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
833*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
834*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->pc);
835*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
836*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
837*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
838*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info == nullptr);
839*eb293b8fSAndroid Build Coastguard Worker 
840*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
841*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
842*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x200U, frame->rel_pc);
843*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1200U, frame->pc);
844*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
845*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
846*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
847*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
848*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
849*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
850*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
851*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
852*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
853*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
854*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
855*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
856*eb293b8fSAndroid Build Coastguard Worker }
857*eb293b8fSAndroid Build Coastguard Worker 
858*eb293b8fSAndroid Build Coastguard Worker // Verify that a speculative frame does not cause a crash when it wasn't
859*eb293b8fSAndroid Build Coastguard Worker // really added due to a filter.
TEST_F(UnwinderTest,speculative_frame_check_with_no_frames)860*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
861*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x23000);
862*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
863*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddress(0x23100);
864*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddressValid(true);
865*eb293b8fSAndroid Build Coastguard Worker 
866*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
867*eb293b8fSAndroid Build Coastguard Worker 
868*eb293b8fSAndroid Build Coastguard Worker   std::vector<std::string> skip_names{"libanother.so"};
869*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind(&skip_names);
870*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
871*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
872*eb293b8fSAndroid Build Coastguard Worker 
873*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(0U, unwinder.NumFrames());
874*eb293b8fSAndroid Build Coastguard Worker }
875*eb293b8fSAndroid Build Coastguard Worker 
876*eb293b8fSAndroid Build Coastguard Worker // Verify that a speculative frame mapping to invalid map doesn't hide error
877*eb293b8fSAndroid Build Coastguard Worker // for the previous frame.
TEST_F(UnwinderTest,speculative_frame_to_invalid_map_not_hide_prev_error)878*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, speculative_frame_to_invalid_map_not_hide_prev_error) {
879*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x100000);
880*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
881*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddress(0x4);
882*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetReturnAddressValid(true);
883*eb293b8fSAndroid Build Coastguard Worker 
884*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
885*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
886*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_INVALID_ELF, unwinder.LastErrorCode());
887*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
888*eb293b8fSAndroid Build Coastguard Worker 
889*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
890*eb293b8fSAndroid Build Coastguard Worker 
891*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
892*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
893*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x300U, frame->rel_pc);
894*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100000U, frame->pc);
895*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
896*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
897*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
898*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
899*eb293b8fSAndroid Build Coastguard Worker }
900*eb293b8fSAndroid Build Coastguard Worker 
901*eb293b8fSAndroid Build Coastguard Worker // Verify that an unwind stops when a frame is in given suffix.
TEST_F(UnwinderTest,map_ignore_suffixes)902*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, map_ignore_suffixes) {
903*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
904*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
905*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
906*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
907*eb293b8fSAndroid Build Coastguard Worker 
908*eb293b8fSAndroid Build Coastguard Worker   // Fake as if code called a nullptr function.
909*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
910*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
911*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x43404, 0x10010, false));
912*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x53504, 0x10020, false));
913*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
914*eb293b8fSAndroid Build Coastguard Worker 
915*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
916*eb293b8fSAndroid Build Coastguard Worker   std::vector<std::string> suffixes{"oat"};
917*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind(nullptr, &suffixes);
918*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
919*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
920*eb293b8fSAndroid Build Coastguard Worker 
921*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, unwinder.NumFrames());
922*eb293b8fSAndroid Build Coastguard Worker   // Make sure the elf was not initialized.
923*eb293b8fSAndroid Build Coastguard Worker   MapInfo* map_info = maps_->Find(0x53000).get();
924*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(map_info != nullptr);
925*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(map_info->elf() == nullptr);
926*eb293b8fSAndroid Build Coastguard Worker 
927*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
928*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
929*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
930*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
931*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
932*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
933*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
934*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
935*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
936*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
937*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
938*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
939*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
940*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
941*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
942*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
943*eb293b8fSAndroid Build Coastguard Worker 
944*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
945*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
946*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x400U, frame->rel_pc);
947*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x43400U, frame->pc);
948*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10010U, frame->sp);
949*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame1", frame->function_name);
950*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->function_offset);
951*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
952*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.apk", frame->map_info->name());
953*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.apk!lib_fake.so", frame->map_info->GetFullName());
954*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1d000U, frame->map_info->elf_start_offset());
955*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1d000U, frame->map_info->offset());
956*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x43000U, frame->map_info->start());
957*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x44000U, frame->map_info->end());
958*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
959*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
960*eb293b8fSAndroid Build Coastguard Worker }
961*eb293b8fSAndroid Build Coastguard Worker 
962*eb293b8fSAndroid Build Coastguard Worker // Verify that an unwind stops when the sp and pc don't change.
TEST_F(UnwinderTest,sp_pc_do_not_change)963*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, sp_pc_do_not_change) {
964*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
965*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
966*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame2", 2));
967*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame3", 3));
968*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame4", 4));
969*eb293b8fSAndroid Build Coastguard Worker 
970*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
971*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
972*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
973*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
974*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
975*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
976*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x33504, 0x10020, false));
977*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
978*eb293b8fSAndroid Build Coastguard Worker 
979*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
980*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
981*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
982*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
983*eb293b8fSAndroid Build Coastguard Worker 
984*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, unwinder.NumFrames());
985*eb293b8fSAndroid Build Coastguard Worker 
986*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
987*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
988*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
989*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
990*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
991*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
992*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
993*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
994*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
995*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
996*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
997*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
998*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
999*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
1000*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1001*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1002*eb293b8fSAndroid Build Coastguard Worker 
1003*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
1004*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
1005*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x400U, frame->rel_pc);
1006*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x33400U, frame->pc);
1007*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10010U, frame->sp);
1008*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame1", frame->function_name);
1009*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->function_offset);
1010*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1011*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/compressed.so", frame->map_info->name());
1012*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/compressed.so", frame->map_info->GetFullName());
1013*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1014*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1015*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x33000U, frame->map_info->start());
1016*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x34000U, frame->map_info->end());
1017*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1018*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1019*eb293b8fSAndroid Build Coastguard Worker 
1020*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[2];
1021*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->num);
1022*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x500U, frame->rel_pc);
1023*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x33500U, frame->pc);
1024*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10020U, frame->sp);
1025*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame2", frame->function_name);
1026*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->function_offset);
1027*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1028*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/compressed.so", frame->map_info->name());
1029*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/compressed.so", frame->map_info->GetFullName());
1030*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1031*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1032*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x33000U, frame->map_info->start());
1033*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x34000U, frame->map_info->end());
1034*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1035*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1036*eb293b8fSAndroid Build Coastguard Worker }
1037*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,dex_pc_in_map)1038*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, dex_pc_in_map) {
1039*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1040*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
1041*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1042*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetDexPc(0xa3400);
1043*eb293b8fSAndroid Build Coastguard Worker 
1044*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1045*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1046*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1047*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
1048*eb293b8fSAndroid Build Coastguard Worker 
1049*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, unwinder.NumFrames());
1050*eb293b8fSAndroid Build Coastguard Worker 
1051*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1052*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1053*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x400U, frame->rel_pc);
1054*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa3400U, frame->pc);
1055*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1056*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
1057*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1058*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1059*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.vdex", frame->map_info->name());
1060*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.vdex", frame->map_info->GetFullName());
1061*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1062*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1063*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa3000U, frame->map_info->start());
1064*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa4000U, frame->map_info->end());
1065*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1066*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
1067*eb293b8fSAndroid Build Coastguard Worker 
1068*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
1069*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
1070*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
1071*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
1072*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1073*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1074*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1075*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1076*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
1077*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
1078*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1079*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1080*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
1081*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
1082*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1083*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1084*eb293b8fSAndroid Build Coastguard Worker }
1085*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,dex_pc_in_map_non_zero_offset)1086*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, dex_pc_in_map_non_zero_offset) {
1087*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1088*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
1089*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1090*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetDexPc(0xd0400);
1091*eb293b8fSAndroid Build Coastguard Worker 
1092*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1093*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1094*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1095*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
1096*eb293b8fSAndroid Build Coastguard Worker 
1097*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, unwinder.NumFrames());
1098*eb293b8fSAndroid Build Coastguard Worker 
1099*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1100*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1101*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x400U, frame->rel_pc);
1102*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xd0400U, frame->pc);
1103*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1104*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
1105*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1106*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1107*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.apk", frame->map_info->name());
1108*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.apk", frame->map_info->GetFullName());
1109*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->elf_start_offset());
1110*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->offset());
1111*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xd0000U, frame->map_info->start());
1112*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xd1000U, frame->map_info->end());
1113*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1114*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
1115*eb293b8fSAndroid Build Coastguard Worker 
1116*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
1117*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
1118*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
1119*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
1120*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1121*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1122*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1123*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1124*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
1125*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
1126*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1127*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1128*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
1129*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
1130*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1131*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1132*eb293b8fSAndroid Build Coastguard Worker }
1133*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,dex_pc_not_in_map)1134*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, dex_pc_not_in_map) {
1135*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1136*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
1137*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1138*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetDexPc(0x50000);
1139*eb293b8fSAndroid Build Coastguard Worker 
1140*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1141*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1142*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1143*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
1144*eb293b8fSAndroid Build Coastguard Worker 
1145*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, unwinder.NumFrames());
1146*eb293b8fSAndroid Build Coastguard Worker 
1147*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1148*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1149*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50000U, frame->rel_pc);
1150*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50000U, frame->pc);
1151*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1152*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
1153*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1154*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info == nullptr);
1155*eb293b8fSAndroid Build Coastguard Worker 
1156*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
1157*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
1158*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
1159*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
1160*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1161*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1162*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1163*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1164*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
1165*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
1166*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1167*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1168*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
1169*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
1170*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1171*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1172*eb293b8fSAndroid Build Coastguard Worker }
1173*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,dex_pc_not_in_map_valid_dex_files)1174*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, dex_pc_not_in_map_valid_dex_files) {
1175*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1176*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
1177*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1178*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetDexPc(0x50000);
1179*eb293b8fSAndroid Build Coastguard Worker 
1180*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<DexFiles> dex_files = CreateDexFiles(regs_.Arch(), process_memory_);
1181*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1182*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetDexFiles(dex_files.get());
1183*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1184*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1185*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
1186*eb293b8fSAndroid Build Coastguard Worker 
1187*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(2U, unwinder.NumFrames());
1188*eb293b8fSAndroid Build Coastguard Worker 
1189*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1190*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1191*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50000U, frame->rel_pc);
1192*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50000U, frame->pc);
1193*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1194*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
1195*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1196*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info == nullptr);
1197*eb293b8fSAndroid Build Coastguard Worker 
1198*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
1199*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
1200*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
1201*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
1202*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1203*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1204*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1205*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1206*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
1207*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
1208*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1209*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1210*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
1211*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
1212*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1213*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1214*eb293b8fSAndroid Build Coastguard Worker }
1215*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,dex_pc_multiple_frames)1216*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, dex_pc_multiple_frames) {
1217*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1218*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame1", 1));
1219*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
1220*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1221*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetDexPc(0xa3400);
1222*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0x33404, 0x10010, false));
1223*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1224*eb293b8fSAndroid Build Coastguard Worker 
1225*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1226*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1227*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1228*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
1229*eb293b8fSAndroid Build Coastguard Worker 
1230*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, unwinder.NumFrames());
1231*eb293b8fSAndroid Build Coastguard Worker 
1232*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1233*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1234*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x400U, frame->rel_pc);
1235*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa3400U, frame->pc);
1236*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1237*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
1238*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1239*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1240*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.vdex", frame->map_info->GetFullName());
1241*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1242*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1243*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa3000U, frame->map_info->start());
1244*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa4000U, frame->map_info->end());
1245*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1246*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
1247*eb293b8fSAndroid Build Coastguard Worker 
1248*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[1];
1249*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->num);
1250*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->rel_pc);
1251*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->pc);
1252*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1253*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1254*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1255*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1256*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->name());
1257*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame->map_info->GetFullName());
1258*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1259*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1260*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame->map_info->start());
1261*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame->map_info->end());
1262*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1263*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1264*eb293b8fSAndroid Build Coastguard Worker 
1265*eb293b8fSAndroid Build Coastguard Worker   frame = &unwinder.frames()[2];
1266*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, frame->num);
1267*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x400U, frame->rel_pc);
1268*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x33400U, frame->pc);
1269*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10010U, frame->sp);
1270*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame1", frame->function_name);
1271*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, frame->function_offset);
1272*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1273*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/compressed.so", frame->map_info->name());
1274*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/compressed.so", frame->map_info->GetFullName());
1275*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1276*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1277*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x33000U, frame->map_info->start());
1278*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x34000U, frame->map_info->end());
1279*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1280*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_info->flags());
1281*eb293b8fSAndroid Build Coastguard Worker }
1282*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,dex_pc_max_frames)1283*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, dex_pc_max_frames) {
1284*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1285*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0x1000);
1286*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1287*eb293b8fSAndroid Build Coastguard Worker   regs_.FakeSetDexPc(0xa3400);
1288*eb293b8fSAndroid Build Coastguard Worker 
1289*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
1290*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1291*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
1292*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
1293*eb293b8fSAndroid Build Coastguard Worker 
1294*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
1295*eb293b8fSAndroid Build Coastguard Worker 
1296*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1297*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1298*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x400U, frame->rel_pc);
1299*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa3400U, frame->pc);
1300*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1301*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->function_name);
1302*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1303*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1304*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.vdex", frame->map_info->name());
1305*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/fake.vdex", frame->map_info->GetFullName());
1306*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1307*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1308*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa3000U, frame->map_info->start());
1309*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xa4000U, frame->map_info->end());
1310*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1311*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
1312*eb293b8fSAndroid Build Coastguard Worker }
1313*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,elf_file_not_readable)1314*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, elf_file_not_readable) {
1315*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1316*eb293b8fSAndroid Build Coastguard Worker 
1317*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0xc0050);
1318*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1319*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1320*eb293b8fSAndroid Build Coastguard Worker 
1321*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1322*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1323*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1324*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
1325*eb293b8fSAndroid Build Coastguard Worker 
1326*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
1327*eb293b8fSAndroid Build Coastguard Worker 
1328*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1329*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1330*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50U, frame->rel_pc);
1331*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc0050U, frame->pc);
1332*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1333*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1334*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1335*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1336*eb293b8fSAndroid Build Coastguard Worker   EXPECT_TRUE(frame->map_info->ElfFileNotReadable());
1337*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/unreadable.so", frame->map_info->name());
1338*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/unreadable.so", frame->map_info->GetFullName());
1339*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1340*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1341*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc0000U, frame->map_info->start());
1342*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc1000U, frame->map_info->end());
1343*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1344*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
1345*eb293b8fSAndroid Build Coastguard Worker }
1346*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,elf_from_memory_but_no_valid_file_with_bracket)1347*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
1348*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1349*eb293b8fSAndroid Build Coastguard Worker 
1350*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0xc1050);
1351*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1352*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1353*eb293b8fSAndroid Build Coastguard Worker 
1354*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1355*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1356*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1357*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
1358*eb293b8fSAndroid Build Coastguard Worker 
1359*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
1360*eb293b8fSAndroid Build Coastguard Worker 
1361*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1362*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1363*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50U, frame->rel_pc);
1364*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc1050U, frame->pc);
1365*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1366*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1367*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1368*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1369*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("[vdso]", frame->map_info->name());
1370*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("[vdso]", frame->map_info->GetFullName());
1371*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1372*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1373*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc1000U, frame->map_info->start());
1374*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc2000U, frame->map_info->end());
1375*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1376*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
1377*eb293b8fSAndroid Build Coastguard Worker }
1378*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,elf_from_memory_but_empty_filename)1379*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
1380*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1381*eb293b8fSAndroid Build Coastguard Worker 
1382*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0xc2050);
1383*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1384*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1385*eb293b8fSAndroid Build Coastguard Worker 
1386*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1387*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1388*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1389*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
1390*eb293b8fSAndroid Build Coastguard Worker 
1391*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
1392*eb293b8fSAndroid Build Coastguard Worker 
1393*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1394*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1395*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50U, frame->rel_pc);
1396*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc2050U, frame->pc);
1397*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1398*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1399*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1400*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1401*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->map_info->name());
1402*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame->map_info->GetFullName());
1403*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1404*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1405*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc2000U, frame->map_info->start());
1406*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc3000U, frame->map_info->end());
1407*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1408*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
1409*eb293b8fSAndroid Build Coastguard Worker }
1410*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,elf_from_memory_but_from_memfd)1411*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, elf_from_memory_but_from_memfd) {
1412*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1413*eb293b8fSAndroid Build Coastguard Worker 
1414*eb293b8fSAndroid Build Coastguard Worker   regs_.set_pc(0xc3050);
1415*eb293b8fSAndroid Build Coastguard Worker   regs_.set_sp(0x10000);
1416*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1417*eb293b8fSAndroid Build Coastguard Worker 
1418*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1419*eb293b8fSAndroid Build Coastguard Worker   unwinder.Unwind();
1420*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1421*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(WARNING_NONE, unwinder.warnings());
1422*eb293b8fSAndroid Build Coastguard Worker 
1423*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(1U, unwinder.NumFrames());
1424*eb293b8fSAndroid Build Coastguard Worker 
1425*eb293b8fSAndroid Build Coastguard Worker   auto* frame = &unwinder.frames()[0];
1426*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->num);
1427*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x50U, frame->rel_pc);
1428*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc3050U, frame->pc);
1429*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10000U, frame->sp);
1430*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame->function_name);
1431*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->function_offset);
1432*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame->map_info != nullptr);
1433*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/memfd:/jit-cache", frame->map_info->name());
1434*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/memfd:/jit-cache", frame->map_info->GetFullName());
1435*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->elf_start_offset());
1436*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->offset());
1437*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc3000U, frame->map_info->start());
1438*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xc4000U, frame->map_info->end());
1439*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame->map_info->GetLoadBias());
1440*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_info->flags());
1441*eb293b8fSAndroid Build Coastguard Worker }
1442*eb293b8fSAndroid Build Coastguard Worker 
1443*eb293b8fSAndroid Build Coastguard Worker // Verify format frame code.
TEST_F(UnwinderTest,format_frame)1444*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, format_frame) {
1445*eb293b8fSAndroid Build Coastguard Worker   RegsFake regs_arm(10);
1446*eb293b8fSAndroid Build Coastguard Worker   regs_arm.FakeSetArch(ARCH_ARM);
1447*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder32(10, maps_.get(), &regs_arm, process_memory_);
1448*eb293b8fSAndroid Build Coastguard Worker 
1449*eb293b8fSAndroid Build Coastguard Worker   RegsFake regs_arm64(10);
1450*eb293b8fSAndroid Build Coastguard Worker   regs_arm64.FakeSetArch(ARCH_ARM64);
1451*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder64(10, maps_.get(), &regs_arm64, process_memory_);
1452*eb293b8fSAndroid Build Coastguard Worker 
1453*eb293b8fSAndroid Build Coastguard Worker   FrameData frame;
1454*eb293b8fSAndroid Build Coastguard Worker   frame.num = 1;
1455*eb293b8fSAndroid Build Coastguard Worker   frame.rel_pc = 0x1000;
1456*eb293b8fSAndroid Build Coastguard Worker   frame.pc = 0x4000;
1457*eb293b8fSAndroid Build Coastguard Worker   frame.sp = 0x1000;
1458*eb293b8fSAndroid Build Coastguard Worker   frame.function_name = "function";
1459*eb293b8fSAndroid Build Coastguard Worker   frame.function_offset = 100;
1460*eb293b8fSAndroid Build Coastguard Worker   auto map_info = MapInfo::Create(0x3000, 0x6000, 0, PROT_READ, "/fake/libfake.so");
1461*eb293b8fSAndroid Build Coastguard Worker   map_info->set_elf_start_offset(0x2000);
1462*eb293b8fSAndroid Build Coastguard Worker   frame.map_info = map_info;
1463*eb293b8fSAndroid Build Coastguard Worker 
1464*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so (offset 0x2000) (function+100)",
1465*eb293b8fSAndroid Build Coastguard Worker             unwinder64.FormatFrame(frame));
1466*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (offset 0x2000) (function+100)",
1467*eb293b8fSAndroid Build Coastguard Worker             unwinder32.FormatFrame(frame));
1468*eb293b8fSAndroid Build Coastguard Worker 
1469*eb293b8fSAndroid Build Coastguard Worker   map_info->set_elf_start_offset(0);
1470*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so (function+100)",
1471*eb293b8fSAndroid Build Coastguard Worker             unwinder64.FormatFrame(frame));
1472*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (function+100)", unwinder32.FormatFrame(frame));
1473*eb293b8fSAndroid Build Coastguard Worker 
1474*eb293b8fSAndroid Build Coastguard Worker   frame.function_offset = 0;
1475*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so (function)",
1476*eb293b8fSAndroid Build Coastguard Worker             unwinder64.FormatFrame(frame));
1477*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (function)", unwinder32.FormatFrame(frame));
1478*eb293b8fSAndroid Build Coastguard Worker 
1479*eb293b8fSAndroid Build Coastguard Worker   // Verify the function name is demangled.
1480*eb293b8fSAndroid Build Coastguard Worker   frame.function_name = "_ZN4funcEv";
1481*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so (func())", unwinder64.FormatFrame(frame));
1482*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (func())", unwinder32.FormatFrame(frame));
1483*eb293b8fSAndroid Build Coastguard Worker 
1484*eb293b8fSAndroid Build Coastguard Worker   frame.function_name = "";
1485*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so", unwinder64.FormatFrame(frame));
1486*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so", unwinder32.FormatFrame(frame));
1487*eb293b8fSAndroid Build Coastguard Worker 
1488*eb293b8fSAndroid Build Coastguard Worker   map_info->name() = "";
1489*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 0000000000001000  <anonymous:3000>", unwinder64.FormatFrame(frame));
1490*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  <anonymous:3000>", unwinder32.FormatFrame(frame));
1491*eb293b8fSAndroid Build Coastguard Worker 
1492*eb293b8fSAndroid Build Coastguard Worker   frame.map_info = nullptr;
1493*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 0000000000001000  <unknown>", unwinder64.FormatFrame(frame));
1494*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  <unknown>", unwinder32.FormatFrame(frame));
1495*eb293b8fSAndroid Build Coastguard Worker }
1496*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,format_frame_build_id)1497*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, format_frame_build_id) {
1498*eb293b8fSAndroid Build Coastguard Worker   RegsFake regs(10);
1499*eb293b8fSAndroid Build Coastguard Worker   regs.FakeSetArch(ARCH_ARM);
1500*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1501*eb293b8fSAndroid Build Coastguard Worker 
1502*eb293b8fSAndroid Build Coastguard Worker   FrameData frame;
1503*eb293b8fSAndroid Build Coastguard Worker   frame.num = 1;
1504*eb293b8fSAndroid Build Coastguard Worker   frame.rel_pc = 0x1000;
1505*eb293b8fSAndroid Build Coastguard Worker   frame.pc = 0x4000;
1506*eb293b8fSAndroid Build Coastguard Worker   frame.sp = 0x1000;
1507*eb293b8fSAndroid Build Coastguard Worker   frame.function_name = "function";
1508*eb293b8fSAndroid Build Coastguard Worker   frame.function_offset = 100;
1509*eb293b8fSAndroid Build Coastguard Worker   frame.map_info = MapInfo::Create(0x3000, 0x6000, 0, PROT_READ, "/fake/libfake.so");
1510*eb293b8fSAndroid Build Coastguard Worker   SharedString* build_id = new SharedString(std::string{0x46, 0x41, 0x4b, 0x45});
1511*eb293b8fSAndroid Build Coastguard Worker   frame.map_info->set_build_id(build_id);
1512*eb293b8fSAndroid Build Coastguard Worker 
1513*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (function+100)", unwinder.FormatFrame(frame));
1514*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetDisplayBuildID(true);
1515*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (function+100) (BuildId: 46414b45)",
1516*eb293b8fSAndroid Build Coastguard Worker             unwinder.FormatFrame(frame));
1517*eb293b8fSAndroid Build Coastguard Worker }
1518*eb293b8fSAndroid Build Coastguard Worker 
ArchToString(ArchEnum arch)1519*eb293b8fSAndroid Build Coastguard Worker static std::string ArchToString(ArchEnum arch) {
1520*eb293b8fSAndroid Build Coastguard Worker   if (arch == ARCH_ARM) {
1521*eb293b8fSAndroid Build Coastguard Worker     return "Arm";
1522*eb293b8fSAndroid Build Coastguard Worker   } else if (arch == ARCH_ARM64) {
1523*eb293b8fSAndroid Build Coastguard Worker     return "Arm64";
1524*eb293b8fSAndroid Build Coastguard Worker   } else if (arch == ARCH_RISCV64) {
1525*eb293b8fSAndroid Build Coastguard Worker     return "Riscv64";
1526*eb293b8fSAndroid Build Coastguard Worker   } else if (arch == ARCH_X86) {
1527*eb293b8fSAndroid Build Coastguard Worker     return "X86";
1528*eb293b8fSAndroid Build Coastguard Worker   } else if (arch == ARCH_X86_64) {
1529*eb293b8fSAndroid Build Coastguard Worker     return "X86_64";
1530*eb293b8fSAndroid Build Coastguard Worker   } else {
1531*eb293b8fSAndroid Build Coastguard Worker     return "Unknown";
1532*eb293b8fSAndroid Build Coastguard Worker   }
1533*eb293b8fSAndroid Build Coastguard Worker }
1534*eb293b8fSAndroid Build Coastguard Worker 
1535*eb293b8fSAndroid Build Coastguard Worker // Verify format frame code.
TEST_F(UnwinderTest,format_frame_by_arch)1536*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, format_frame_by_arch) {
1537*eb293b8fSAndroid Build Coastguard Worker   std::vector<Regs*> reg_list;
1538*eb293b8fSAndroid Build Coastguard Worker   RegsArm* arm = new RegsArm;
1539*eb293b8fSAndroid Build Coastguard Worker   arm->set_pc(0x2300);
1540*eb293b8fSAndroid Build Coastguard Worker   arm->set_sp(0x10000);
1541*eb293b8fSAndroid Build Coastguard Worker   reg_list.push_back(arm);
1542*eb293b8fSAndroid Build Coastguard Worker 
1543*eb293b8fSAndroid Build Coastguard Worker   RegsArm64* arm64 = new RegsArm64;
1544*eb293b8fSAndroid Build Coastguard Worker   arm64->set_pc(0x2300);
1545*eb293b8fSAndroid Build Coastguard Worker   arm64->set_sp(0x10000);
1546*eb293b8fSAndroid Build Coastguard Worker   reg_list.push_back(arm64);
1547*eb293b8fSAndroid Build Coastguard Worker 
1548*eb293b8fSAndroid Build Coastguard Worker   RegsRiscv64* riscv64 = new RegsRiscv64;
1549*eb293b8fSAndroid Build Coastguard Worker   riscv64->set_pc(0x2300);
1550*eb293b8fSAndroid Build Coastguard Worker   riscv64->set_sp(0x10000);
1551*eb293b8fSAndroid Build Coastguard Worker   reg_list.push_back(riscv64);
1552*eb293b8fSAndroid Build Coastguard Worker 
1553*eb293b8fSAndroid Build Coastguard Worker   RegsX86* x86 = new RegsX86;
1554*eb293b8fSAndroid Build Coastguard Worker   x86->set_pc(0x2300);
1555*eb293b8fSAndroid Build Coastguard Worker   x86->set_sp(0x10000);
1556*eb293b8fSAndroid Build Coastguard Worker   reg_list.push_back(x86);
1557*eb293b8fSAndroid Build Coastguard Worker 
1558*eb293b8fSAndroid Build Coastguard Worker   RegsX86_64* x86_64 = new RegsX86_64;
1559*eb293b8fSAndroid Build Coastguard Worker   x86_64->set_pc(0x2300);
1560*eb293b8fSAndroid Build Coastguard Worker   x86_64->set_sp(0x10000);
1561*eb293b8fSAndroid Build Coastguard Worker   reg_list.push_back(x86_64);
1562*eb293b8fSAndroid Build Coastguard Worker 
1563*eb293b8fSAndroid Build Coastguard Worker   for (auto regs : reg_list) {
1564*eb293b8fSAndroid Build Coastguard Worker     ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
1565*eb293b8fSAndroid Build Coastguard Worker 
1566*eb293b8fSAndroid Build Coastguard Worker     Unwinder unwinder(64, maps_.get(), regs, process_memory_);
1567*eb293b8fSAndroid Build Coastguard Worker     unwinder.Unwind();
1568*eb293b8fSAndroid Build Coastguard Worker 
1569*eb293b8fSAndroid Build Coastguard Worker     ASSERT_EQ(1U, unwinder.NumFrames());
1570*eb293b8fSAndroid Build Coastguard Worker     std::string expected;
1571*eb293b8fSAndroid Build Coastguard Worker     switch (regs->Arch()) {
1572*eb293b8fSAndroid Build Coastguard Worker       case ARCH_ARM:
1573*eb293b8fSAndroid Build Coastguard Worker       case ARCH_X86:
1574*eb293b8fSAndroid Build Coastguard Worker         expected = "  #00 pc 00001300  /system/fake/libc.so (Frame0+10)";
1575*eb293b8fSAndroid Build Coastguard Worker         break;
1576*eb293b8fSAndroid Build Coastguard Worker       case ARCH_ARM64:
1577*eb293b8fSAndroid Build Coastguard Worker       case ARCH_X86_64:
1578*eb293b8fSAndroid Build Coastguard Worker       case ARCH_RISCV64:
1579*eb293b8fSAndroid Build Coastguard Worker         expected = "  #00 pc 0000000000001300  /system/fake/libc.so (Frame0+10)";
1580*eb293b8fSAndroid Build Coastguard Worker         break;
1581*eb293b8fSAndroid Build Coastguard Worker       default:
1582*eb293b8fSAndroid Build Coastguard Worker         expected = "";
1583*eb293b8fSAndroid Build Coastguard Worker     }
1584*eb293b8fSAndroid Build Coastguard Worker     EXPECT_EQ(expected, unwinder.FormatFrame(0))
1585*eb293b8fSAndroid Build Coastguard Worker         << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
1586*eb293b8fSAndroid Build Coastguard Worker     delete regs;
1587*eb293b8fSAndroid Build Coastguard Worker   }
1588*eb293b8fSAndroid Build Coastguard Worker }
1589*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,build_frame_pc_only_errors)1590*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, build_frame_pc_only_errors) {
1591*eb293b8fSAndroid Build Coastguard Worker   RegsFake regs(10);
1592*eb293b8fSAndroid Build Coastguard Worker   regs.FakeSetArch(ARCH_ARM);
1593*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1594*eb293b8fSAndroid Build Coastguard Worker 
1595*eb293b8fSAndroid Build Coastguard Worker   FrameData frame;
1596*eb293b8fSAndroid Build Coastguard Worker 
1597*eb293b8fSAndroid Build Coastguard Worker   // Pc not in map
1598*eb293b8fSAndroid Build Coastguard Worker   frame = unwinder.BuildFrameFromPcOnly(0x10);
1599*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10U, frame.pc);
1600*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10U, frame.rel_pc);
1601*eb293b8fSAndroid Build Coastguard Worker 
1602*eb293b8fSAndroid Build Coastguard Worker   // No regs set
1603*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetRegs(nullptr);
1604*eb293b8fSAndroid Build Coastguard Worker   frame = unwinder.BuildFrameFromPcOnly(0x100310);
1605*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100310U, frame.pc);
1606*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100310U, frame.rel_pc);
1607*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetRegs(&regs);
1608*eb293b8fSAndroid Build Coastguard Worker 
1609*eb293b8fSAndroid Build Coastguard Worker   // Invalid elf
1610*eb293b8fSAndroid Build Coastguard Worker   frame = unwinder.BuildFrameFromPcOnly(0x100310);
1611*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10030eU, frame.pc);
1612*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x60eU, frame.rel_pc);
1613*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame.map_info != nullptr);
1614*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/jit.so", frame.map_info->name());
1615*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/jit.so", frame.map_info->GetFullName());
1616*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100U, frame.map_info->elf_start_offset());
1617*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x200U, frame.map_info->offset());
1618*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100000U, frame.map_info->start());
1619*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x101000U, frame.map_info->end());
1620*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame.map_info->flags());
1621*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->GetLoadBias());
1622*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame.function_name);
1623*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.function_offset);
1624*eb293b8fSAndroid Build Coastguard Worker }
1625*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,build_frame_pc_valid_elf)1626*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, build_frame_pc_valid_elf) {
1627*eb293b8fSAndroid Build Coastguard Worker   RegsFake regs(10);
1628*eb293b8fSAndroid Build Coastguard Worker   regs.FakeSetArch(ARCH_ARM);
1629*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1630*eb293b8fSAndroid Build Coastguard Worker 
1631*eb293b8fSAndroid Build Coastguard Worker   FrameData frame;
1632*eb293b8fSAndroid Build Coastguard Worker 
1633*eb293b8fSAndroid Build Coastguard Worker   // Valid elf, no function data.
1634*eb293b8fSAndroid Build Coastguard Worker   frame = unwinder.BuildFrameFromPcOnly(0x1010);
1635*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100cU, frame.pc);
1636*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xcU, frame.rel_pc);
1637*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame.map_info != nullptr);
1638*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame.map_info->name());
1639*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame.map_info->GetFullName());
1640*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->elf_start_offset());
1641*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->offset());
1642*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame.map_info->start());
1643*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame.map_info->end());
1644*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame.map_info->flags());
1645*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->GetLoadBias());
1646*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame.function_name);
1647*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.function_offset);
1648*eb293b8fSAndroid Build Coastguard Worker 
1649*eb293b8fSAndroid Build Coastguard Worker   // Valid elf, function data present, but do not resolve.
1650*eb293b8fSAndroid Build Coastguard Worker   ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));
1651*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetResolveNames(false);
1652*eb293b8fSAndroid Build Coastguard Worker 
1653*eb293b8fSAndroid Build Coastguard Worker   frame = unwinder.BuildFrameFromPcOnly(0x1010);
1654*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100cU, frame.pc);
1655*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xcU, frame.rel_pc);
1656*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame.map_info != nullptr);
1657*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame.map_info->name());
1658*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame.map_info->GetFullName());
1659*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->elf_start_offset());
1660*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->offset());
1661*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame.map_info->start());
1662*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame.map_info->end());
1663*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame.map_info->flags());
1664*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->GetLoadBias());
1665*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("", frame.function_name);
1666*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.function_offset);
1667*eb293b8fSAndroid Build Coastguard Worker 
1668*eb293b8fSAndroid Build Coastguard Worker   // Valid elf, function data present.
1669*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetResolveNames(true);
1670*eb293b8fSAndroid Build Coastguard Worker 
1671*eb293b8fSAndroid Build Coastguard Worker   frame = unwinder.BuildFrameFromPcOnly(0x1010);
1672*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100cU, frame.pc);
1673*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xcU, frame.rel_pc);
1674*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame.map_info != nullptr);
1675*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame.map_info->name());
1676*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/system/fake/libc.so", frame.map_info->GetFullName());
1677*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->elf_start_offset());
1678*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->offset());
1679*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x1000U, frame.map_info->start());
1680*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x8000U, frame.map_info->end());
1681*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE, frame.map_info->flags());
1682*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->GetLoadBias());
1683*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("Frame0", frame.function_name);
1684*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(10U, frame.function_offset);
1685*eb293b8fSAndroid Build Coastguard Worker }
1686*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,build_frame_pc_in_jit)1687*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, build_frame_pc_in_jit) {
1688*eb293b8fSAndroid Build Coastguard Worker   // The whole ELF will be copied (read), so it must be valid (readable) memory.
1689*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemoryBlock(0xf7000, 0x1000, 0);
1690*eb293b8fSAndroid Build Coastguard Worker 
1691*eb293b8fSAndroid Build Coastguard Worker   Elf32_Ehdr ehdr = {};
1692*eb293b8fSAndroid Build Coastguard Worker   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
1693*eb293b8fSAndroid Build Coastguard Worker   ehdr.e_phoff = 0x50;
1694*eb293b8fSAndroid Build Coastguard Worker   ehdr.e_phnum = 1;
1695*eb293b8fSAndroid Build Coastguard Worker   ehdr.e_phentsize = sizeof(Elf32_Phdr);
1696*eb293b8fSAndroid Build Coastguard Worker   ehdr.e_shoff = 0x100;
1697*eb293b8fSAndroid Build Coastguard Worker   ehdr.e_shstrndx = 1;
1698*eb293b8fSAndroid Build Coastguard Worker   ehdr.e_shentsize = sizeof(Elf32_Shdr);
1699*eb293b8fSAndroid Build Coastguard Worker   ehdr.e_shnum = 3;
1700*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemory(0xf7000, &ehdr, sizeof(ehdr));
1701*eb293b8fSAndroid Build Coastguard Worker 
1702*eb293b8fSAndroid Build Coastguard Worker   Elf32_Phdr phdr = {};
1703*eb293b8fSAndroid Build Coastguard Worker   phdr.p_flags = PF_X;
1704*eb293b8fSAndroid Build Coastguard Worker   phdr.p_type = PT_LOAD;
1705*eb293b8fSAndroid Build Coastguard Worker   phdr.p_offset = 0x100000;
1706*eb293b8fSAndroid Build Coastguard Worker   phdr.p_vaddr = 0x100000;
1707*eb293b8fSAndroid Build Coastguard Worker   phdr.p_memsz = 0x1000;
1708*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemory(0xf7050, &phdr, sizeof(phdr));
1709*eb293b8fSAndroid Build Coastguard Worker 
1710*eb293b8fSAndroid Build Coastguard Worker   Elf32_Shdr shdr = {};
1711*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_type = SHT_NULL;
1712*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemory(0xf7100, &shdr, sizeof(shdr));
1713*eb293b8fSAndroid Build Coastguard Worker 
1714*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_type = SHT_SYMTAB;
1715*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_link = 2;
1716*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_addr = 0x300;
1717*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_offset = 0x300;
1718*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_entsize = sizeof(Elf32_Sym);
1719*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_size = shdr.sh_entsize;
1720*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemory(0xf7100 + sizeof(shdr), &shdr, sizeof(shdr));
1721*eb293b8fSAndroid Build Coastguard Worker 
1722*eb293b8fSAndroid Build Coastguard Worker   memset(&shdr, 0, sizeof(shdr));
1723*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_type = SHT_STRTAB;
1724*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_name = 0x500;
1725*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_offset = 0x400;
1726*eb293b8fSAndroid Build Coastguard Worker   shdr.sh_size = 0x100;
1727*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemory(0xf7100 + 2 * sizeof(shdr), &shdr, sizeof(shdr));
1728*eb293b8fSAndroid Build Coastguard Worker 
1729*eb293b8fSAndroid Build Coastguard Worker   Elf32_Sym sym = {};
1730*eb293b8fSAndroid Build Coastguard Worker   sym.st_shndx = 2;
1731*eb293b8fSAndroid Build Coastguard Worker   sym.st_info = STT_FUNC;
1732*eb293b8fSAndroid Build Coastguard Worker   sym.st_value = 0x100300;
1733*eb293b8fSAndroid Build Coastguard Worker   sym.st_size = 0x100;
1734*eb293b8fSAndroid Build Coastguard Worker   sym.st_name = 1;
1735*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemory(0xf7300, &sym, sizeof(sym));
1736*eb293b8fSAndroid Build Coastguard Worker   memory_->SetMemory(0xf7401, "FakeJitFunction");
1737*eb293b8fSAndroid Build Coastguard Worker 
1738*eb293b8fSAndroid Build Coastguard Worker   RegsFake regs(10);
1739*eb293b8fSAndroid Build Coastguard Worker   regs.FakeSetArch(ARCH_ARM);
1740*eb293b8fSAndroid Build Coastguard Worker   std::unique_ptr<JitDebug> jit_debug = CreateJitDebug(regs.Arch(), process_memory_);
1741*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
1742*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetJitDebug(jit_debug.get());
1743*eb293b8fSAndroid Build Coastguard Worker 
1744*eb293b8fSAndroid Build Coastguard Worker   FrameData frame = unwinder.BuildFrameFromPcOnly(0x100310);
1745*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x10030eU, frame.pc);
1746*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x60eU, frame.rel_pc);
1747*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(frame.map_info != nullptr);
1748*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/jit.so", frame.map_info->name());
1749*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("/fake/jit.so", frame.map_info->GetFullName());
1750*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100U, frame.map_info->elf_start_offset());
1751*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x200U, frame.map_info->offset());
1752*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x100000U, frame.map_info->start());
1753*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0x101000U, frame.map_info->end());
1754*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame.map_info->flags());
1755*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, frame.map_info->GetLoadBias());
1756*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ("FakeJitFunction", frame.function_name);
1757*eb293b8fSAndroid Build Coastguard Worker   EXPECT_EQ(0xeU, frame.function_offset);
1758*eb293b8fSAndroid Build Coastguard Worker }
1759*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,unwinder_from_pid_set_process_memory)1760*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, unwinder_from_pid_set_process_memory) {
1761*eb293b8fSAndroid Build Coastguard Worker   auto process_memory = Memory::CreateProcessMemoryCached(getpid());
1762*eb293b8fSAndroid Build Coastguard Worker   UnwinderFromPid unwinder(10, getpid(), process_memory);
1763*eb293b8fSAndroid Build Coastguard Worker   unwinder.SetArch(unwindstack::Regs::CurrentArch());
1764*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(unwinder.Init());
1765*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(process_memory.get(), unwinder.GetProcessMemory().get());
1766*eb293b8fSAndroid Build Coastguard Worker }
1767*eb293b8fSAndroid Build Coastguard Worker 
1768*eb293b8fSAndroid Build Coastguard Worker using UnwinderDeathTest = SilentDeathTest;
1769*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderDeathTest,unwinder_from_pid_init_error)1770*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderDeathTest, unwinder_from_pid_init_error) {
1771*eb293b8fSAndroid Build Coastguard Worker   UnwinderFromPid unwinder(10, getpid());
1772*eb293b8fSAndroid Build Coastguard Worker   ASSERT_DEATH(unwinder.Init(), "");
1773*eb293b8fSAndroid Build Coastguard Worker }
1774*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderDeathTest,set_jit_debug_error)1775*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderDeathTest, set_jit_debug_error) {
1776*eb293b8fSAndroid Build Coastguard Worker   Maps maps;
1777*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<Memory> process_memory(new MemoryFake);
1778*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(10, &maps, process_memory);
1779*eb293b8fSAndroid Build Coastguard Worker   ASSERT_DEATH(CreateJitDebug(ARCH_UNKNOWN, process_memory), "");
1780*eb293b8fSAndroid Build Coastguard Worker }
1781*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderTest,unwinder_from_pid_with_external_maps)1782*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderTest, unwinder_from_pid_with_external_maps) {
1783*eb293b8fSAndroid Build Coastguard Worker   LocalMaps map;
1784*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(map.Parse());
1785*eb293b8fSAndroid Build Coastguard Worker 
1786*eb293b8fSAndroid Build Coastguard Worker   UnwinderFromPid unwinder1(10, getpid(), &map);
1787*eb293b8fSAndroid Build Coastguard Worker   unwinder1.SetArch(Regs::CurrentArch());
1788*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(&map, unwinder1.GetMaps());
1789*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(unwinder1.Init());
1790*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(&map, unwinder1.GetMaps());
1791*eb293b8fSAndroid Build Coastguard Worker 
1792*eb293b8fSAndroid Build Coastguard Worker   UnwinderFromPid unwinder2(10, getpid(), Regs::CurrentArch(), &map);
1793*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(&map, unwinder2.GetMaps());
1794*eb293b8fSAndroid Build Coastguard Worker   ASSERT_TRUE(unwinder2.Init());
1795*eb293b8fSAndroid Build Coastguard Worker   ASSERT_EQ(&map, unwinder2.GetMaps());
1796*eb293b8fSAndroid Build Coastguard Worker }
1797*eb293b8fSAndroid Build Coastguard Worker 
TEST_F(UnwinderDeathTest,set_dex_files_error)1798*eb293b8fSAndroid Build Coastguard Worker TEST_F(UnwinderDeathTest, set_dex_files_error) {
1799*eb293b8fSAndroid Build Coastguard Worker   Maps maps;
1800*eb293b8fSAndroid Build Coastguard Worker   std::shared_ptr<Memory> process_memory(new MemoryFake);
1801*eb293b8fSAndroid Build Coastguard Worker   Unwinder unwinder(10, &maps, process_memory);
1802*eb293b8fSAndroid Build Coastguard Worker   ASSERT_DEATH(CreateDexFiles(ARCH_UNKNOWN, process_memory), "");
1803*eb293b8fSAndroid Build Coastguard Worker }
1804*eb293b8fSAndroid Build Coastguard Worker 
1805*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
1806