1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_DEBUG_ASAN_SERVICE_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_DEBUG_ASAN_SERVICE_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER) 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <string> 11*6777b538SAndroid Build Coastguard Worker #include <vector> 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h" 16*6777b538SAndroid Build Coastguard Worker #include "base/thread_annotations.h" 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker namespace base { 19*6777b538SAndroid Build Coastguard Worker namespace debug { 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker // This implements an abstraction layer for the parts of the AddressSanitizer 22*6777b538SAndroid Build Coastguard Worker // API used to receive callbacks during crash handling. This is used to add 23*6777b538SAndroid Build Coastguard Worker // application-specific information into the AddressSanitizer error messages 24*6777b538SAndroid Build Coastguard Worker // to assist with debugging, and to filter known false-positive crashes during 25*6777b538SAndroid Build Coastguard Worker // fuzz testing. 26*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT AsanService { 27*6777b538SAndroid Build Coastguard Worker public: 28*6777b538SAndroid Build Coastguard Worker // We can't use a base::Callback type here as we need execution of these 29*6777b538SAndroid Build Coastguard Worker // callbacks to be as simple as possible. 30*6777b538SAndroid Build Coastguard Worker // 31*6777b538SAndroid Build Coastguard Worker // `reason` points to a string containing the AddressSanitizer error report. 32*6777b538SAndroid Build Coastguard Worker // `should_exit_cleanly` should be set to true only if the callback determines 33*6777b538SAndroid Build Coastguard Worker // that this crash is known to be safe - this will override the normal ASan 34*6777b538SAndroid Build Coastguard Worker // behaviour and instead exit cleanly. If your callback is modifying this 35*6777b538SAndroid Build Coastguard Worker // parameter, it should log a message explaining why this error is known to 36*6777b538SAndroid Build Coastguard Worker // be safe. 37*6777b538SAndroid Build Coastguard Worker using ErrorCallback = void (*)(const char* reason, bool* should_exit_cleanly); 38*6777b538SAndroid Build Coastguard Worker 39*6777b538SAndroid Build Coastguard Worker static AsanService* GetInstance(); 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Worker // Registers the global AddressSanitizer error report callback. Any callbacks 42*6777b538SAndroid Build Coastguard Worker // registered by calls to AddErrorCallback will become active after this is 43*6777b538SAndroid Build Coastguard Worker // complete. Safe to call from any thread, and safe to call multiple times. 44*6777b538SAndroid Build Coastguard Worker void Initialize() LOCKS_EXCLUDED(lock_); 45*6777b538SAndroid Build Coastguard Worker 46*6777b538SAndroid Build Coastguard Worker // Writes a message to the same log as AddressSanitizer. This should be used 47*6777b538SAndroid Build Coastguard Worker // for logging inside callbacks. Safe to call from any thread. 48*6777b538SAndroid Build Coastguard Worker void Log(const char* format, ...); 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard Worker // Adds an error callback that will be called on the faulting thread when 51*6777b538SAndroid Build Coastguard Worker // Address Sanitizer detects an error. All registered callbacks are called 52*6777b538SAndroid Build Coastguard Worker // for every error. Safe to call from any thread, and the callback registered 53*6777b538SAndroid Build Coastguard Worker // must also be safe to call from any thread. 54*6777b538SAndroid Build Coastguard Worker void AddErrorCallback(ErrorCallback error_callback) LOCKS_EXCLUDED(lock_); 55*6777b538SAndroid Build Coastguard Worker 56*6777b538SAndroid Build Coastguard Worker private: 57*6777b538SAndroid Build Coastguard Worker friend class AsanServiceTest; 58*6777b538SAndroid Build Coastguard Worker friend class base::NoDestructor<AsanService>; 59*6777b538SAndroid Build Coastguard Worker 60*6777b538SAndroid Build Coastguard Worker AsanService(); 61*6777b538SAndroid Build Coastguard Worker ~AsanService() = delete; 62*6777b538SAndroid Build Coastguard Worker 63*6777b538SAndroid Build Coastguard Worker void RunErrorCallbacks(const char* reason) LOCKS_EXCLUDED(lock_); 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker // This is the error report entrypoint function that is registered with 66*6777b538SAndroid Build Coastguard Worker // AddressSanitizer. 67*6777b538SAndroid Build Coastguard Worker static void ErrorReportCallback(const char* reason); 68*6777b538SAndroid Build Coastguard Worker 69*6777b538SAndroid Build Coastguard Worker // Guards all of the internal state, so that we can safely handle concurrent 70*6777b538SAndroid Build Coastguard Worker // errors on multiple threads. 71*6777b538SAndroid Build Coastguard Worker Lock lock_; 72*6777b538SAndroid Build Coastguard Worker 73*6777b538SAndroid Build Coastguard Worker // Ensure that we don't try and register callbacks before calling Initialize. 74*6777b538SAndroid Build Coastguard Worker bool is_initialized_ GUARDED_BY(lock_) = false; 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker // The list of currently registered error callbacks. 77*6777b538SAndroid Build Coastguard Worker std::vector<ErrorCallback> error_callbacks_ GUARDED_BY(lock_); 78*6777b538SAndroid Build Coastguard Worker }; 79*6777b538SAndroid Build Coastguard Worker 80*6777b538SAndroid Build Coastguard Worker } // namespace debug 81*6777b538SAndroid Build Coastguard Worker } // namespace base 82*6777b538SAndroid Build Coastguard Worker 83*6777b538SAndroid Build Coastguard Worker #endif // defined(ADDRESS_SANITIZER) 84*6777b538SAndroid Build Coastguard Worker #endif // BASE_DEBUG_ASAN_SERVICE_H_ 85