Merge "Change the 64 bit map address format."
This commit is contained in:
commit
493cdcbb77
|
@ -75,46 +75,55 @@ LOCAL_MULTILIB := both
|
|||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
debuggerd_test_src_files := \
|
||||
utility.cpp \
|
||||
test/dump_maps_test.cpp \
|
||||
test/dump_memory_test.cpp \
|
||||
test/elf_fake.cpp \
|
||||
test/log_fake.cpp \
|
||||
test/property_fake.cpp \
|
||||
test/ptrace_fake.cpp \
|
||||
test/selinux_fake.cpp \
|
||||
|
||||
LOCAL_MODULE := debuggerd_test
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
debuggerd_shared_libraries := \
|
||||
libbacktrace \
|
||||
libbase \
|
||||
libcutils \
|
||||
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/test
|
||||
LOCAL_CPPFLAGS := $(common_cppflags)
|
||||
debuggerd_c_includes := \
|
||||
$(LOCAL_PATH)/test \
|
||||
|
||||
debuggerd_cpp_flags := \
|
||||
$(common_cppflags) \
|
||||
-Wno-missing-field-initializers \
|
||||
|
||||
# Only build the host tests on linux.
|
||||
ifeq ($(HOST_OS),linux)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := debuggerd_test
|
||||
LOCAL_SRC_FILES := $(debuggerd_test_src_files)
|
||||
LOCAL_SHARED_LIBRARIES := $(debuggerd_shared_libraries)
|
||||
LOCAL_C_INCLUDES := $(debuggerd_c_includes)
|
||||
LOCAL_CPPFLAGS := $(debuggerd_cpp_flags)
|
||||
|
||||
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
|
||||
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
|
||||
LOCAL_MULTILIB := both
|
||||
|
||||
include $(BUILD_HOST_NATIVE_TEST)
|
||||
|
||||
endif
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
utility.cpp \
|
||||
test/dump_memory_test.cpp \
|
||||
test/log_fake.cpp \
|
||||
|
||||
LOCAL_MODULE := debuggerd_test
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbacktrace \
|
||||
libbase \
|
||||
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/test
|
||||
LOCAL_CPPFLAGS := $(common_cppflags)
|
||||
LOCAL_SRC_FILES := $(debuggerd_test_src_files)
|
||||
LOCAL_SHARED_LIBRARIES := $(debuggerd_shared_libraries)
|
||||
LOCAL_C_INCLUDES := $(debuggerd_c_includes)
|
||||
LOCAL_CPPFLAGS := $(debuggerd_cpp_flags)
|
||||
|
||||
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
|
||||
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
|
||||
LOCAL_MULTILIB := both
|
||||
|
||||
include $(BUILD_NATIVE_TEST)
|
||||
|
|
|
@ -32,6 +32,10 @@ class BacktraceMapMock : public BacktraceMap {
|
|||
public:
|
||||
BacktraceMapMock() : BacktraceMap(0) {}
|
||||
virtual ~BacktraceMapMock() {}
|
||||
|
||||
void AddMap(backtrace_map_t& map) {
|
||||
maps_.push_back(map);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,571 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <base/file.h>
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
#include "BacktraceMock.h"
|
||||
#include "elf_fake.h"
|
||||
#include "host_signal_fixup.h"
|
||||
#include "log_fake.h"
|
||||
#include "ptrace_fake.h"
|
||||
|
||||
// In order to test this code, we need to include the tombstone.cpp code.
|
||||
// Including it, also allows us to override the ptrace function.
|
||||
#define ptrace ptrace_fake
|
||||
|
||||
#include "tombstone.cpp"
|
||||
|
||||
void dump_registers(log_t*, pid_t) {
|
||||
}
|
||||
|
||||
void dump_memory_and_code(log_t*, Backtrace*) {
|
||||
}
|
||||
|
||||
void dump_backtrace_to_log(Backtrace*, log_t*, char const*) {
|
||||
}
|
||||
|
||||
class DumpMapsTest : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
map_mock_.reset(new BacktraceMapMock());
|
||||
backtrace_mock_.reset(new BacktraceMock(map_mock_.get()));
|
||||
|
||||
char tmp_file[256];
|
||||
const char data_template[] = "/data/local/tmp/debuggerd_memory_testXXXXXX";
|
||||
memcpy(tmp_file, data_template, sizeof(data_template));
|
||||
int tombstone_fd = mkstemp(tmp_file);
|
||||
if (tombstone_fd == -1) {
|
||||
const char tmp_template[] = "/tmp/debuggerd_memory_testXXXXXX";
|
||||
memcpy(tmp_file, tmp_template, sizeof(tmp_template));
|
||||
tombstone_fd = mkstemp(tmp_file);
|
||||
if (tombstone_fd == -1) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (unlink(tmp_file) == -1) {
|
||||
abort();
|
||||
}
|
||||
|
||||
log_.tfd = tombstone_fd;
|
||||
log_.amfd = -1;
|
||||
log_.crashed_tid = 12;
|
||||
log_.current_tid = 12;
|
||||
log_.should_retrieve_logcat = false;
|
||||
|
||||
resetLogs();
|
||||
elf_set_fake_build_id("");
|
||||
siginfo_t si;
|
||||
si.si_signo = SIGPIPE;
|
||||
ptrace_set_fake_getsiginfo(si);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
if (log_.tfd >= 0) {
|
||||
close(log_.tfd);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<BacktraceMapMock> map_mock_;
|
||||
std::unique_ptr<BacktraceMock> backtrace_mock_;
|
||||
|
||||
log_t log_;
|
||||
};
|
||||
|
||||
TEST_F(DumpMapsTest, single_map) {
|
||||
backtrace_map_t map;
|
||||
#if defined(__LP64__)
|
||||
map.start = 0x123456789abcd000UL;
|
||||
map.end = 0x123456789abdf000UL;
|
||||
#else
|
||||
map.start = 0x1234000;
|
||||
map.end = 0x1235000;
|
||||
#endif
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"\nmemory map:\n"
|
||||
#if defined(__LP64__)
|
||||
" 12345678'9abcd000-12345678'9abdefff --- 0 12000\n";
|
||||
#else
|
||||
" 01234000-01234fff --- 0 1000\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
TEST_F(DumpMapsTest, single_map_elf_build_id) {
|
||||
backtrace_map_t map;
|
||||
#if defined(__LP64__)
|
||||
map.start = 0x123456789abcd000UL;
|
||||
map.end = 0x123456789abdf000UL;
|
||||
#else
|
||||
map.start = 0x1234000;
|
||||
map.end = 0x1235000;
|
||||
#endif
|
||||
map.flags = PROT_READ;
|
||||
map.name = "/system/lib/libfake.so";
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
elf_set_fake_build_id("abcdef1234567890abcdef1234567890");
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"\nmemory map:\n"
|
||||
#if defined(__LP64__)
|
||||
" 12345678'9abcd000-12345678'9abdefff r-- 0 12000 /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
|
||||
#else
|
||||
" 01234000-01234fff r-- 0 1000 /system/lib/libfake.so (BuildId: abcdef1234567890abcdef1234567890)\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
// Even though build id is present, it should not be printed in either of
|
||||
// these cases.
|
||||
TEST_F(DumpMapsTest, single_map_no_build_id) {
|
||||
backtrace_map_t map;
|
||||
#if defined(__LP64__)
|
||||
map.start = 0x123456789abcd000UL;
|
||||
map.end = 0x123456789abdf000UL;
|
||||
#else
|
||||
map.start = 0x1234000;
|
||||
map.end = 0x1235000;
|
||||
#endif
|
||||
map.flags = PROT_WRITE;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.name = "/system/lib/libfake.so";
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
elf_set_fake_build_id("abcdef1234567890abcdef1234567890");
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"\nmemory map:\n"
|
||||
#if defined(__LP64__)
|
||||
" 12345678'9abcd000-12345678'9abdefff -w- 0 12000\n"
|
||||
" 12345678'9abcd000-12345678'9abdefff -w- 0 12000 /system/lib/libfake.so\n";
|
||||
#else
|
||||
" 01234000-01234fff -w- 0 1000\n"
|
||||
" 01234000-01234fff -w- 0 1000 /system/lib/libfake.so\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
TEST_F(DumpMapsTest, multiple_maps) {
|
||||
backtrace_map_t map;
|
||||
|
||||
map.start = 0xa234000;
|
||||
map.end = 0xa235000;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa334000;
|
||||
map.end = 0xa335000;
|
||||
map.offset = 0xf000;
|
||||
map.flags = PROT_READ;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa434000;
|
||||
map.end = 0xa435000;
|
||||
map.offset = 0x1000;
|
||||
map.load_base = 0xd000;
|
||||
map.flags = PROT_WRITE;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa534000;
|
||||
map.end = 0xa535000;
|
||||
map.offset = 0x3000;
|
||||
map.load_base = 0x2000;
|
||||
map.flags = PROT_EXEC;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa634000;
|
||||
map.end = 0xa635000;
|
||||
map.offset = 0;
|
||||
map.load_base = 0;
|
||||
map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||
map.name = "/system/lib/fake.so";
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"\nmemory map:\n"
|
||||
#if defined(__LP64__)
|
||||
" 00000000'0a234000-00000000'0a234fff --- 0 1000\n"
|
||||
" 00000000'0a334000-00000000'0a334fff r-- f000 1000\n"
|
||||
" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
" 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
|
||||
#else
|
||||
" 0a234000-0a234fff --- 0 1000\n"
|
||||
" 0a334000-0a334fff r-- f000 1000\n"
|
||||
" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
" 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
TEST_F(DumpMapsTest, multiple_maps_fault_address_before) {
|
||||
backtrace_map_t map;
|
||||
|
||||
map.start = 0xa434000;
|
||||
map.end = 0xa435000;
|
||||
map.offset = 0x1000;
|
||||
map.load_base = 0xd000;
|
||||
map.flags = PROT_WRITE;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa534000;
|
||||
map.end = 0xa535000;
|
||||
map.offset = 0x3000;
|
||||
map.load_base = 0x2000;
|
||||
map.flags = PROT_EXEC;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa634000;
|
||||
map.end = 0xa635000;
|
||||
map.offset = 0;
|
||||
map.load_base = 0;
|
||||
map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||
map.name = "/system/lib/fake.so";
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
siginfo_t si;
|
||||
si.si_signo = SIGBUS;
|
||||
si.si_addr = reinterpret_cast<void*>(0x1000);
|
||||
ptrace_set_fake_getsiginfo(si);
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"\nmemory map: (fault address prefixed with --->)\n"
|
||||
#if defined(__LP64__)
|
||||
"--->Fault address falls at 00000000'00001000 before any mapped regions\n"
|
||||
" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
" 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
|
||||
#else
|
||||
"--->Fault address falls at 00001000 before any mapped regions\n"
|
||||
" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
" 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
TEST_F(DumpMapsTest, multiple_maps_fault_address_between) {
|
||||
backtrace_map_t map;
|
||||
|
||||
map.start = 0xa434000;
|
||||
map.end = 0xa435000;
|
||||
map.offset = 0x1000;
|
||||
map.load_base = 0xd000;
|
||||
map.flags = PROT_WRITE;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa534000;
|
||||
map.end = 0xa535000;
|
||||
map.offset = 0x3000;
|
||||
map.load_base = 0x2000;
|
||||
map.flags = PROT_EXEC;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa634000;
|
||||
map.end = 0xa635000;
|
||||
map.offset = 0;
|
||||
map.load_base = 0;
|
||||
map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||
map.name = "/system/lib/fake.so";
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
siginfo_t si;
|
||||
si.si_signo = SIGBUS;
|
||||
si.si_addr = reinterpret_cast<void*>(0xa533000);
|
||||
ptrace_set_fake_getsiginfo(si);
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"\nmemory map: (fault address prefixed with --->)\n"
|
||||
#if defined(__LP64__)
|
||||
" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
"--->Fault address falls at 00000000'0a533000 between mapped regions\n"
|
||||
" 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
|
||||
#else
|
||||
" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
"--->Fault address falls at 0a533000 between mapped regions\n"
|
||||
" 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
TEST_F(DumpMapsTest, multiple_maps_fault_address_in_map) {
|
||||
backtrace_map_t map;
|
||||
|
||||
map.start = 0xa434000;
|
||||
map.end = 0xa435000;
|
||||
map.offset = 0x1000;
|
||||
map.load_base = 0xd000;
|
||||
map.flags = PROT_WRITE;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa534000;
|
||||
map.end = 0xa535000;
|
||||
map.offset = 0x3000;
|
||||
map.load_base = 0x2000;
|
||||
map.flags = PROT_EXEC;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa634000;
|
||||
map.end = 0xa635000;
|
||||
map.offset = 0;
|
||||
map.load_base = 0;
|
||||
map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||
map.name = "/system/lib/fake.so";
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
siginfo_t si;
|
||||
si.si_signo = SIGBUS;
|
||||
si.si_addr = reinterpret_cast<void*>(0xa534040);
|
||||
ptrace_set_fake_getsiginfo(si);
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"\nmemory map: (fault address prefixed with --->)\n"
|
||||
#if defined(__LP64__)
|
||||
" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
"--->00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
|
||||
#else
|
||||
" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
"--->0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
TEST_F(DumpMapsTest, multiple_maps_fault_address_after) {
|
||||
backtrace_map_t map;
|
||||
|
||||
map.start = 0xa434000;
|
||||
map.end = 0xa435000;
|
||||
map.offset = 0x1000;
|
||||
map.load_base = 0xd000;
|
||||
map.flags = PROT_WRITE;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa534000;
|
||||
map.end = 0xa535000;
|
||||
map.offset = 0x3000;
|
||||
map.load_base = 0x2000;
|
||||
map.flags = PROT_EXEC;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
map.start = 0xa634000;
|
||||
map.end = 0xa635000;
|
||||
map.offset = 0;
|
||||
map.load_base = 0;
|
||||
map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||
map.name = "/system/lib/fake.so";
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
siginfo_t si;
|
||||
si.si_signo = SIGBUS;
|
||||
#if defined(__LP64__)
|
||||
si.si_addr = reinterpret_cast<void*>(0x12345a534040UL);
|
||||
#else
|
||||
si.si_addr = reinterpret_cast<void*>(0xf534040UL);
|
||||
#endif
|
||||
ptrace_set_fake_getsiginfo(si);
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"\nmemory map: (fault address prefixed with --->)\n"
|
||||
#if defined(__LP64__)
|
||||
" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
" 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"
|
||||
"--->Fault address falls at 00001234'5a534040 after any mapped regions\n";
|
||||
#else
|
||||
" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"
|
||||
" 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n"
|
||||
" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"
|
||||
"--->Fault address falls at 0f534040 after any mapped regions\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
TEST_F(DumpMapsTest, multiple_maps_getsiginfo_fail) {
|
||||
backtrace_map_t map;
|
||||
|
||||
map.start = 0xa434000;
|
||||
map.end = 0xa435000;
|
||||
map.offset = 0x1000;
|
||||
map.load_base = 0xd000;
|
||||
map.flags = PROT_WRITE;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
siginfo_t si;
|
||||
si.si_signo = 0;
|
||||
ptrace_set_fake_getsiginfo(si);
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
const char* expected_dump = \
|
||||
"Cannot get siginfo for 100: Bad address\n"
|
||||
"\nmemory map:\n"
|
||||
#if defined(__LP64__)
|
||||
" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n";
|
||||
#else
|
||||
" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n";
|
||||
#endif
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("DEBUG Cannot get siginfo for 100: Bad address\n",
|
||||
getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
|
||||
TEST_F(DumpMapsTest, multiple_maps_check_signal_has_si_addr) {
|
||||
backtrace_map_t map;
|
||||
|
||||
map.start = 0xa434000;
|
||||
map.end = 0xa435000;
|
||||
map.flags = PROT_WRITE;
|
||||
map_mock_->AddMap(map);
|
||||
|
||||
for (int i = 1; i < 255; i++) {
|
||||
ASSERT_TRUE(ftruncate(log_.tfd, 0) == 0);
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
|
||||
siginfo_t si;
|
||||
si.si_signo = i;
|
||||
si.si_addr = reinterpret_cast<void*>(0x1000);
|
||||
ptrace_set_fake_getsiginfo(si);
|
||||
dump_all_maps(backtrace_mock_.get(), map_mock_.get(), &log_, 100);
|
||||
|
||||
std::string tombstone_contents;
|
||||
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||
bool has_addr = false;
|
||||
switch (si.si_signo) {
|
||||
case SIGBUS:
|
||||
case SIGFPE:
|
||||
case SIGILL:
|
||||
case SIGSEGV:
|
||||
case SIGTRAP:
|
||||
has_addr = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const char* expected_addr_dump = \
|
||||
"\nmemory map: (fault address prefixed with --->)\n"
|
||||
#if defined(__LP64__)
|
||||
"--->Fault address falls at 00000000'00001000 before any mapped regions\n"
|
||||
" 00000000'0a434000-00000000'0a434fff -w- 0 1000\n";
|
||||
#else
|
||||
"--->Fault address falls at 00001000 before any mapped regions\n"
|
||||
" 0a434000-0a434fff -w- 0 1000\n";
|
||||
#endif
|
||||
const char* expected_dump = \
|
||||
"\nmemory map:\n"
|
||||
#if defined(__LP64__)
|
||||
" 00000000'0a434000-00000000'0a434fff -w- 0 1000\n";
|
||||
#else
|
||||
" 0a434000-0a434fff -w- 0 1000\n";
|
||||
#endif
|
||||
if (has_addr) {
|
||||
ASSERT_STREQ(expected_addr_dump, tombstone_contents.c_str())
|
||||
<< "Signal " << si.si_signo << " expected to include an address.";
|
||||
} else {
|
||||
ASSERT_STREQ(expected_dump, tombstone_contents.c_str())
|
||||
<< "Signal " << si.si_signo << " is not expected to include an address.";
|
||||
}
|
||||
|
||||
// Verify that the log buf is empty, and no error messages.
|
||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
class Backtrace;
|
||||
|
||||
std::string g_build_id;
|
||||
|
||||
void elf_set_fake_build_id(const std::string& build_id) {
|
||||
g_build_id = build_id;
|
||||
}
|
||||
|
||||
bool elf_get_build_id(Backtrace*, uintptr_t, std::string* build_id) {
|
||||
if (g_build_id != "") {
|
||||
*build_id = g_build_id;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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_TEST_ELF_FAKE_H
|
||||
#define _DEBUGGERD_TEST_ELF_FAKE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
void elf_set_fake_build_id(const std::string&);
|
||||
|
||||
#endif // _DEBUGGERD_TEST_ELF_FAKE_H
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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_TEST_HOST_SIGNAL_FIXUP_H
|
||||
#define _DEBUGGERD_TEST_HOST_SIGNAL_FIXUP_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#if !defined(__BIONIC__)
|
||||
|
||||
// In order to compile parts of debuggerd for the host, we need to
|
||||
// define these values.
|
||||
|
||||
#if !defined(NSIGILL)
|
||||
#define NSIGILL ILL_BADSTK
|
||||
#endif
|
||||
|
||||
#if !defined(BUS_MCEERR_AR)
|
||||
#define BUS_MCEERR_AR 4
|
||||
#endif
|
||||
#if !defined(BUS_MCEERR_AO)
|
||||
#define BUS_MCEERR_AO 5
|
||||
#endif
|
||||
#if !defined(NSIGBUS)
|
||||
#define NSIGBUS BUS_MCEERR_AO
|
||||
#endif
|
||||
|
||||
#if !defined(NSIGFPE)
|
||||
#define NSIGFPE FPE_FLTSUB
|
||||
#endif
|
||||
|
||||
#if !defined(NSIGSEGV)
|
||||
#define NSIGSEGV SEGV_ACCERR
|
||||
#endif
|
||||
|
||||
#if !defined(TRAP_BRANCH)
|
||||
#define TRAP_BRANCH 3
|
||||
#endif
|
||||
#if !defined(TRAP_HWBKPT)
|
||||
#define TRAP_HWBKPT 4
|
||||
#endif
|
||||
#if !defined(NSIGTRAP)
|
||||
#define NSIGTRAP TRAP_HWBKPT
|
||||
#endif
|
||||
|
||||
#if !defined(SI_DETHREAD)
|
||||
#define SI_DETHREAD -7
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _DEBUGGERD_TEST_HOST_SIGNAL_FIXUP_H
|
|
@ -19,6 +19,13 @@
|
|||
#include <string>
|
||||
|
||||
#include <base/stringprintf.h>
|
||||
#include <log/log.h>
|
||||
#include <log/logger.h>
|
||||
|
||||
// Forward declarations.
|
||||
class Backtrace;
|
||||
struct EventTagMap;
|
||||
struct AndroidLogEntry;
|
||||
|
||||
std::string g_fake_log_buf;
|
||||
|
||||
|
@ -29,6 +36,14 @@ void resetLogs() {
|
|||
g_fake_log_print = "";
|
||||
}
|
||||
|
||||
std::string getFakeLogBuf() {
|
||||
return g_fake_log_buf;
|
||||
}
|
||||
|
||||
std::string getFakeLogPrint() {
|
||||
return g_fake_log_print;
|
||||
}
|
||||
|
||||
extern "C" int __android_log_buf_write(int, int, const char* tag, const char* msg) {
|
||||
g_fake_log_buf += tag;
|
||||
g_fake_log_buf += ' ';
|
||||
|
@ -36,10 +51,6 @@ extern "C" int __android_log_buf_write(int, int, const char* tag, const char* ms
|
|||
return 1;
|
||||
}
|
||||
|
||||
std::string getFakeLogBuf() {
|
||||
return g_fake_log_buf;
|
||||
}
|
||||
|
||||
extern "C" int __android_log_print(int, const char* tag, const char* fmt, ...) {
|
||||
g_fake_log_print += tag;
|
||||
g_fake_log_print += ' ';
|
||||
|
@ -54,6 +65,27 @@ extern "C" int __android_log_print(int, const char* tag, const char* fmt, ...) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
std::string getFakeLogPrint() {
|
||||
return g_fake_log_print;
|
||||
extern "C" log_id_t android_name_to_log_id(const char*) {
|
||||
return LOG_ID_SYSTEM;
|
||||
}
|
||||
|
||||
extern "C" struct logger_list* android_logger_list_open(log_id_t, int, unsigned int, pid_t) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" int android_logger_list_read(struct logger_list*, struct log_msg*) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" EventTagMap* android_openEventTagMap(const char*) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" int android_log_processBinaryLogBuffer(
|
||||
struct logger_entry*,
|
||||
AndroidLogEntry*, const EventTagMap*, char*, int) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void android_logger_list_free(struct logger_list*) {
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <sys/system_properties.h>
|
||||
|
||||
std::unordered_map<std::string, std::string> g_properties;
|
||||
|
||||
extern "C" int property_set(const char* name, const char* value) {
|
||||
if (g_properties.count(name) != 0) {
|
||||
g_properties.erase(name);
|
||||
}
|
||||
g_properties[name] = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int property_get(const char* key, char* value, const char* default_value) {
|
||||
if (g_properties.count(key) == 0) {
|
||||
if (default_value == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
strncpy(value, default_value, PROP_VALUE_MAX-1);
|
||||
} else {
|
||||
strncpy(value, g_properties[key].c_str(), PROP_VALUE_MAX-1);
|
||||
}
|
||||
value[PROP_VALUE_MAX-1] = '\0';
|
||||
return strlen(value);
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ptrace_fake.h"
|
||||
|
||||
siginfo_t g_fake_si = {.si_signo = 0};
|
||||
|
||||
void ptrace_set_fake_getsiginfo(const siginfo_t& si) {
|
||||
g_fake_si = si;
|
||||
}
|
||||
|
||||
#if !defined(__BIONIC__)
|
||||
extern "C" long ptrace_fake(enum __ptrace_request request, ...) {
|
||||
#else
|
||||
extern "C" long ptrace_fake(int request, ...) {
|
||||
#endif
|
||||
if (request == PTRACE_GETSIGINFO) {
|
||||
if (g_fake_si.si_signo == 0) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, request);
|
||||
va_arg(ap, int);
|
||||
va_arg(ap, int);
|
||||
siginfo_t* si = va_arg(ap, siginfo*);
|
||||
va_end(ap);
|
||||
*si = g_fake_si;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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_TEST_PTRACE_FAKE_H
|
||||
#define _DEBUGGERD_TEST_PTRACE_FAKE_H
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
void ptrace_set_fake_getsiginfo(const siginfo_t&);
|
||||
|
||||
#endif // _DEBUGGERD_TEST_PTRACE_FAKE_H
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
extern "C" int selinux_android_restorecon(const char*, unsigned int) {
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEBUGGERD_TEST_SYS_SYSTEM_PROPERTIES_H
|
||||
#define _DEBUGGERD_TEST_SYS_SYSTEM_PROPERTIES_H
|
||||
|
||||
// This is just enough to get the property code to compile on
|
||||
// the host.
|
||||
|
||||
#define PROP_NAME_MAX 32
|
||||
#define PROP_VALUE_MAX 92
|
||||
|
||||
#endif // _DEBUGGERD_TEST_SYS_SYSTEM_PROPERTIES_H
|
|
@ -317,16 +317,28 @@ static void dump_stack(Backtrace* backtrace, log_t* log) {
|
|||
}
|
||||
}
|
||||
|
||||
static std::string get_addr_string(uintptr_t addr) {
|
||||
std::string addr_str;
|
||||
#if defined(__LP64__)
|
||||
addr_str = android::base::StringPrintf("%08x'%08x",
|
||||
static_cast<uint32_t>(addr >> 32),
|
||||
static_cast<uint32_t>(addr & 0xffffffff));
|
||||
#else
|
||||
addr_str = android::base::StringPrintf("%08x", addr);
|
||||
#endif
|
||||
return addr_str;
|
||||
}
|
||||
|
||||
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::ERROR, "cannot get siginfo for %d: %s\n", tid, strerror(errno));
|
||||
} else {
|
||||
if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) != -1) {
|
||||
print_fault_address_marker = signal_has_si_addr(si.si_signo);
|
||||
addr = reinterpret_cast<uintptr_t>(si.si_addr);
|
||||
} else {
|
||||
_LOG(log, logtype::ERROR, "Cannot get siginfo for %d: %s\n", tid, strerror(errno));
|
||||
}
|
||||
|
||||
_LOG(log, logtype::MAPS, "\n");
|
||||
|
@ -335,8 +347,8 @@ static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, p
|
|||
} 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);
|
||||
_LOG(log, logtype::MAPS, "--->Fault address falls at %s before any mapped regions\n",
|
||||
get_addr_string(addr).c_str());
|
||||
print_fault_address_marker = false;
|
||||
}
|
||||
}
|
||||
|
@ -346,15 +358,15 @@ static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, p
|
|||
line = " ";
|
||||
if (print_fault_address_marker) {
|
||||
if (addr < it->start) {
|
||||
_LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " between mapped regions\n",
|
||||
addr);
|
||||
_LOG(log, logtype::MAPS, "--->Fault address falls at %s between mapped regions\n",
|
||||
get_addr_string(addr).c_str());
|
||||
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);
|
||||
line += get_addr_string(it->start) + '-' + get_addr_string(it->end - 1) + ' ';
|
||||
if (it->flags & PROT_READ) {
|
||||
line += 'r';
|
||||
} else {
|
||||
|
@ -372,7 +384,9 @@ static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, p
|
|||
}
|
||||
line += android::base::StringPrintf(" %8" PRIxPTR " %8" PRIxPTR,
|
||||
it->offset, it->end - it->start);
|
||||
bool space_needed = true;
|
||||
if (it->name.length() > 0) {
|
||||
space_needed = false;
|
||||
line += " " + it->name;
|
||||
std::string build_id;
|
||||
if ((it->flags & PROT_READ) && elf_get_build_id(backtrace, it->start, &build_id)) {
|
||||
|
@ -380,13 +394,16 @@ static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, p
|
|||
}
|
||||
}
|
||||
if (it->load_base != 0) {
|
||||
if (space_needed) {
|
||||
line += ' ';
|
||||
}
|
||||
line += android::base::StringPrintf(" (load base 0x%" PRIxPTR ")", it->load_base);
|
||||
}
|
||||
_LOG(log, logtype::MAPS, "%s\n", line.c_str());
|
||||
}
|
||||
if (print_fault_address_marker) {
|
||||
_LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " after any mapped regions\n",
|
||||
addr);
|
||||
_LOG(log, logtype::MAPS, "--->Fault address falls at %s after any mapped regions\n",
|
||||
get_addr_string(addr).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,13 +33,11 @@
|
|||
#include <string>
|
||||
|
||||
struct backtrace_map_t {
|
||||
backtrace_map_t(): start(0), end(0), flags(0) {}
|
||||
|
||||
uintptr_t start;
|
||||
uintptr_t end;
|
||||
uintptr_t offset;
|
||||
uintptr_t load_base;
|
||||
int flags;
|
||||
uintptr_t start = 0;
|
||||
uintptr_t end = 0;
|
||||
uintptr_t offset = 0;
|
||||
uintptr_t load_base = 0;
|
||||
int flags = 0;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue