xref: /llvm-project/compiler-rt/lib/rtsan/rtsan_diagnostics.cpp (revision 7c41b5ccdcf0f5de1b9b254693635283faff3658)
1 //===--- rtsan_diagnostics.cpp - Realtime Sanitizer -------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #include "rtsan/rtsan_diagnostics.h"
12 
13 #include "sanitizer_common/sanitizer_flags.h"
14 #include "sanitizer_common/sanitizer_report_decorator.h"
15 #include "sanitizer_common/sanitizer_stacktrace.h"
16 
17 using namespace __sanitizer;
18 using namespace __rtsan;
19 
20 // We must define our own implementation of this method for our runtime.
21 // This one is just copied from UBSan.
22 namespace __sanitizer {
23 void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context,
24                                     bool request_fast, u32 max_depth) {
25   uptr top = 0;
26   uptr bottom = 0;
27   GetThreadStackTopAndBottom(false, &top, &bottom);
28   bool fast = StackTrace::WillUseFastUnwind(request_fast);
29   Unwind(max_depth, pc, bp, context, top, bottom, fast);
30 }
31 } // namespace __sanitizer
32 
33 namespace {
34 class Decorator : public SanitizerCommonDecorator {
35 public:
36   Decorator() : SanitizerCommonDecorator() {}
37   const char *FunctionName() const { return Green(); }
38   const char *Reason() const { return Blue(); }
39 };
40 } // namespace
41 
42 static const char *GetErrorTypeStr(const DiagnosticsInfo &info) {
43   switch (info.type) {
44   case DiagnosticsInfoType::InterceptedCall:
45     return "unsafe-library-call";
46   case DiagnosticsInfoType::BlockingCall:
47     return "blocking-call";
48   }
49   CHECK(false);
50   return "(unknown error)";
51 }
52 
53 static void PrintError(const Decorator &decorator,
54                        const DiagnosticsInfo &info) {
55 
56   Printf("%s", decorator.Error());
57   Report("ERROR: RealtimeSanitizer: %s\n", GetErrorTypeStr(info));
58 }
59 
60 static void PrintReason(const Decorator &decorator,
61                         const DiagnosticsInfo &info) {
62   Printf("%s", decorator.Reason());
63 
64   switch (info.type) {
65   case DiagnosticsInfoType::InterceptedCall: {
66     Printf("Intercepted call to real-time unsafe function "
67            "`%s%s%s` in real-time context!",
68            decorator.FunctionName(), info.func_name, decorator.Reason());
69     break;
70   }
71   case DiagnosticsInfoType::BlockingCall: {
72     Printf("Call to blocking function "
73            "`%s%s%s` in real-time context!",
74            decorator.FunctionName(), info.func_name, decorator.Reason());
75     break;
76   }
77   }
78 
79   Printf("\n");
80 }
81 
82 void __rtsan::PrintDiagnostics(const DiagnosticsInfo &info) {
83   ScopedErrorReportLock::CheckLocked();
84 
85   Decorator d;
86   PrintError(d, info);
87   PrintReason(d, info);
88   Printf("%s", d.Default());
89 }
90 
91 void __rtsan::PrintErrorSummary(const DiagnosticsInfo &info,
92                                 const BufferedStackTrace &stack) {
93   ScopedErrorReportLock::CheckLocked();
94   ReportErrorSummary(GetErrorTypeStr(info), &stack);
95 }
96