Re-add backtrace note about unreadable elf.
When moving to the proto-ized tombstones, the note about unreadable
elf files in a backtrace got lost. This re-adds it and adds a test
to verify that the note properly shows up.
Bug: 185428454
Test: Ran unit tests.
Change-Id: I1150cc737772e1b79fd73ec5c782caadc4629421
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 93725b9..eb3738e 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -15,6 +15,7 @@
*/
#include <dirent.h>
+#include <dlfcn.h>
#include <err.h>
#include <fcntl.h>
#include <malloc.h>
@@ -30,6 +31,7 @@
#include <chrono>
#include <regex>
+#include <string>
#include <thread>
#include <android/fdsan.h>
@@ -1510,6 +1512,60 @@
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;