2727#include " sanitizer_common/sanitizer_placement_new.h"
2828#include " sanitizer_common/sanitizer_stackdepot.h"
2929#include " sanitizer_common/sanitizer_symbolizer.h"
30+ #include " sanitizer_common/sanitizer_thread_safety.h"
3031
3132namespace __asan {
3233
@@ -39,7 +40,7 @@ struct GlobalListNode {
3940typedef IntrusiveList<GlobalListNode> ListOfGlobals;
4041
4142static Mutex mu_for_globals;
42- static ListOfGlobals list_of_all_globals;
43+ static ListOfGlobals list_of_all_globals SANITIZER_GUARDED_BY (mu_for_globals) ;
4344
4445static const int kDynamicInitGlobalsInitialCapacity = 512 ;
4546struct DynInitGlobal {
@@ -48,7 +49,8 @@ struct DynInitGlobal {
4849};
4950typedef InternalMmapVector<DynInitGlobal> VectorOfGlobals;
5051// Lazy-initialized and never deleted.
51- static VectorOfGlobals *dynamic_init_globals;
52+ static VectorOfGlobals *dynamic_init_globals
53+ SANITIZER_GUARDED_BY (mu_for_globals);
5254
5355// We want to remember where a certain range of globals was registered.
5456struct GlobalRegistrationSite {
@@ -58,7 +60,8 @@ struct GlobalRegistrationSite {
5860typedef InternalMmapVector<GlobalRegistrationSite> GlobalRegistrationSiteVector;
5961static GlobalRegistrationSiteVector *global_registration_site_vector;
6062
61- static ListOfGlobals &GlobalsByIndicator (uptr odr_indicator) {
63+ static ListOfGlobals &GlobalsByIndicator (uptr odr_indicator)
64+ SANITIZER_REQUIRES(mu_for_globals) {
6265 using MapOfGlobals = DenseMap<uptr, ListOfGlobals>;
6366
6467 static MapOfGlobals *globals_by_indicator = nullptr ;
@@ -158,7 +161,8 @@ enum GlobalSymbolState {
158161// Check ODR violation for given global G via special ODR indicator. We use
159162// this method in case compiler instruments global variables through their
160163// local aliases.
161- static void CheckODRViolationViaIndicator (const Global *g) {
164+ static void CheckODRViolationViaIndicator (const Global *g)
165+ SANITIZER_REQUIRES(mu_for_globals) {
162166 // Instrumentation requests to skip ODR check.
163167 if (g->odr_indicator == UINTPTR_MAX)
164168 return ;
@@ -185,7 +189,8 @@ static void CheckODRViolationViaIndicator(const Global *g) {
185189// Check ODR violation for given global G by checking if it's already poisoned.
186190// We use this method in case compiler doesn't use private aliases for global
187191// variables.
188- static void CheckODRViolationViaPoisoning (const Global *g) {
192+ static void CheckODRViolationViaPoisoning (const Global *g)
193+ SANITIZER_REQUIRES(mu_for_globals) {
189194 if (__asan_region_is_poisoned (g->beg , g->size_with_redzone )) {
190195 // This check may not be enough: if the first global is much larger
191196 // the entire redzone of the second global may be within the first global.
@@ -223,7 +228,7 @@ static inline bool UseODRIndicator(const Global *g) {
223228// Register a global variable.
224229// This function may be called more than once for every global
225230// so we store the globals in a map.
226- static void RegisterGlobal (const Global *g) {
231+ static void RegisterGlobal (const Global *g) SANITIZER_REQUIRES(mu_for_globals) {
227232 CHECK (AsanInited ());
228233 if (flags ()->report_globals >= 2 )
229234 ReportGlobal (*g, " Added" );
@@ -263,7 +268,8 @@ static void RegisterGlobal(const Global *g) {
263268 }
264269}
265270
266- static void UnregisterGlobal (const Global *g) {
271+ static void UnregisterGlobal (const Global *g)
272+ SANITIZER_REQUIRES(mu_for_globals) {
267273 CHECK (AsanInited ());
268274 if (flags ()->report_globals >= 2 )
269275 ReportGlobal (*g, " Removed" );
@@ -285,8 +291,10 @@ static void UnregisterGlobal(const Global *g) {
285291}
286292
287293void StopInitOrderChecking () {
294+ if (!flags ()->check_initialization_order )
295+ return ;
288296 Lock lock (&mu_for_globals);
289- if (!flags ()-> check_initialization_order || ! dynamic_init_globals)
297+ if (!dynamic_init_globals)
290298 return ;
291299 flags ()->check_initialization_order = false ;
292300 for (uptr i = 0 , n = dynamic_init_globals->size (); i < n; ++i) {
@@ -451,14 +459,14 @@ void __asan_unregister_globals(__asan_global *globals, uptr n) {
451459// poisons all global variables not defined in this TU, so that a dynamic
452460// initializer can only touch global variables in the same TU.
453461void __asan_before_dynamic_init (const char *module_name) {
454- if (!flags ()->check_initialization_order ||
455- !CanPoisonMemory () ||
456- !dynamic_init_globals)
462+ if (!flags ()->check_initialization_order || !CanPoisonMemory ())
457463 return ;
458464 bool strict_init_order = flags ()->strict_init_order ;
459465 CHECK (module_name);
460466 CHECK (AsanInited ());
461467 Lock lock (&mu_for_globals);
468+ if (!dynamic_init_globals)
469+ return ;
462470 if (flags ()->report_globals >= 3 )
463471 Printf (" DynInitPoison module: %s\n " , module_name);
464472 for (uptr i = 0 , n = dynamic_init_globals->size (); i < n; ++i) {
@@ -477,12 +485,12 @@ void __asan_before_dynamic_init(const char *module_name) {
477485// all dynamically initialized globals except for those defined in the current
478486// TU are poisoned. It simply unpoisons all dynamically initialized globals.
479487void __asan_after_dynamic_init () {
480- if (!flags ()->check_initialization_order ||
481- !CanPoisonMemory () ||
482- !dynamic_init_globals)
488+ if (!flags ()->check_initialization_order || !CanPoisonMemory ())
483489 return ;
484490 CHECK (AsanInited ());
485491 Lock lock (&mu_for_globals);
492+ if (!dynamic_init_globals)
493+ return ;
486494 // FIXME: Optionally report that we're unpoisoning globals from a module.
487495 for (uptr i = 0 , n = dynamic_init_globals->size (); i < n; ++i) {
488496 DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
0 commit comments