• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/core


Commit MetaInfo

修訂b7b0cecce43022a31d99622be0591e9f900fa80c (tree)
時間2019-04-20 02:57:11
作者Christopher Ferris <cferris@goog...>
CommiterChristopher Ferris

Log Message

Add indicator that an elf is memory backed.

Modify the unwinder library to indicate that at least one of the stack
frames contains an elf file that is unreadable.

Modify debuggerd to display a note about the unreadable frame and a possible
way to fix it.

Bug: 129769339

Test: New unit tests pass.
Test: Ran an app that crashes and has an unreadable file and verified the
Test: message is displayed. Then setenforce 0 and verify the message is
Test: not displayed.
Change-Id: Ibc4fe1d117e9b5840290454e90914ddc698d3cc2
Merged-In: Ibc4fe1d117e9b5840290454e90914ddc698d3cc2
(cherry picked from commit 4ae266ccbddbd0a6529248ecd1b324feab261c0d)

Change Summary

差異

--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -183,6 +183,12 @@ cc_library_static {
183183 ],
184184 },
185185 },
186+
187+ product_variables: {
188+ debuggable: {
189+ cflags: ["-DROOT_POSSIBLE"],
190+ },
191+ },
186192 }
187193
188194 cc_test {
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -74,10 +74,7 @@ void dump_backtrace_thread(int output_fd, unwindstack::Unwinder* unwinder,
7474 return;
7575 }
7676
77- unwinder->SetDisplayBuildID(true);
78- for (size_t i = 0; i < unwinder->NumFrames(); i++) {
79- _LOG(&log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(i).c_str());
80- }
77+ log_backtrace(&log, unwinder, " ");
8178 }
8279
8380 void dump_backtrace(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder,
--- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
@@ -73,9 +73,12 @@ typedef uint32_t word_t;
7373 void _LOG(log_t* log, logtype ltype, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
7474
7575 namespace unwindstack {
76+class Unwinder;
7677 class Memory;
7778 }
7879
80+void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix);
81+
7982 void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const std::string&);
8083
8184 void read_with_default(const char* path, char* buf, size_t len, const char* default_value);
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -371,13 +371,6 @@ static void dump_all_maps(log_t* log, unwindstack::Unwinder* unwinder, uint64_t
371371 }
372372 }
373373
374-void dump_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
375- unwinder->SetDisplayBuildID(true);
376- for (size_t i = 0; i < unwinder->NumFrames(); i++) {
377- _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
378- }
379-}
380-
381374 static void print_register_row(log_t* log,
382375 const std::vector<std::pair<std::string, uint64_t>>& registers) {
383376 std::string output;
@@ -470,7 +463,7 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa
470463 _LOG(log, logtype::THREAD, "Failed to unwind");
471464 } else {
472465 _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n");
473- dump_backtrace(log, unwinder, " ");
466+ log_backtrace(log, unwinder, " ");
474467
475468 _LOG(log, logtype::STACK, "\nstack:\n");
476469 dump_stack(log, unwinder->frames(), unwinder->GetMaps(), unwinder->GetProcessMemory().get());
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -38,6 +38,7 @@
3838 #include <debuggerd/handler.h>
3939 #include <log/log.h>
4040 #include <unwindstack/Memory.h>
41+#include <unwindstack/Unwinder.h>
4142
4243 using android::base::unique_fd;
4344
@@ -422,3 +423,22 @@ const char* get_sigcode(const siginfo_t* si) {
422423 // Then give up...
423424 return "?";
424425 }
426+
427+void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
428+ if (unwinder->elf_from_memory_not_file()) {
429+ _LOG(log, logtype::BACKTRACE,
430+ "%sNOTE: Function names and BuildId information is missing for some frames due\n", prefix);
431+ _LOG(log, logtype::BACKTRACE,
432+ "%sNOTE: to unreadable libraries. For unwinds of apps, only shared libraries\n", prefix);
433+ _LOG(log, logtype::BACKTRACE, "%sNOTE: found under the lib/ directory are readable.\n", prefix);
434+#if defined(ROOT_POSSIBLE)
435+ _LOG(log, logtype::BACKTRACE,
436+ "%sNOTE: On this device, run setenforce 0 to make the libraries readable.\n", prefix);
437+#endif
438+ }
439+
440+ unwinder->SetDisplayBuildID(true);
441+ for (size_t i = 0; i < unwinder->NumFrames(); i++) {
442+ _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(i).c_str());
443+ }
444+}
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -161,6 +161,7 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
161161 // option is used.
162162 std::unique_ptr<MemoryRange> memory(new MemoryRange(process_memory, start, end - start, 0));
163163 if (Elf::IsValidElf(memory.get())) {
164+ memory_backed_elf = true;
164165 return memory.release();
165166 }
166167
@@ -184,6 +185,7 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
184185 new MemoryRange(process_memory, prev_map->start, prev_map->end - prev_map->start, 0));
185186 ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset));
186187
188+ memory_backed_elf = true;
187189 return ranges;
188190 }
189191
@@ -237,6 +239,7 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum exp
237239 std::lock_guard<std::mutex> guard(prev_map->mutex_);
238240 if (prev_map->elf.get() == nullptr) {
239241 prev_map->elf = elf;
242+ prev_map->memory_backed_elf = memory_backed_elf;
240243 }
241244 }
242245 return elf.get();
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -141,6 +141,7 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
141141 frames_.clear();
142142 last_error_.code = ERROR_NONE;
143143 last_error_.address = 0;
144+ elf_from_memory_not_file_ = false;
144145
145146 ArchEnum arch = regs_->Arch();
146147
@@ -164,6 +165,12 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
164165 break;
165166 }
166167 elf = map_info->GetElf(process_memory_, arch);
168+ // If this elf is memory backed, and there is a valid file, then set
169+ // an indicator that we couldn't open the file.
170+ if (!elf_from_memory_not_file_ && map_info->memory_backed_elf && !map_info->name.empty() &&
171+ map_info->name[0] != '[') {
172+ elf_from_memory_not_file_ = true;
173+ }
167174 step_pc = regs_->pc();
168175 rel_pc = elf->GetRelPc(step_pc, map_info);
169176 // Everyone except elf data in gdb jit debug maps uses the relative pc.
--- a/libunwindstack/include/unwindstack/MapInfo.h
+++ b/libunwindstack/include/unwindstack/MapInfo.h
@@ -75,6 +75,9 @@ struct MapInfo {
7575 // make it easier to move to a fine grained lock in the future.
7676 std::atomic_uintptr_t build_id;
7777
78+ // Set to true if the elf file data is coming from memory.
79+ bool memory_backed_elf = false;
80+
7881 // This function guarantees it will never return nullptr.
7982 Elf* GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum expected_arch);
8083
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -111,6 +111,8 @@ class Unwinder {
111111 void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
112112 #endif
113113
114+ bool elf_from_memory_not_file() { return elf_from_memory_not_file_; }
115+
114116 ErrorCode LastErrorCode() { return last_error_.code; }
115117 uint64_t LastErrorAddress() { return last_error_.address; }
116118
@@ -132,6 +134,9 @@ class Unwinder {
132134 bool resolve_names_ = true;
133135 bool embedded_soname_ = true;
134136 bool display_build_id_ = false;
137+ // True if at least one elf file is coming from memory and not the related
138+ // file. This is only true if there is an actual file backing up the elf.
139+ bool elf_from_memory_not_file_ = false;
135140 ErrorData last_error_;
136141 };
137142
--- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
+++ b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
@@ -108,6 +108,7 @@ TEST_F(MapInfoCreateMemoryTest, end_le_start) {
108108 info.end = 0x101;
109109 memory.reset(info.CreateMemory(process_memory_));
110110 ASSERT_TRUE(memory.get() != nullptr);
111+ EXPECT_FALSE(info.memory_backed_elf);
111112 }
112113
113114 // Verify that if the offset is non-zero but there is no elf at the offset,
@@ -117,6 +118,7 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_full_file) {
117118
118119 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
119120 ASSERT_TRUE(memory.get() != nullptr);
121+ EXPECT_FALSE(info.memory_backed_elf);
120122 ASSERT_EQ(0x100U, info.elf_offset);
121123 EXPECT_EQ(0x100U, info.elf_start_offset);
122124
@@ -140,32 +142,40 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_full_file) {
140142 // offset to zero.
141143 info.elf_offset = 0;
142144 info.elf_start_offset = 0;
145+ info.memory_backed_elf = false;
143146 memory.reset(info.CreateMemory(process_memory_));
144147 ASSERT_TRUE(memory.get() != nullptr);
148+ EXPECT_FALSE(info.memory_backed_elf);
145149 ASSERT_EQ(0x100U, info.elf_offset);
146150 EXPECT_EQ(0x100U, info.elf_start_offset);
147151
148152 prev_info.offset = 0;
149153 info.elf_offset = 0;
150154 info.elf_start_offset = 0;
155+ info.memory_backed_elf = false;
151156 memory.reset(info.CreateMemory(process_memory_));
152157 ASSERT_TRUE(memory.get() != nullptr);
158+ EXPECT_FALSE(info.memory_backed_elf);
153159 ASSERT_EQ(0x100U, info.elf_offset);
154160 EXPECT_EQ(0x100U, info.elf_start_offset);
155161
156162 prev_info.flags = PROT_READ;
157163 info.elf_offset = 0;
158164 info.elf_start_offset = 0;
165+ info.memory_backed_elf = false;
159166 memory.reset(info.CreateMemory(process_memory_));
160167 ASSERT_TRUE(memory.get() != nullptr);
168+ EXPECT_FALSE(info.memory_backed_elf);
161169 ASSERT_EQ(0x100U, info.elf_offset);
162170 EXPECT_EQ(0x100U, info.elf_start_offset);
163171
164172 prev_info.name = info.name;
165173 info.elf_offset = 0;
166174 info.elf_start_offset = 0;
175+ info.memory_backed_elf = false;
167176 memory.reset(info.CreateMemory(process_memory_));
168177 ASSERT_TRUE(memory.get() != nullptr);
178+ EXPECT_FALSE(info.memory_backed_elf);
169179 ASSERT_EQ(0x100U, info.elf_offset);
170180 EXPECT_EQ(0U, info.elf_start_offset);
171181 }
@@ -177,6 +187,7 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file) {
177187
178188 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
179189 ASSERT_TRUE(memory.get() != nullptr);
190+ EXPECT_FALSE(info.memory_backed_elf);
180191 ASSERT_EQ(0U, info.elf_offset);
181192 EXPECT_EQ(0x1000U, info.elf_start_offset);
182193
@@ -201,6 +212,7 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_e
201212
202213 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
203214 ASSERT_TRUE(memory.get() != nullptr);
215+ EXPECT_FALSE(info.memory_backed_elf);
204216 ASSERT_EQ(0U, info.elf_offset);
205217 EXPECT_EQ(0x1000U, info.elf_start_offset);
206218
@@ -218,6 +230,7 @@ TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_e
218230
219231 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
220232 ASSERT_TRUE(memory.get() != nullptr);
233+ EXPECT_FALSE(info.memory_backed_elf);
221234 ASSERT_EQ(0U, info.elf_offset);
222235 EXPECT_EQ(0x2000U, info.elf_start_offset);
223236
@@ -259,6 +272,7 @@ TEST_F(MapInfoCreateMemoryTest, process_memory) {
259272
260273 std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
261274 ASSERT_TRUE(memory.get() != nullptr);
275+ EXPECT_TRUE(info.memory_backed_elf);
262276
263277 memset(buffer.data(), 0, buffer.size());
264278 ASSERT_TRUE(memory->ReadFully(0, buffer.data(), buffer.size()));
@@ -290,6 +304,7 @@ TEST_F(MapInfoCreateMemoryTest, valid_rosegment_zero_offset) {
290304
291305 std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
292306 ASSERT_TRUE(mem.get() != nullptr);
307+ EXPECT_TRUE(map_info->memory_backed_elf);
293308 EXPECT_EQ(0x4000UL, map_info->elf_offset);
294309 EXPECT_EQ(0x4000UL, map_info->offset);
295310 EXPECT_EQ(0U, map_info->elf_start_offset);
@@ -336,6 +351,7 @@ TEST_F(MapInfoCreateMemoryTest, valid_rosegment_non_zero_offset) {
336351
337352 std::unique_ptr<Memory> mem(map_info->CreateMemory(process_memory_));
338353 ASSERT_TRUE(mem.get() != nullptr);
354+ EXPECT_TRUE(map_info->memory_backed_elf);
339355 EXPECT_EQ(0x1000UL, map_info->elf_offset);
340356 EXPECT_EQ(0xb000UL, map_info->offset);
341357 EXPECT_EQ(0xa000UL, map_info->elf_start_offset);
@@ -374,6 +390,7 @@ TEST_F(MapInfoCreateMemoryTest, rosegment_from_file) {
374390 // extend over the executable segment.
375391 std::unique_ptr<Memory> memory(map_info->CreateMemory(process_memory_));
376392 ASSERT_TRUE(memory.get() != nullptr);
393+ EXPECT_FALSE(map_info->memory_backed_elf);
377394 std::vector<uint8_t> buffer(0x100);
378395 EXPECT_EQ(0x2000U, map_info->offset);
379396 EXPECT_EQ(0U, map_info->elf_offset);
@@ -388,7 +405,9 @@ TEST_F(MapInfoCreateMemoryTest, rosegment_from_file) {
388405 ASSERT_EQ(0x1000, lseek(elf_at_1000_.fd, 0x1000, SEEK_SET));
389406 ASSERT_TRUE(android::base::WriteFully(elf_at_1000_.fd, &ehdr, sizeof(ehdr)));
390407
408+ map_info->memory_backed_elf = false;
391409 memory.reset(map_info->CreateMemory(process_memory_));
410+ EXPECT_FALSE(map_info->memory_backed_elf);
392411 EXPECT_EQ(0x2000U, map_info->offset);
393412 EXPECT_EQ(0x1000U, map_info->elf_offset);
394413 EXPECT_EQ(0x1000U, map_info->elf_start_offset);
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -108,6 +108,24 @@ class UnwinderTest : public ::testing::Test {
108108 const auto& info2 = *--maps_->end();
109109 info2->elf_offset = 0x8000;
110110
111+ elf = new ElfFake(new MemoryFake);
112+ elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
113+ AddMapInfo(0xc0000, 0xc1000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "/fake/unreadable.so", elf);
114+ const auto& info3 = *--maps_->end();
115+ info3->memory_backed_elf = true;
116+
117+ elf = new ElfFake(new MemoryFake);
118+ elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
119+ AddMapInfo(0xc1000, 0xc2000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "[vdso]", elf);
120+ const auto& info4 = *--maps_->end();
121+ info4->memory_backed_elf = true;
122+
123+ elf = new ElfFake(new MemoryFake);
124+ elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
125+ AddMapInfo(0xc2000, 0xc3000, 0, PROT_READ | PROT_WRITE | PROT_EXEC, "", elf);
126+ const auto& info5 = *--maps_->end();
127+ info5->memory_backed_elf = true;
128+
111129 process_memory_.reset(new MemoryFake);
112130 }
113131
@@ -140,6 +158,7 @@ TEST_F(UnwinderTest, multiple_frames) {
140158 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
141159 unwinder.Unwind();
142160 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
161+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
143162
144163 ASSERT_EQ(3U, unwinder.NumFrames());
145164
@@ -204,6 +223,7 @@ TEST_F(UnwinderTest, multiple_frames_dont_resolve_names) {
204223 unwinder.SetResolveNames(false);
205224 unwinder.Unwind();
206225 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
226+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
207227
208228 ASSERT_EQ(3U, unwinder.NumFrames());
209229
@@ -263,6 +283,7 @@ TEST_F(UnwinderTest, non_zero_load_bias) {
263283 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
264284 unwinder.Unwind();
265285 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
286+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
266287
267288 ASSERT_EQ(1U, unwinder.NumFrames());
268289
@@ -292,6 +313,7 @@ TEST_F(UnwinderTest, non_zero_elf_offset) {
292313 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
293314 unwinder.Unwind();
294315 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
316+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
295317
296318 ASSERT_EQ(1U, unwinder.NumFrames());
297319
@@ -321,6 +343,7 @@ TEST_F(UnwinderTest, non_zero_map_offset) {
321343 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
322344 unwinder.Unwind();
323345 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
346+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
324347
325348 ASSERT_EQ(1U, unwinder.NumFrames());
326349
@@ -351,6 +374,7 @@ TEST_F(UnwinderTest, disable_embedded_soname) {
351374 unwinder.SetEmbeddedSoname(false);
352375 unwinder.Unwind();
353376 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
377+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
354378
355379 ASSERT_EQ(1U, unwinder.NumFrames());
356380
@@ -387,6 +411,7 @@ TEST_F(UnwinderTest, no_frames_after_finished) {
387411 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
388412 unwinder.Unwind();
389413 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
414+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
390415
391416 ASSERT_EQ(1U, unwinder.NumFrames());
392417
@@ -419,6 +444,7 @@ TEST_F(UnwinderTest, max_frames) {
419444 Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
420445 unwinder.Unwind();
421446 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
447+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
422448
423449 ASSERT_EQ(20U, unwinder.NumFrames());
424450
@@ -461,6 +487,7 @@ TEST_F(UnwinderTest, verify_frames_skipped) {
461487 std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
462488 unwinder.Unwind(&skip_libs);
463489 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
490+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
464491
465492 ASSERT_EQ(3U, unwinder.NumFrames());
466493
@@ -522,6 +549,7 @@ TEST_F(UnwinderTest, sp_not_in_map) {
522549 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
523550 unwinder.Unwind();
524551 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
552+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
525553
526554 ASSERT_EQ(2U, unwinder.NumFrames());
527555
@@ -569,6 +597,7 @@ TEST_F(UnwinderTest, pc_in_device_stops_unwind) {
569597 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
570598 unwinder.Unwind();
571599 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
600+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
572601
573602 ASSERT_EQ(1U, unwinder.NumFrames());
574603 }
@@ -588,6 +617,7 @@ TEST_F(UnwinderTest, sp_in_device_stops_unwind) {
588617 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
589618 unwinder.Unwind();
590619 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
620+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
591621
592622 ASSERT_EQ(1U, unwinder.NumFrames());
593623 }
@@ -602,6 +632,7 @@ TEST_F(UnwinderTest, pc_without_map) {
602632 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
603633 unwinder.Unwind();
604634 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
635+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
605636
606637 ASSERT_EQ(1U, unwinder.NumFrames());
607638
@@ -638,6 +669,7 @@ TEST_F(UnwinderTest, speculative_frame) {
638669 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
639670 unwinder.Unwind();
640671 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
672+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
641673
642674 ASSERT_EQ(3U, unwinder.NumFrames());
643675
@@ -703,6 +735,7 @@ TEST_F(UnwinderTest, speculative_frame_removed) {
703735 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
704736 unwinder.Unwind();
705737 EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
738+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
706739
707740 ASSERT_EQ(2U, unwinder.NumFrames());
708741
@@ -752,6 +785,7 @@ TEST_F(UnwinderTest, speculative_frame_not_removed_pc_bad) {
752785 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
753786 unwinder.Unwind();
754787 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
788+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
755789
756790 ASSERT_EQ(2U, unwinder.NumFrames());
757791
@@ -799,6 +833,7 @@ TEST_F(UnwinderTest, speculative_frame_check_with_no_frames) {
799833 std::vector<std::string> skip_names{"libanother.so"};
800834 unwinder.Unwind(&skip_names);
801835 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
836+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
802837
803838 ASSERT_EQ(0U, unwinder.NumFrames());
804839 }
@@ -821,6 +856,7 @@ TEST_F(UnwinderTest, map_ignore_suffixes) {
821856 std::vector<std::string> suffixes{"oat"};
822857 unwinder.Unwind(nullptr, &suffixes);
823858 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
859+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
824860
825861 ASSERT_EQ(2U, unwinder.NumFrames());
826862 // Make sure the elf was not initialized.
@@ -879,6 +915,7 @@ TEST_F(UnwinderTest, sp_pc_do_not_change) {
879915 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
880916 unwinder.Unwind();
881917 EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
918+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
882919
883920 ASSERT_EQ(3U, unwinder.NumFrames());
884921
@@ -937,6 +974,7 @@ TEST_F(UnwinderTest, dex_pc_in_map) {
937974 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
938975 unwinder.Unwind();
939976 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
977+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
940978
941979 ASSERT_EQ(2U, unwinder.NumFrames());
942980
@@ -980,6 +1018,7 @@ TEST_F(UnwinderTest, dex_pc_not_in_map) {
9801018 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
9811019 unwinder.Unwind();
9821020 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1021+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
9831022
9841023 ASSERT_EQ(2U, unwinder.NumFrames());
9851024
@@ -1026,6 +1065,7 @@ TEST_F(UnwinderTest, dex_pc_multiple_frames) {
10261065 Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
10271066 unwinder.Unwind();
10281067 EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1068+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
10291069
10301070 ASSERT_EQ(3U, unwinder.NumFrames());
10311071
@@ -1084,6 +1124,7 @@ TEST_F(UnwinderTest, dex_pc_max_frames) {
10841124 Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
10851125 unwinder.Unwind();
10861126 EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
1127+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
10871128
10881129 ASSERT_EQ(1U, unwinder.NumFrames());
10891130
@@ -1103,6 +1144,96 @@ TEST_F(UnwinderTest, dex_pc_max_frames) {
11031144 EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
11041145 }
11051146
1147+TEST_F(UnwinderTest, elf_from_memory_not_file) {
1148+ ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1149+
1150+ regs_.set_pc(0xc0050);
1151+ regs_.set_sp(0x10000);
1152+ ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1153+
1154+ Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1155+ unwinder.Unwind();
1156+ EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1157+ EXPECT_TRUE(unwinder.elf_from_memory_not_file());
1158+
1159+ ASSERT_EQ(1U, unwinder.NumFrames());
1160+
1161+ auto* frame = &unwinder.frames()[0];
1162+ EXPECT_EQ(0U, frame->num);
1163+ EXPECT_EQ(0x50U, frame->rel_pc);
1164+ EXPECT_EQ(0xc0050U, frame->pc);
1165+ EXPECT_EQ(0x10000U, frame->sp);
1166+ EXPECT_EQ("Frame0", frame->function_name);
1167+ EXPECT_EQ(0U, frame->function_offset);
1168+ EXPECT_EQ("/fake/unreadable.so", frame->map_name);
1169+ EXPECT_EQ(0U, frame->map_elf_start_offset);
1170+ EXPECT_EQ(0U, frame->map_exact_offset);
1171+ EXPECT_EQ(0xc0000U, frame->map_start);
1172+ EXPECT_EQ(0xc1000U, frame->map_end);
1173+ EXPECT_EQ(0U, frame->map_load_bias);
1174+ EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1175+}
1176+
1177+TEST_F(UnwinderTest, elf_from_memory_but_no_valid_file_with_bracket) {
1178+ ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1179+
1180+ regs_.set_pc(0xc1050);
1181+ regs_.set_sp(0x10000);
1182+ ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1183+
1184+ Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1185+ unwinder.Unwind();
1186+ EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1187+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1188+
1189+ ASSERT_EQ(1U, unwinder.NumFrames());
1190+
1191+ auto* frame = &unwinder.frames()[0];
1192+ EXPECT_EQ(0U, frame->num);
1193+ EXPECT_EQ(0x50U, frame->rel_pc);
1194+ EXPECT_EQ(0xc1050U, frame->pc);
1195+ EXPECT_EQ(0x10000U, frame->sp);
1196+ EXPECT_EQ("Frame0", frame->function_name);
1197+ EXPECT_EQ(0U, frame->function_offset);
1198+ EXPECT_EQ("[vdso]", frame->map_name);
1199+ EXPECT_EQ(0U, frame->map_elf_start_offset);
1200+ EXPECT_EQ(0U, frame->map_exact_offset);
1201+ EXPECT_EQ(0xc1000U, frame->map_start);
1202+ EXPECT_EQ(0xc2000U, frame->map_end);
1203+ EXPECT_EQ(0U, frame->map_load_bias);
1204+ EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1205+}
1206+
1207+TEST_F(UnwinderTest, elf_from_memory_but_empty_filename) {
1208+ ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0));
1209+
1210+ regs_.set_pc(0xc2050);
1211+ regs_.set_sp(0x10000);
1212+ ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
1213+
1214+ Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
1215+ unwinder.Unwind();
1216+ EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
1217+ EXPECT_FALSE(unwinder.elf_from_memory_not_file());
1218+
1219+ ASSERT_EQ(1U, unwinder.NumFrames());
1220+
1221+ auto* frame = &unwinder.frames()[0];
1222+ EXPECT_EQ(0U, frame->num);
1223+ EXPECT_EQ(0x50U, frame->rel_pc);
1224+ EXPECT_EQ(0xc2050U, frame->pc);
1225+ EXPECT_EQ(0x10000U, frame->sp);
1226+ EXPECT_EQ("Frame0", frame->function_name);
1227+ EXPECT_EQ(0U, frame->function_offset);
1228+ EXPECT_EQ("", frame->map_name);
1229+ EXPECT_EQ(0U, frame->map_elf_start_offset);
1230+ EXPECT_EQ(0U, frame->map_exact_offset);
1231+ EXPECT_EQ(0xc2000U, frame->map_start);
1232+ EXPECT_EQ(0xc3000U, frame->map_end);
1233+ EXPECT_EQ(0U, frame->map_load_bias);
1234+ EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags);
1235+}
1236+
11061237 // Verify format frame code.
11071238 TEST_F(UnwinderTest, format_frame) {
11081239 RegsFake regs_arm(10);