@@ -33,17 +33,12 @@ SpinLock sanitizer_lock;
3333std::set<const LifetimeSanitizer*> sanitizer_map;
3434
3535
36- std::atomic<bool > LifetimeSanitizer_enabled (true );
37- bool LifetimeSanitizer_has_been_disabled = false ;
36+ std::atomic<bool > LifetimeSanitizer_disabled (false );
3837
39- void LifetimeSanitizer::set_enabled (bool enabled){
40- if (enabled){
41- LifetimeSanitizer_enabled.store (true , std::memory_order_relaxed);
42- return ;
43- }
38+ void LifetimeSanitizer::disable (){
4439 WriteSpinLock lg (sanitizer_lock);
45- LifetimeSanitizer_has_been_disabled = true ;
46- LifetimeSanitizer_enabled. store ( false , std::memory_order_relaxed );
40+ LifetimeSanitizer_disabled. store ( true , std::memory_order_relaxed) ;
41+ sanitizer_map. clear ( );
4742}
4843
4944PA_NO_INLINE void LifetimeSanitizer::terminate_with_dump (){
@@ -60,53 +55,40 @@ PA_NO_INLINE void LifetimeSanitizer::terminate_with_dump(){
6055
6156
6257
63- LifetimeSanitizer::LifetimeSanitizer (const char * name)
64- : m_token(SANITIZER_TOKEN)
65- , m_self(this )
66- , m_name(name)
67- {
68- if (!LifetimeSanitizer_enabled.load (std::memory_order_relaxed)){
58+ LifetimeSanitizer::LifetimeSanitizer (const char * name){
59+ if (LifetimeSanitizer_disabled.load (std::memory_order_relaxed)){
6960 return ;
7061 }
71- internal_construct ();
62+ internal_construct (name );
7263}
7364LifetimeSanitizer::~LifetimeSanitizer (){
74- if (!LifetimeSanitizer_enabled.load (std::memory_order_relaxed)){
75- m_self = nullptr ;
65+ if (LifetimeSanitizer_disabled.load (std::memory_order_relaxed)){
7666 return ;
7767 }
7868 internal_destruct ();
7969}
8070
8171
82- LifetimeSanitizer::LifetimeSanitizer (LifetimeSanitizer&& x)
83- : m_token(SANITIZER_TOKEN)
84- , m_self(this )
85- , m_name(x.m_name)
86- {
87- if (!LifetimeSanitizer_enabled.load (std::memory_order_relaxed)){
72+ LifetimeSanitizer::LifetimeSanitizer (LifetimeSanitizer&& x){
73+ if (LifetimeSanitizer_disabled.load (std::memory_order_relaxed)){
8874 return ;
8975 }
9076 x.check_usage ();
91- internal_construct ();
77+ internal_construct (x. m_name );
9278}
9379void LifetimeSanitizer::operator =(LifetimeSanitizer&& x){
94- if (!LifetimeSanitizer_enabled .load (std::memory_order_relaxed)){
80+ if (LifetimeSanitizer_disabled .load (std::memory_order_relaxed)){
9581 return ;
9682 }
9783 check_usage ();
9884 x.check_usage ();
9985}
100- LifetimeSanitizer::LifetimeSanitizer (const LifetimeSanitizer& x)
101- : m_token(SANITIZER_TOKEN)
102- , m_self(this )
103- , m_name(x.m_name)
104- {
105- if (!LifetimeSanitizer_enabled.load (std::memory_order_relaxed)){
86+ LifetimeSanitizer::LifetimeSanitizer (const LifetimeSanitizer& x){
87+ if (LifetimeSanitizer_disabled.load (std::memory_order_relaxed)){
10688 return ;
10789 }
10890 x.check_usage ();
109- internal_construct ();
91+ internal_construct (x. m_name );
11092}
11193void LifetimeSanitizer::operator =(const LifetimeSanitizer& x){
11294 check_usage ();
@@ -116,72 +98,102 @@ void LifetimeSanitizer::operator=(const LifetimeSanitizer& x){
11698
11799
118100void LifetimeSanitizer::check_usage () const {
119- if (!LifetimeSanitizer_enabled .load (std::memory_order_relaxed)){
101+ if (LifetimeSanitizer_disabled .load (std::memory_order_relaxed)){
120102 return ;
121103 }
122-
123- if (m_token != SANITIZER_TOKEN || m_self != this ){
104+ ReadSpinLock lg (sanitizer_lock);
105+ if (SANITIZER_FILTER.contains (m_name)){
106+ std::cout << " LifetimeSanitizer - Using: " << this << " : " << m_name << std::endl;
107+ }
108+ auto iter = sanitizer_map.find (this );
109+ if (iter == sanitizer_map.end ()){
124110 std::cerr << " Use non-existant: " << this << " : " << m_name << std::endl;
125111 terminate_with_dump ();
126112 }
127-
128- if (LifetimeSanitizer_has_been_disabled){
113+ if (m_token != SANITIZER_TOKEN || m_self != this ){
114+ std::cerr << " Use corrupted: " << this << " : " << m_name << std::endl;
115+ terminate_with_dump ();
116+ }
117+ }
118+ void LifetimeSanitizer::start_using () const {
119+ if (LifetimeSanitizer_disabled.load (std::memory_order_relaxed)){
129120 return ;
130121 }
131-
132122 ReadSpinLock lg (sanitizer_lock);
133123 if (SANITIZER_FILTER.contains (m_name)){
134- std::cout << " LifetimeSanitizer - Using : " << this << " : " << m_name << std::endl;
124+ std::cout << " LifetimeSanitizer - Start using : " << this << " : " << m_name << std::endl;
135125 }
136126 auto iter = sanitizer_map.find (this );
137- if (iter != sanitizer_map.end ()){
138- return ;
127+ if (iter == sanitizer_map.end ()){
128+ std::cerr << " Start using non-existant: " << this << " : " << m_name << std::endl;
129+ terminate_with_dump ();
139130 }
140- std::cerr << " Use non-existant: " << this << " : " << m_name << std::endl;
141- terminate_with_dump ();
131+ if (m_token != SANITIZER_TOKEN || m_self != this ){
132+ std::cerr << " Start using corrupted: " << this << " : " << m_name << std::endl;
133+ terminate_with_dump ();
134+ }
135+ m_use_counter++;
142136}
143-
144-
145- void LifetimeSanitizer::internal_construct (){
146- WriteSpinLock lg (sanitizer_lock);
137+ void LifetimeSanitizer::done_using () const {
138+ if (LifetimeSanitizer_disabled.load (std::memory_order_relaxed)){
139+ return ;
140+ }
141+ ReadSpinLock lg (sanitizer_lock);
147142 if (SANITIZER_FILTER.contains (m_name)){
148- std::cout << " LifetimeSanitizer - Allocating : " << this << " : " << m_name << std::endl;
143+ std::cout << " LifetimeSanitizer - Done using : " << this << " : " << m_name << std::endl;
149144 }
150145 auto iter = sanitizer_map.find (this );
151146 if (iter == sanitizer_map.end ()){
152- sanitizer_map.insert (this );
153- return ;
147+ std::cerr << " Done using non-existant: " << this << " : " << m_name << std::endl;
148+ terminate_with_dump ();
149+ }
150+ if (m_token != SANITIZER_TOKEN || m_self != this ){
151+ std::cerr << " Done using corrupted: " << this << " : " << m_name << std::endl;
152+ terminate_with_dump ();
154153 }
155- std::cerr << " LifetimeSanitizer - Double allocation: " << this << " : " << m_name << std::endl;
156- terminate_with_dump ();
154+ m_use_counter--;
157155}
158- void LifetimeSanitizer::internal_destruct (){
159- void * self = m_self;
160- m_self = nullptr ;
161156
157+
158+ void LifetimeSanitizer::internal_construct (const char * name){
162159 WriteSpinLock lg (sanitizer_lock);
163- if (m_token != SANITIZER_TOKEN || self != this ){
164- std::cerr << " LifetimeSanitizer - Free non-existant: " << this << " : " << m_name << std::endl;
160+ if (SANITIZER_FILTER.contains (name)){
161+ std::cout << " LifetimeSanitizer - Allocating: " << this << " : " << name << std::endl;
162+ }
163+
164+ auto iter = sanitizer_map.find (this );
165+ if (iter != sanitizer_map.end ()){
166+ std::cerr << " LifetimeSanitizer - Double allocation: " << this << " : " << name << std::endl;
165167 terminate_with_dump ();
166168 }
169+ sanitizer_map.insert (this );
167170
171+ m_token = SANITIZER_TOKEN;
172+ m_self = this ;
173+ m_name = name;
174+ }
175+ void LifetimeSanitizer::internal_destruct (){
176+ WriteSpinLock lg (sanitizer_lock);
168177 if (SANITIZER_FILTER.contains (m_name)){
169178 std::cout << " LifetimeSanitizer - Freeing: " << this << " : " << m_name << std::endl;
170179 }
180+
171181 auto iter = sanitizer_map.find (this );
172- if (iter ! = sanitizer_map.end ()){
173- sanitizer_map. erase ( this ) ;
174- return ;
182+ if (iter = = sanitizer_map.end ()){
183+ std::cerr << " LifetimeSanitizer - Free non-existant: " << this << " : " << m_name << std::endl ;
184+ terminate_with_dump () ;
175185 }
186+ sanitizer_map.erase (this );
176187
177- // Skip this check if we've been disabled before in case there's stuff we
178- // haven't tracked.
179- if (LifetimeSanitizer_has_been_disabled){
180- return ;
188+ if (m_token != SANITIZER_TOKEN || m_self != this ){
189+ std::cerr << " LifetimeSanitizer - Free non-existant: " << this << " : " << m_name << std::endl;
190+ terminate_with_dump ();
181191 }
182-
183- std::cerr << " LifetimeSanitizer - Free non-existant: " << this << " : " << m_name << std::endl;
184- terminate_with_dump ();
192+ if (m_use_counter != 0 ){
193+ std::cerr << " LifetimeSanitizer - Freeing while in-use: " << this << " : " << m_name << std::endl;
194+ terminate_with_dump ();
195+ }
196+ m_self = nullptr ;
185197}
186198
187199
0 commit comments