tombstoned: don't generate tombstones for native backtraces.

Previously, if an intercept ends before we ask for a file descriptor
when doing a backtrace, we'll create a tombstone file instead.

Bug: http://b/114139908
Bug: http://b/115349586
Test: debuggerd_test32
Change-Id: I23c7bb8ae5a982a4374a862d0a4f17bee03eb1d9
This commit is contained in:
Josh Gao 2018-09-12 14:51:03 -07:00
parent 6f9eeecd2b
commit 2b22ae132f
2 changed files with 47 additions and 2 deletions

View file

@ -37,6 +37,7 @@
#include <android-base/macros.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/test_utils.h>
#include <android-base/unique_fd.h>
@ -1053,3 +1054,42 @@ TEST(tombstoned, intercept_any) {
ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
ASSERT_STREQ("any", outbuf);
}
TEST(tombstoned, interceptless_backtrace) {
// Generate 50 backtraces, and then check to see that we haven't created 50 new tombstones.
auto get_tombstone_timestamps = []() -> std::map<int, time_t> {
std::map<int, time_t> result;
for (int i = 0; i < 99; ++i) {
std::string path = android::base::StringPrintf("/data/tombstones/tombstone_%02d", i);
struct stat st;
if (stat(path.c_str(), &st) == 0) {
result[i] = st.st_mtim.tv_sec;
}
}
return result;
};
auto before = get_tombstone_timestamps();
for (int i = 0; i < 50; ++i) {
raise_debugger_signal(kDebuggerdNativeBacktrace);
}
auto after = get_tombstone_timestamps();
int diff = 0;
for (int i = 0; i < 99; ++i) {
if (after.count(i) == 0) {
continue;
}
if (before.count(i) == 0) {
++diff;
continue;
}
if (before[i] != after[i]) {
++diff;
}
}
// We can't be sure that nothing's crash looping in the background.
// This should be good enough, though...
ASSERT_LT(diff, 10) << "too many new tombstones; is something crashing in the background?";
}

View file

@ -212,8 +212,13 @@ static void perform_request(Crash* crash) {
bool intercepted =
intercept_manager->GetIntercept(crash->crash_pid, crash->crash_type, &output_fd);
if (!intercepted) {
std::tie(crash->crash_tombstone_path, output_fd) = CrashQueue::for_crash(crash)->get_output();
crash->crash_tombstone_fd.reset(dup(output_fd.get()));
if (crash->crash_type == kDebuggerdNativeBacktrace) {
// Don't generate tombstones for native backtrace requests.
output_fd.reset(open("/dev/null", O_WRONLY | O_CLOEXEC));
} else {
std::tie(crash->crash_tombstone_path, output_fd) = CrashQueue::for_crash(crash)->get_output();
crash->crash_tombstone_fd.reset(dup(output_fd.get()));
}
}
TombstonedCrashPacket response = {