[rtsan] Add support for ReportErrorSummary (#116424)
Adding support for the extra SUMMARY line that is output by most compilers. This also adds the ability for end-users to specify their own handlers for reporting these errors (see the test).
This commit is contained in:
@@ -62,8 +62,12 @@ static void OnViolation(const BufferedStackTrace &stack,
|
||||
if (UNLIKELY(is_stack_novel)) {
|
||||
IncrementUniqueErrorCount();
|
||||
|
||||
PrintDiagnostics(info);
|
||||
stack.Print();
|
||||
{
|
||||
ScopedErrorReportLock l;
|
||||
PrintDiagnostics(info);
|
||||
stack.Print();
|
||||
PrintErrorSummary(info, stack);
|
||||
}
|
||||
|
||||
handle.inc_use_count_unsafe();
|
||||
}
|
||||
|
||||
@@ -39,20 +39,22 @@ public:
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static const char *GetErrorTypeStr(const DiagnosticsInfo &info) {
|
||||
switch (info.type) {
|
||||
case DiagnosticsInfoType::InterceptedCall:
|
||||
return "unsafe-library-call";
|
||||
case DiagnosticsInfoType::BlockingCall:
|
||||
return "blocking-call";
|
||||
}
|
||||
CHECK(false);
|
||||
return "(unknown error)";
|
||||
}
|
||||
|
||||
static void PrintError(const Decorator &decorator,
|
||||
const DiagnosticsInfo &info) {
|
||||
const auto ErrorTypeStr = [&info]() -> const char * {
|
||||
switch (info.type) {
|
||||
case DiagnosticsInfoType::InterceptedCall:
|
||||
return "unsafe-library-call";
|
||||
case DiagnosticsInfoType::BlockingCall:
|
||||
return "blocking-call";
|
||||
}
|
||||
return "(unknown error)";
|
||||
};
|
||||
|
||||
Printf("%s", decorator.Error());
|
||||
Report("ERROR: RealtimeSanitizer: %s\n", ErrorTypeStr());
|
||||
Report("ERROR: RealtimeSanitizer: %s\n", GetErrorTypeStr(info));
|
||||
}
|
||||
|
||||
static void PrintReason(const Decorator &decorator,
|
||||
@@ -78,10 +80,16 @@ static void PrintReason(const Decorator &decorator,
|
||||
}
|
||||
|
||||
void __rtsan::PrintDiagnostics(const DiagnosticsInfo &info) {
|
||||
ScopedErrorReportLock l;
|
||||
ScopedErrorReportLock::CheckLocked();
|
||||
|
||||
Decorator d;
|
||||
PrintError(d, info);
|
||||
PrintReason(d, info);
|
||||
Printf("%s", d.Default());
|
||||
}
|
||||
|
||||
void __rtsan::PrintErrorSummary(const DiagnosticsInfo &info,
|
||||
const BufferedStackTrace &stack) {
|
||||
ScopedErrorReportLock::CheckLocked();
|
||||
ReportErrorSummary(GetErrorTypeStr(info), &stack);
|
||||
}
|
||||
|
||||
@@ -30,4 +30,6 @@ struct DiagnosticsInfo {
|
||||
};
|
||||
|
||||
void PrintDiagnostics(const DiagnosticsInfo &info);
|
||||
void PrintErrorSummary(const DiagnosticsInfo &info,
|
||||
const __sanitizer::BufferedStackTrace &stack);
|
||||
} // namespace __rtsan
|
||||
|
||||
32
compiler-rt/test/rtsan/report_error_summary.cpp
Normal file
32
compiler-rt/test/rtsan/report_error_summary.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// RUN: %clangxx -fsanitize=realtime %s -o %t
|
||||
// RUN: %env_rtsan_opts="halt_on_error=false" %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: %clangxx -DTEST_CUSTOM_HANDLER=1 -fsanitize=realtime %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK-CUSTOM-HANDLER
|
||||
|
||||
// UNSUPPORTED: ios
|
||||
|
||||
// Intent: Make sure we support ReporErrorSummary, including custom handlers
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef TEST_CUSTOM_HANDLER
|
||||
extern "C" void __sanitizer_report_error_summary(const char *error_summary) {
|
||||
fprintf(stderr, "%s %s\n", "In custom handler! ", error_summary);
|
||||
}
|
||||
#endif
|
||||
|
||||
int blocking_call() [[clang::blocking]] { return 0; }
|
||||
|
||||
int main() [[clang::nonblocking]] {
|
||||
void *ptr = malloc(2);
|
||||
blocking_call();
|
||||
|
||||
printf("ptr: %p\n", ptr); // ensure we don't optimize out the malloc
|
||||
}
|
||||
|
||||
// CHECK: SUMMARY: RealtimeSanitizer: unsafe-library-call
|
||||
// CHECK: SUMMARY: RealtimeSanitizer: blocking-call
|
||||
|
||||
// CHECK-CUSTOM-HANDLER: In custom handler! SUMMARY: RealtimeSanitizer: unsafe-library-call
|
||||
Reference in New Issue
Block a user