Display offset in backtraces if necessary.
When moving to a proto tombstone, backtraces no longer contain an offset when a frame is in a shared library from an apk. Add the offset display again if needed, and add a test to verify this behavior. Bug: 267341682 Test: All unit tests pass. Test: Dumped a process running through an apk to verify the offset Test: is present. Change-Id: Ib720ccb5bfcc8531d1e407f3d01817e8a0b9128c
This commit is contained in:
parent
d34157e26e
commit
22035ccb01
|
@ -36,6 +36,7 @@
|
|||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <android/dlext.h>
|
||||
#include <android/fdsan.h>
|
||||
#include <android/set_abort_message.h>
|
||||
#include <bionic/malloc.h>
|
||||
|
@ -1909,7 +1910,7 @@ TEST_F(CrasherTest, stack_overflow) {
|
|||
ASSERT_MATCH(result, R"(Cause: stack pointer[^\n]*stack overflow.\n)");
|
||||
}
|
||||
|
||||
static bool CopySharedLibrary(const char* tmp_dir, std::string* tmp_so_name) {
|
||||
static std::string GetTestLibraryPath() {
|
||||
std::string test_lib(testing::internal::GetArgvs()[0]);
|
||||
auto const value = test_lib.find_last_of('/');
|
||||
if (value == std::string::npos) {
|
||||
|
@ -1917,7 +1918,62 @@ static bool CopySharedLibrary(const char* tmp_dir, std::string* tmp_so_name) {
|
|||
} else {
|
||||
test_lib = test_lib.substr(0, value + 1) + "./";
|
||||
}
|
||||
test_lib += "libcrash_test.so";
|
||||
return test_lib + "libcrash_test.so";
|
||||
}
|
||||
|
||||
static void CreateEmbeddedLibrary(int out_fd) {
|
||||
std::string test_lib(GetTestLibraryPath());
|
||||
android::base::unique_fd fd(open(test_lib.c_str(), O_RDONLY | O_CLOEXEC));
|
||||
ASSERT_NE(fd.get(), -1);
|
||||
off_t file_size = lseek(fd, 0, SEEK_END);
|
||||
ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
|
||||
std::vector<uint8_t> contents(file_size);
|
||||
ASSERT_TRUE(android::base::ReadFully(fd, contents.data(), contents.size()));
|
||||
|
||||
// Put the shared library data at a pagesize() offset.
|
||||
ASSERT_EQ(lseek(out_fd, 4 * getpagesize(), SEEK_CUR), 4 * getpagesize());
|
||||
ASSERT_EQ(static_cast<size_t>(write(out_fd, contents.data(), contents.size())), contents.size());
|
||||
}
|
||||
|
||||
TEST_F(CrasherTest, non_zero_offset_in_library) {
|
||||
int intercept_result;
|
||||
unique_fd output_fd;
|
||||
TemporaryFile tf;
|
||||
CreateEmbeddedLibrary(tf.fd);
|
||||
StartProcess([&tf]() {
|
||||
android_dlextinfo extinfo{};
|
||||
extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
|
||||
extinfo.library_fd = tf.fd;
|
||||
extinfo.library_fd_offset = 4 * getpagesize();
|
||||
void* handle = android_dlopen_ext(tf.path, RTLD_NOW, &extinfo);
|
||||
if (handle == nullptr) {
|
||||
_exit(1);
|
||||
}
|
||||
void (*crash_func)() = reinterpret_cast<void (*)()>(dlsym(handle, "crash"));
|
||||
if (crash_func == nullptr) {
|
||||
_exit(1);
|
||||
}
|
||||
crash_func();
|
||||
});
|
||||
|
||||
StartIntercept(&output_fd);
|
||||
FinishCrasher();
|
||||
AssertDeath(SIGSEGV);
|
||||
FinishIntercept(&intercept_result);
|
||||
|
||||
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
|
||||
|
||||
std::string result;
|
||||
ConsumeFd(std::move(output_fd), &result);
|
||||
|
||||
// Verify the crash includes an offset value in the backtrace.
|
||||
std::string match_str = android::base::StringPrintf("%s\\!libcrash_test.so \\(offset 0x%x\\)",
|
||||
tf.path, 4 * getpagesize());
|
||||
ASSERT_MATCH(result, match_str);
|
||||
}
|
||||
|
||||
static bool CopySharedLibrary(const char* tmp_dir, std::string* tmp_so_name) {
|
||||
std::string test_lib(GetTestLibraryPath());
|
||||
|
||||
*tmp_so_name = std::string(tmp_dir) + "/libcrash_test.so";
|
||||
std::string cp_cmd = android::base::StringPrintf("cp %s %s", test_lib.c_str(), tmp_dir);
|
||||
|
|
|
@ -176,8 +176,14 @@ static void print_backtrace(CallbackType callback, const Tombstone& tombstone,
|
|||
build_id = StringPrintf(" (BuildId: %s)", frame.build_id().c_str());
|
||||
}
|
||||
|
||||
CB(should_log, " #%02d pc %0*" PRIx64 " %s%s%s", index++, pointer_width(tombstone) * 2,
|
||||
frame.rel_pc(), frame.file_name().c_str(), function.c_str(), build_id.c_str());
|
||||
std::string line =
|
||||
StringPrintf(" #%02d pc %0*" PRIx64 " %s", index++, pointer_width(tombstone) * 2,
|
||||
frame.rel_pc(), frame.file_name().c_str());
|
||||
if (frame.file_map_offset() != 0) {
|
||||
line += StringPrintf(" (offset 0x%" PRIx64 ")", frame.file_map_offset());
|
||||
}
|
||||
line += function + build_id;
|
||||
CB(should_log, "%s", line.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue