Loading debuggerd/Android.bp +10 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,12 @@ cc_binary { ], } cc_test_library { name: "libcrash_test", defaults: ["debuggerd_defaults"], srcs: ["crash_test.cpp"], } cc_test { name: "debuggerd_test", defaults: ["debuggerd_defaults"], Loading Loading @@ -341,6 +347,10 @@ cc_test { }, }, data: [ ":libcrash_test", ], test_suites: ["device-tests"], } Loading debuggerd/crash_test.cpp 0 → 100644 +21 −0 Original line number Diff line number Diff line /* * Copyright 2021, 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> extern "C" void crash() { *reinterpret_cast<volatile char*>(0xdead) = '1'; } debuggerd/debuggerd_test.cpp +56 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ #include <dirent.h> #include <dlfcn.h> #include <err.h> #include <fcntl.h> #include <malloc.h> Loading @@ -30,6 +31,7 @@ #include <chrono> #include <regex> #include <string> #include <thread> #include <android/fdsan.h> Loading Loading @@ -1510,6 +1512,60 @@ 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) { std::string test_lib(testing::internal::GetArgvs()[0]); auto const value = test_lib.find_last_of('/'); if (value == std::string::npos) { test_lib = "./"; } else { test_lib = test_lib.substr(0, value + 1) + "./"; } test_lib += "libcrash_test.so"; *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); // Copy the shared so to a tempory directory. return system(cp_cmd.c_str()) == 0; } TEST_F(CrasherTest, unreadable_elf) { int intercept_result; unique_fd output_fd; StartProcess([]() { TemporaryDir td; std::string tmp_so_name; if (!CopySharedLibrary(td.path, &tmp_so_name)) { _exit(1); } void* handle = dlopen(tmp_so_name.c_str(), RTLD_NOW); if (handle == nullptr) { _exit(1); } // Delete the original shared library so that we get the warning // about unreadable elf files. if (unlink(tmp_so_name.c_str()) == -1) { _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); ASSERT_MATCH(result, R"(NOTE: Function names and BuildId information is missing )"); } TEST(tombstoned, proto) { const pid_t self = getpid(); unique_fd tombstoned_socket, text_fd, proto_fd; Loading debuggerd/libdebuggerd/tombstone_proto.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -395,6 +395,15 @@ static void dump_thread(Tombstone* tombstone, unwindstack::Unwinder* unwinder, unwinder->LastErrorAddress()); } } else { if (unwinder->elf_from_memory_not_file()) { auto backtrace_note = thread.mutable_backtrace_note(); *backtrace_note->Add() = "Function names and BuildId information is missing for some frames due"; *backtrace_note->Add() = "to unreadable libraries. For unwinds of apps, only shared libraries"; *backtrace_note->Add() = "found under the lib/ directory are readable."; *backtrace_note->Add() = "On this device, run setenforce 0 to make the libraries readable."; } unwinder->SetDisplayBuildID(true); for (const auto& frame : unwinder->frames()) { BacktraceFrame* f = thread.add_current_backtrace(); Loading debuggerd/libdebuggerd/tombstone_proto_to_text.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,10 @@ static void print_thread_backtrace(CallbackType callback, const Tombstone& tombs const Thread& thread, bool should_log) { CBS(""); CB(should_log, "backtrace:"); if (!thread.backtrace_note().empty()) { CB(should_log, " NOTE: %s", android::base::Join(thread.backtrace_note(), "\n NOTE: ").c_str()); } print_backtrace(callback, tombstone, thread.current_backtrace(), should_log); } Loading Loading
debuggerd/Android.bp +10 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,12 @@ cc_binary { ], } cc_test_library { name: "libcrash_test", defaults: ["debuggerd_defaults"], srcs: ["crash_test.cpp"], } cc_test { name: "debuggerd_test", defaults: ["debuggerd_defaults"], Loading Loading @@ -341,6 +347,10 @@ cc_test { }, }, data: [ ":libcrash_test", ], test_suites: ["device-tests"], } Loading
debuggerd/crash_test.cpp 0 → 100644 +21 −0 Original line number Diff line number Diff line /* * Copyright 2021, 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> extern "C" void crash() { *reinterpret_cast<volatile char*>(0xdead) = '1'; }
debuggerd/debuggerd_test.cpp +56 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ #include <dirent.h> #include <dlfcn.h> #include <err.h> #include <fcntl.h> #include <malloc.h> Loading @@ -30,6 +31,7 @@ #include <chrono> #include <regex> #include <string> #include <thread> #include <android/fdsan.h> Loading Loading @@ -1510,6 +1512,60 @@ 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) { std::string test_lib(testing::internal::GetArgvs()[0]); auto const value = test_lib.find_last_of('/'); if (value == std::string::npos) { test_lib = "./"; } else { test_lib = test_lib.substr(0, value + 1) + "./"; } test_lib += "libcrash_test.so"; *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); // Copy the shared so to a tempory directory. return system(cp_cmd.c_str()) == 0; } TEST_F(CrasherTest, unreadable_elf) { int intercept_result; unique_fd output_fd; StartProcess([]() { TemporaryDir td; std::string tmp_so_name; if (!CopySharedLibrary(td.path, &tmp_so_name)) { _exit(1); } void* handle = dlopen(tmp_so_name.c_str(), RTLD_NOW); if (handle == nullptr) { _exit(1); } // Delete the original shared library so that we get the warning // about unreadable elf files. if (unlink(tmp_so_name.c_str()) == -1) { _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); ASSERT_MATCH(result, R"(NOTE: Function names and BuildId information is missing )"); } TEST(tombstoned, proto) { const pid_t self = getpid(); unique_fd tombstoned_socket, text_fd, proto_fd; Loading
debuggerd/libdebuggerd/tombstone_proto.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -395,6 +395,15 @@ static void dump_thread(Tombstone* tombstone, unwindstack::Unwinder* unwinder, unwinder->LastErrorAddress()); } } else { if (unwinder->elf_from_memory_not_file()) { auto backtrace_note = thread.mutable_backtrace_note(); *backtrace_note->Add() = "Function names and BuildId information is missing for some frames due"; *backtrace_note->Add() = "to unreadable libraries. For unwinds of apps, only shared libraries"; *backtrace_note->Add() = "found under the lib/ directory are readable."; *backtrace_note->Add() = "On this device, run setenforce 0 to make the libraries readable."; } unwinder->SetDisplayBuildID(true); for (const auto& frame : unwinder->frames()) { BacktraceFrame* f = thread.add_current_backtrace(); Loading
debuggerd/libdebuggerd/tombstone_proto_to_text.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,10 @@ static void print_thread_backtrace(CallbackType callback, const Tombstone& tombs const Thread& thread, bool should_log) { CBS(""); CB(should_log, "backtrace:"); if (!thread.backtrace_note().empty()) { CB(should_log, " NOTE: %s", android::base::Join(thread.backtrace_note(), "\n NOTE: ").c_str()); } print_backtrace(callback, tombstone, thread.current_backtrace(), should_log); } Loading