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 {
UnwindImpl(uptr pc,uptr bp,void * context,bool request_fast,u32 max_depth)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:
Decorator()36 Decorator() : SanitizerCommonDecorator() {}
FunctionName() const37 const char *FunctionName() const { return Green(); }
Reason() const38 const char *Reason() const { return Blue(); }
39 };
40 } // namespace
41
GetErrorTypeStr(const DiagnosticsInfo & info)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
PrintError(const Decorator & decorator,const DiagnosticsInfo & info)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
PrintReason(const Decorator & decorator,const DiagnosticsInfo & info)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
PrintDiagnostics(const DiagnosticsInfo & info)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
PrintErrorSummary(const DiagnosticsInfo & info,const BufferedStackTrace & stack)91 void __rtsan::PrintErrorSummary(const DiagnosticsInfo &info,
92 const BufferedStackTrace &stack) {
93 ScopedErrorReportLock::CheckLocked();
94 ReportErrorSummary(GetErrorTypeStr(info), &stack);
95 }
96