Loading debuggerd/Android.mk +2 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ backtrace.cpp \ debuggerd.cpp \ elf_utils.cpp \ getevent.cpp \ tombstone.cpp \ utility.cpp \ Loading @@ -28,6 +29,7 @@ endif LOCAL_SHARED_LIBRARIES := \ libbacktrace \ libbase \ libcutils \ liblog \ libselinux \ Loading @@ -38,7 +40,6 @@ LOCAL_MODULE := debuggerd LOCAL_MODULE_STEM_32 := debuggerd LOCAL_MODULE_STEM_64 := debuggerd64 LOCAL_MULTILIB := both LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk include $(BUILD_EXECUTABLE) Loading debuggerd/elf_utils.cpp 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "DEBUG" #include <elf.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <string> #include <backtrace/Backtrace.h> #include <base/stringprintf.h> #include <log/log.h> #include "elf_utils.h" template <typename HdrType, typename PhdrType, typename NhdrType> static bool get_build_id( Backtrace* backtrace, uintptr_t base_addr, uint8_t* e_ident, std::string* build_id) { HdrType hdr; memcpy(&hdr.e_ident[0], e_ident, EI_NIDENT); // First read the rest of the header. if (backtrace->Read(base_addr + EI_NIDENT, reinterpret_cast<uint8_t*>(&hdr) + EI_NIDENT, sizeof(HdrType) - EI_NIDENT) != sizeof(HdrType) - EI_NIDENT) { return false; } for (size_t i = 0; i < hdr.e_phnum; i++) { PhdrType phdr; if (backtrace->Read(base_addr + hdr.e_phoff + i * hdr.e_phentsize, reinterpret_cast<uint8_t*>(&phdr), sizeof(phdr)) != sizeof(phdr)) { return false; } // Looking for the .note.gnu.build-id note. if (phdr.p_type == PT_NOTE) { size_t hdr_size = phdr.p_filesz; uintptr_t addr = base_addr + phdr.p_offset; while (hdr_size >= sizeof(NhdrType)) { NhdrType nhdr; if (backtrace->Read(addr, reinterpret_cast<uint8_t*>(&nhdr), sizeof(nhdr)) != sizeof(nhdr)) { return false; } addr += sizeof(nhdr); if (nhdr.n_type == NT_GNU_BUILD_ID) { // Skip the name (which is the owner and should be "GNU"). addr += nhdr.n_namesz; uint8_t build_id_data[128]; if (nhdr.n_namesz > sizeof(build_id_data)) { ALOGE("Possible corrupted note, name size value is too large: %u", nhdr.n_namesz); return false; } if (backtrace->Read(addr, build_id_data, nhdr.n_descsz) != nhdr.n_descsz) { return false; } build_id->clear(); for (size_t bytes = 0; bytes < nhdr.n_descsz; bytes++) { *build_id += android::base::StringPrintf("%02x", build_id_data[bytes]); } return true; } else { // Move past the extra note data. hdr_size -= sizeof(nhdr); size_t skip_bytes = nhdr.n_namesz + nhdr.n_descsz; addr += skip_bytes; if (hdr_size < skip_bytes) { break; } hdr_size -= skip_bytes; } } } } return false; } bool elf_get_build_id(Backtrace* backtrace, uintptr_t addr, std::string* build_id) { // Read and verify the elf magic number first. uint8_t e_ident[EI_NIDENT]; if (backtrace->Read(addr, e_ident, SELFMAG) != SELFMAG) { return false; } if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { return false; } // Read the rest of EI_NIDENT. if (backtrace->Read(addr + SELFMAG, e_ident + SELFMAG, EI_NIDENT - SELFMAG) != EI_NIDENT - SELFMAG) { return false; } if (e_ident[EI_CLASS] == ELFCLASS32) { return get_build_id<Elf32_Ehdr, Elf32_Phdr, Elf32_Nhdr>(backtrace, addr, e_ident, build_id); } else if (e_ident[EI_CLASS] == ELFCLASS64) { return get_build_id<Elf64_Ehdr, Elf64_Phdr, Elf64_Nhdr>(backtrace, addr, e_ident, build_id); } return false; } debuggerd/elf_utils.h 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _DEBUGGERD_ELF_UTILS_H #define _DEBUGGERD_ELF_UTILS_H #include <stdint.h> #include <string> class Backtrace; bool elf_get_build_id(Backtrace*, uintptr_t, std::string*); #endif // _DEBUGGERD_ELF_UTILS_H debuggerd/tombstone.cpp +81 −60 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <private/android_filesystem_config.h> #include <base/stringprintf.h> #include <cutils/properties.h> #include <log/log.h> #include <log/logger.h> Loading @@ -46,9 +47,12 @@ #include <UniquePtr.h> #include <string> #include "backtrace.h" #include "elf_utils.h" #include "machine.h" #include "tombstone.h" #include "backtrace.h" #define STACK_WORDS 16 Loading Loading @@ -234,47 +238,36 @@ static void dump_thread_info(log_t* log, pid_t pid, pid_t tid) { static void dump_stack_segment( Backtrace* backtrace, log_t* log, uintptr_t* sp, size_t words, int label) { // Read the data all at once. word_t stack_data[words]; size_t bytes_read = backtrace->Read(*sp, reinterpret_cast<uint8_t*>(&stack_data[0]), sizeof(word_t) * words); words = bytes_read / sizeof(word_t); std::string line; for (size_t i = 0; i < words; i++) { word_t stack_content; if (!backtrace->ReadWord(*sp, &stack_content)) { break; line = " "; if (i == 0 && label >= 0) { // Print the label once. line += android::base::StringPrintf("#%02d ", label); } else { line += " "; } line += android::base::StringPrintf("%" PRIPTR " %" PRIPTR, *sp, stack_data[i]); backtrace_map_t map; backtrace->FillInMap(stack_content, &map); std::string map_name; if (BacktraceMap::IsValid(map) && map.name.length() > 0) { map_name = " " + map.name; } backtrace->FillInMap(stack_data[i], &map); if (BacktraceMap::IsValid(map) && !map.name.empty()) { line += " " + map.name; uintptr_t offset = 0; std::string func_name(backtrace->GetFunctionName(stack_content, &offset)); std::string func_name(backtrace->GetFunctionName(stack_data[i], &offset)); if (!func_name.empty()) { if (!i && label >= 0) { line += " (" + func_name; if (offset) { _LOG(log, logtype::STACK, " #%02d %" PRIPTR " %" PRIPTR "%s (%s+%" PRIuPTR ")\n", label, *sp, stack_content, map_name.c_str(), func_name.c_str(), offset); } else { _LOG(log, logtype::STACK, " #%02d %" PRIPTR " %" PRIPTR "%s (%s)\n", label, *sp, stack_content, map_name.c_str(), func_name.c_str()); line += android::base::StringPrintf("+%" PRIuPTR, offset); } } else { if (offset) { _LOG(log, logtype::STACK, " %" PRIPTR " %" PRIPTR "%s (%s+%" PRIuPTR ")\n", *sp, stack_content, map_name.c_str(), func_name.c_str(), offset); } else { _LOG(log, logtype::STACK, " %" PRIPTR " %" PRIPTR "%s (%s)\n", *sp, stack_content, map_name.c_str(), func_name.c_str()); } } } else { if (!i && label >= 0) { _LOG(log, logtype::STACK, " #%02d %" PRIPTR " %" PRIPTR "%s\n", label, *sp, stack_content, map_name.c_str()); } else { _LOG(log, logtype::STACK, " %" PRIPTR " %" PRIPTR "%s\n", *sp, stack_content, map_name.c_str()); line += ')'; } } _LOG(log, logtype::STACK, "%s\n", line.c_str()); *sp += sizeof(word_t); } Loading Loading @@ -325,44 +318,72 @@ static void dump_stack(Backtrace* backtrace, log_t* log) { } } static void dump_map(log_t* log, const backtrace_map_t* map, bool fault_addr) { _LOG(log, logtype::MAPS, "%s%" PRIPTR "-%" PRIPTR " %c%c%c %7" PRIdPTR "%s\n", (fault_addr? "--->" : " "), map->start, map->end - 1, (map->flags & PROT_READ) ? 'r' : '-', (map->flags & PROT_WRITE) ? 'w' : '-', (map->flags & PROT_EXEC) ? 'x' : '-', (map->end - map->start), (map->name.length() > 0) ? (" " + map->name).c_str() : ""); } static void dump_all_maps(BacktraceMap* map, log_t* log, pid_t tid) { bool has_fault_address = false; static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, pid_t tid) { bool print_fault_address_marker = false; uintptr_t addr = 0; siginfo_t si; memset(&si, 0, sizeof(si)); if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si)) { _LOG(log, logtype::MAPS, "cannot get siginfo for %d: %s\n", tid, strerror(errno)); _LOG(log, logtype::ERROR, "cannot get siginfo for %d: %s\n", tid, strerror(errno)); } else { has_fault_address = signal_has_si_addr(si.si_signo); print_fault_address_marker = signal_has_si_addr(si.si_signo); addr = reinterpret_cast<uintptr_t>(si.si_addr); } _LOG(log, logtype::MAPS, "\nmemory map:%s\n", has_fault_address ? " (fault address prefixed with --->)" : ""); if (has_fault_address && (addr < map->begin()->start)) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " before any mapped regions\n", addr); _LOG(log, logtype::MAPS, "\n"); if (!print_fault_address_marker) { _LOG(log, logtype::MAPS, "memory map:\n"); } else { _LOG(log, logtype::MAPS, "memory map: (fault address prefixed with --->)\n"); if (map->begin() != map->end() && addr < map->begin()->start) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " before any mapped regions\n", addr); print_fault_address_marker = false; } } BacktraceMap::const_iterator prev = map->begin(); std::string line; for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) { if (addr >= (*prev).end && addr < (*it).start) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " between mapped regions\n", addr); line = " "; if (print_fault_address_marker) { if (addr < it->start) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " between mapped regions\n", addr); print_fault_address_marker = false; } else if (addr >= it->start && addr < it->end) { line = "--->"; print_fault_address_marker = false; } } line += android::base::StringPrintf("%" PRIPTR "-%" PRIPTR " ", it->start, it->end - 1); if (it->flags & PROT_READ) { line += 'r'; } else { line += '-'; } if (it->flags & PROT_WRITE) { line += 'w'; } else { line += '-'; } if (it->flags & PROT_EXEC) { line += 'x'; } else { line += '-'; } line += android::base::StringPrintf(" %8" PRIxPTR, it->end - it->start); if (it->name.length() > 0) { line += " " + it->name; std::string build_id; if ((it->flags & PROT_READ) && elf_get_build_id(backtrace, it->start, &build_id)) { line += " (BuildId: " + build_id + ")"; } } prev = it; bool in_map = has_fault_address && (addr >= (*it).start) && (addr < (*it).end); dump_map(log, &*it, in_map); _LOG(log, logtype::MAPS, "%s\n", line.c_str()); } if (has_fault_address && (addr >= (*prev).end)) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " after any mapped regions\n", addr); if (print_fault_address_marker) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " after any mapped regions\n", addr); } } Loading Loading @@ -627,7 +648,7 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, int si_code dump_backtrace_and_stack(backtrace.get(), log); } dump_memory_and_code(log, tid); dump_all_maps(map.get(), log, tid); dump_all_maps(backtrace.get(), map.get(), log, tid); if (want_logs) { dump_logs(log, pid, 5); Loading Loading
debuggerd/Android.mk +2 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ backtrace.cpp \ debuggerd.cpp \ elf_utils.cpp \ getevent.cpp \ tombstone.cpp \ utility.cpp \ Loading @@ -28,6 +29,7 @@ endif LOCAL_SHARED_LIBRARIES := \ libbacktrace \ libbase \ libcutils \ liblog \ libselinux \ Loading @@ -38,7 +40,6 @@ LOCAL_MODULE := debuggerd LOCAL_MODULE_STEM_32 := debuggerd LOCAL_MODULE_STEM_64 := debuggerd64 LOCAL_MULTILIB := both LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk include $(BUILD_EXECUTABLE) Loading
debuggerd/elf_utils.cpp 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "DEBUG" #include <elf.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <string> #include <backtrace/Backtrace.h> #include <base/stringprintf.h> #include <log/log.h> #include "elf_utils.h" template <typename HdrType, typename PhdrType, typename NhdrType> static bool get_build_id( Backtrace* backtrace, uintptr_t base_addr, uint8_t* e_ident, std::string* build_id) { HdrType hdr; memcpy(&hdr.e_ident[0], e_ident, EI_NIDENT); // First read the rest of the header. if (backtrace->Read(base_addr + EI_NIDENT, reinterpret_cast<uint8_t*>(&hdr) + EI_NIDENT, sizeof(HdrType) - EI_NIDENT) != sizeof(HdrType) - EI_NIDENT) { return false; } for (size_t i = 0; i < hdr.e_phnum; i++) { PhdrType phdr; if (backtrace->Read(base_addr + hdr.e_phoff + i * hdr.e_phentsize, reinterpret_cast<uint8_t*>(&phdr), sizeof(phdr)) != sizeof(phdr)) { return false; } // Looking for the .note.gnu.build-id note. if (phdr.p_type == PT_NOTE) { size_t hdr_size = phdr.p_filesz; uintptr_t addr = base_addr + phdr.p_offset; while (hdr_size >= sizeof(NhdrType)) { NhdrType nhdr; if (backtrace->Read(addr, reinterpret_cast<uint8_t*>(&nhdr), sizeof(nhdr)) != sizeof(nhdr)) { return false; } addr += sizeof(nhdr); if (nhdr.n_type == NT_GNU_BUILD_ID) { // Skip the name (which is the owner and should be "GNU"). addr += nhdr.n_namesz; uint8_t build_id_data[128]; if (nhdr.n_namesz > sizeof(build_id_data)) { ALOGE("Possible corrupted note, name size value is too large: %u", nhdr.n_namesz); return false; } if (backtrace->Read(addr, build_id_data, nhdr.n_descsz) != nhdr.n_descsz) { return false; } build_id->clear(); for (size_t bytes = 0; bytes < nhdr.n_descsz; bytes++) { *build_id += android::base::StringPrintf("%02x", build_id_data[bytes]); } return true; } else { // Move past the extra note data. hdr_size -= sizeof(nhdr); size_t skip_bytes = nhdr.n_namesz + nhdr.n_descsz; addr += skip_bytes; if (hdr_size < skip_bytes) { break; } hdr_size -= skip_bytes; } } } } return false; } bool elf_get_build_id(Backtrace* backtrace, uintptr_t addr, std::string* build_id) { // Read and verify the elf magic number first. uint8_t e_ident[EI_NIDENT]; if (backtrace->Read(addr, e_ident, SELFMAG) != SELFMAG) { return false; } if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { return false; } // Read the rest of EI_NIDENT. if (backtrace->Read(addr + SELFMAG, e_ident + SELFMAG, EI_NIDENT - SELFMAG) != EI_NIDENT - SELFMAG) { return false; } if (e_ident[EI_CLASS] == ELFCLASS32) { return get_build_id<Elf32_Ehdr, Elf32_Phdr, Elf32_Nhdr>(backtrace, addr, e_ident, build_id); } else if (e_ident[EI_CLASS] == ELFCLASS64) { return get_build_id<Elf64_Ehdr, Elf64_Phdr, Elf64_Nhdr>(backtrace, addr, e_ident, build_id); } return false; }
debuggerd/elf_utils.h 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _DEBUGGERD_ELF_UTILS_H #define _DEBUGGERD_ELF_UTILS_H #include <stdint.h> #include <string> class Backtrace; bool elf_get_build_id(Backtrace*, uintptr_t, std::string*); #endif // _DEBUGGERD_ELF_UTILS_H
debuggerd/tombstone.cpp +81 −60 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <private/android_filesystem_config.h> #include <base/stringprintf.h> #include <cutils/properties.h> #include <log/log.h> #include <log/logger.h> Loading @@ -46,9 +47,12 @@ #include <UniquePtr.h> #include <string> #include "backtrace.h" #include "elf_utils.h" #include "machine.h" #include "tombstone.h" #include "backtrace.h" #define STACK_WORDS 16 Loading Loading @@ -234,47 +238,36 @@ static void dump_thread_info(log_t* log, pid_t pid, pid_t tid) { static void dump_stack_segment( Backtrace* backtrace, log_t* log, uintptr_t* sp, size_t words, int label) { // Read the data all at once. word_t stack_data[words]; size_t bytes_read = backtrace->Read(*sp, reinterpret_cast<uint8_t*>(&stack_data[0]), sizeof(word_t) * words); words = bytes_read / sizeof(word_t); std::string line; for (size_t i = 0; i < words; i++) { word_t stack_content; if (!backtrace->ReadWord(*sp, &stack_content)) { break; line = " "; if (i == 0 && label >= 0) { // Print the label once. line += android::base::StringPrintf("#%02d ", label); } else { line += " "; } line += android::base::StringPrintf("%" PRIPTR " %" PRIPTR, *sp, stack_data[i]); backtrace_map_t map; backtrace->FillInMap(stack_content, &map); std::string map_name; if (BacktraceMap::IsValid(map) && map.name.length() > 0) { map_name = " " + map.name; } backtrace->FillInMap(stack_data[i], &map); if (BacktraceMap::IsValid(map) && !map.name.empty()) { line += " " + map.name; uintptr_t offset = 0; std::string func_name(backtrace->GetFunctionName(stack_content, &offset)); std::string func_name(backtrace->GetFunctionName(stack_data[i], &offset)); if (!func_name.empty()) { if (!i && label >= 0) { line += " (" + func_name; if (offset) { _LOG(log, logtype::STACK, " #%02d %" PRIPTR " %" PRIPTR "%s (%s+%" PRIuPTR ")\n", label, *sp, stack_content, map_name.c_str(), func_name.c_str(), offset); } else { _LOG(log, logtype::STACK, " #%02d %" PRIPTR " %" PRIPTR "%s (%s)\n", label, *sp, stack_content, map_name.c_str(), func_name.c_str()); line += android::base::StringPrintf("+%" PRIuPTR, offset); } } else { if (offset) { _LOG(log, logtype::STACK, " %" PRIPTR " %" PRIPTR "%s (%s+%" PRIuPTR ")\n", *sp, stack_content, map_name.c_str(), func_name.c_str(), offset); } else { _LOG(log, logtype::STACK, " %" PRIPTR " %" PRIPTR "%s (%s)\n", *sp, stack_content, map_name.c_str(), func_name.c_str()); } } } else { if (!i && label >= 0) { _LOG(log, logtype::STACK, " #%02d %" PRIPTR " %" PRIPTR "%s\n", label, *sp, stack_content, map_name.c_str()); } else { _LOG(log, logtype::STACK, " %" PRIPTR " %" PRIPTR "%s\n", *sp, stack_content, map_name.c_str()); line += ')'; } } _LOG(log, logtype::STACK, "%s\n", line.c_str()); *sp += sizeof(word_t); } Loading Loading @@ -325,44 +318,72 @@ static void dump_stack(Backtrace* backtrace, log_t* log) { } } static void dump_map(log_t* log, const backtrace_map_t* map, bool fault_addr) { _LOG(log, logtype::MAPS, "%s%" PRIPTR "-%" PRIPTR " %c%c%c %7" PRIdPTR "%s\n", (fault_addr? "--->" : " "), map->start, map->end - 1, (map->flags & PROT_READ) ? 'r' : '-', (map->flags & PROT_WRITE) ? 'w' : '-', (map->flags & PROT_EXEC) ? 'x' : '-', (map->end - map->start), (map->name.length() > 0) ? (" " + map->name).c_str() : ""); } static void dump_all_maps(BacktraceMap* map, log_t* log, pid_t tid) { bool has_fault_address = false; static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, pid_t tid) { bool print_fault_address_marker = false; uintptr_t addr = 0; siginfo_t si; memset(&si, 0, sizeof(si)); if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si)) { _LOG(log, logtype::MAPS, "cannot get siginfo for %d: %s\n", tid, strerror(errno)); _LOG(log, logtype::ERROR, "cannot get siginfo for %d: %s\n", tid, strerror(errno)); } else { has_fault_address = signal_has_si_addr(si.si_signo); print_fault_address_marker = signal_has_si_addr(si.si_signo); addr = reinterpret_cast<uintptr_t>(si.si_addr); } _LOG(log, logtype::MAPS, "\nmemory map:%s\n", has_fault_address ? " (fault address prefixed with --->)" : ""); if (has_fault_address && (addr < map->begin()->start)) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " before any mapped regions\n", addr); _LOG(log, logtype::MAPS, "\n"); if (!print_fault_address_marker) { _LOG(log, logtype::MAPS, "memory map:\n"); } else { _LOG(log, logtype::MAPS, "memory map: (fault address prefixed with --->)\n"); if (map->begin() != map->end() && addr < map->begin()->start) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " before any mapped regions\n", addr); print_fault_address_marker = false; } } BacktraceMap::const_iterator prev = map->begin(); std::string line; for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) { if (addr >= (*prev).end && addr < (*it).start) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " between mapped regions\n", addr); line = " "; if (print_fault_address_marker) { if (addr < it->start) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " between mapped regions\n", addr); print_fault_address_marker = false; } else if (addr >= it->start && addr < it->end) { line = "--->"; print_fault_address_marker = false; } } line += android::base::StringPrintf("%" PRIPTR "-%" PRIPTR " ", it->start, it->end - 1); if (it->flags & PROT_READ) { line += 'r'; } else { line += '-'; } if (it->flags & PROT_WRITE) { line += 'w'; } else { line += '-'; } if (it->flags & PROT_EXEC) { line += 'x'; } else { line += '-'; } line += android::base::StringPrintf(" %8" PRIxPTR, it->end - it->start); if (it->name.length() > 0) { line += " " + it->name; std::string build_id; if ((it->flags & PROT_READ) && elf_get_build_id(backtrace, it->start, &build_id)) { line += " (BuildId: " + build_id + ")"; } } prev = it; bool in_map = has_fault_address && (addr >= (*it).start) && (addr < (*it).end); dump_map(log, &*it, in_map); _LOG(log, logtype::MAPS, "%s\n", line.c_str()); } if (has_fault_address && (addr >= (*prev).end)) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " after any mapped regions\n", addr); if (print_fault_address_marker) { _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " after any mapped regions\n", addr); } } Loading Loading @@ -627,7 +648,7 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, int si_code dump_backtrace_and_stack(backtrace.get(), log); } dump_memory_and_code(log, tid); dump_all_maps(map.get(), log, tid); dump_all_maps(backtrace.get(), map.get(), log, tid); if (want_logs) { dump_logs(log, pid, 5); Loading