[ASan] Add sleep_before_init flag

Also do a little bit of refactoring instead of just copy&paste.

Differential Revision: https://reviews.llvm.org/D126037
This commit is contained in:
Julian Lettner 2022-05-19 17:46:42 -07:00
parent cf348f6a2c
commit ec563c5a90
7 changed files with 35 additions and 28 deletions

View file

@ -83,6 +83,10 @@ ASAN_FLAG(
int, sleep_after_init, 0,
"Number of seconds to sleep after AddressSanitizer is initialized. "
"Useful for debugging purposes (e.g. when one needs to attach gdb).")
ASAN_FLAG(
int, sleep_before_init, 0,
"Number of seconds to sleep before AddressSanitizer starts initializing. "
"Useful for debugging purposes (e.g. when one needs to attach gdb).")
ASAN_FLAG(bool, check_malloc_usable_size, true,
"Allows the users to work around the bug in Nvidia drivers prior to "
"295.*.")

View file

@ -51,10 +51,9 @@ static void AsanDie() {
}
if (common_flags()->print_module_map >= 1)
DumpProcessMap();
if (flags()->sleep_before_dying) {
Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
SleepForSeconds(flags()->sleep_before_dying);
}
WaitForDebugger(flags()->sleep_before_dying, "before dying");
if (flags()->unmap_shadow_on_exit) {
if (kMidMemBeg) {
UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
@ -386,6 +385,8 @@ static void AsanInitInternal() {
// initialization steps look at flags().
InitializeFlags();
WaitForDebugger(flags()->sleep_before_init, "before init");
// Stop performing init at this point if we are being loaded via
// dlopen() and the platform supports it.
if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) {
@ -497,10 +498,7 @@ static void AsanInitInternal() {
VReport(1, "AddressSanitizer Init done\n");
if (flags()->sleep_after_init) {
Report("Sleeping for %d second(s)\n", flags()->sleep_after_init);
SleepForSeconds(flags()->sleep_after_init);
}
WaitForDebugger(flags()->sleep_after_init, "after init");
}
// Initialize as requested from some part of ASan runtime library (interceptors,

View file

@ -351,6 +351,13 @@ void SleepForSeconds(unsigned seconds) {
}
void SleepForMillis(unsigned millis) { internal_usleep((u64)millis * 1000); }
void WaitForDebugger(unsigned seconds, const char *label) {
if (seconds) {
Report("Sleeping for %u second(s) %s\n", seconds, label);
SleepForSeconds(seconds);
}
}
} // namespace __sanitizer
using namespace __sanitizer;

View file

@ -294,6 +294,7 @@ void InitTlsSize();
uptr GetTlsSize();
// Other
void WaitForDebugger(unsigned seconds, const char *label);
void SleepForSeconds(unsigned seconds);
void SleepForMillis(unsigned millis);
u64 NanoTime();

View file

@ -1,10 +0,0 @@
// RUN: %clang_asan -O2 %s -o %t
// RUN: %env_asan_opts=sleep_after_init=1 not %run %t 2>&1 | FileCheck %s
#include <stdlib.h>
int main() {
// CHECK: Sleeping for 1 second
char *x = (char*)malloc(10 * sizeof(char));
free(x);
return x[5];
}

View file

@ -1,10 +0,0 @@
// RUN: %clang_asan -O2 %s -o %t
// RUN: %env_asan_opts=sleep_before_dying=1 not %run %t 2>&1 | FileCheck %s
#include <stdlib.h>
int main() {
char *x = (char*)malloc(10 * sizeof(char));
free(x);
return x[5];
// CHECK: Sleeping for 1 second
}

View file

@ -0,0 +1,17 @@
// RUN: %clang_asan -O2 %s -o %t
// RUN: %env_asan_opts=verbosity=1:sleep_before_init=1:sleep_after_init=1:sleep_before_dying=1 not %run %t 2>&1 | FileCheck %s
#include <stdlib.h>
int main() {
char *x = (char*)malloc(10 * sizeof(char));
free(x);
return x[5];
}
// CHECK: Sleeping for 1 second(s) before init
// CHECK: AddressSanitizer Init done
// CHECK: Sleeping for 1 second(s) after init
// CHECK: ERROR: AddressSanitizer
// CHECK: ABORTING
// CHECK: Sleeping for 1 second(s) before dying