fdsan: improve diagnostics.
Generate a tombstone instead of just a log message when warning. Also,
don't use async_safe_fatal_va_list when we're not calling abort, as
this will permanently set the abort message.
Test: bionic_unit_tests
Test: setprop debug.fdsan warn; crasher fdsan_file
Change-Id: I2fe271da9004c8fd1f50ad3d8280be254eeaf656
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index df369cc..1ace9b6 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -30,6 +30,7 @@
#include <errno.h>
#include <inttypes.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdatomic.h>
#include <string.h>
@@ -117,20 +118,26 @@
va_list va;
va_start(va, fmt);
- async_safe_fatal_va_list("fdsan", fmt, va);
+ if (error_level == ANDROID_FDSAN_ERROR_LEVEL_FATAL) {
+ async_safe_fatal_va_list("fdsan", fmt, va);
+ } else {
+ async_safe_format_log_va_list(ANDROID_LOG_ERROR, "fdsan", fmt, va);
+ }
va_end(va);
switch (error_level) {
case ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE:
atomic_compare_exchange_strong(&fd_table->error_level, &error_level,
ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
+ case ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS:
+ // DEBUGGER_SIGNAL
+ raise(__SIGRTMIN + 3);
break;
case ANDROID_FDSAN_ERROR_LEVEL_FATAL:
abort();
case ANDROID_FDSAN_ERROR_LEVEL_DISABLED:
- case ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS:
break;
}
}