OLD | NEW |
1 // Copyright (c) 2005, Google Inc. | 1 // Copyright (c) 2005, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 class Disabler { | 174 class Disabler { |
175 public: | 175 public: |
176 Disabler(); | 176 Disabler(); |
177 ~Disabler(); | 177 ~Disabler(); |
178 private: | 178 private: |
179 Disabler(const Disabler&); // disallow copy | 179 Disabler(const Disabler&); // disallow copy |
180 void operator=(const Disabler&); // and assign | 180 void operator=(const Disabler&); // and assign |
181 }; | 181 }; |
182 | 182 |
183 // Ignore an object located at 'ptr' (can go at the start or into the object) | 183 // Ignore an object located at 'ptr' (can go at the start or into the object) |
184 // as well as all heap objects (transitively) referenced from it | 184 // as well as all heap objects (transitively) referenced from it for the |
185 // for the purposes of heap leak checking. | 185 // purposes of heap leak checking. Returns 'ptr' so that one can write |
186 // If 'ptr' does not point to an active allocated object | 186 // static T* obj = IgnoreObject(new T(...)); |
187 // at the time of this call, it is ignored; | 187 // |
188 // but if it does, the object must not get deleted from the heap later on. | 188 // If 'ptr' does not point to an active allocated object at the time of this |
| 189 // call, it is ignored; but if it does, the object must not get deleted from |
| 190 // the heap later on. |
189 // | 191 // |
190 // See also HiddenPointer, below, if you need to prevent a pointer from | 192 // See also HiddenPointer, below, if you need to prevent a pointer from |
191 // being traversed by the heap checker but do not wish to transitively | 193 // being traversed by the heap checker but do not wish to transitively |
192 // whitelist objects referenced through it. | 194 // whitelist objects referenced through it. |
193 static void IgnoreObject(const void* ptr); | 195 template <typename T> |
| 196 static T* IgnoreObject(T* ptr) { |
| 197 DoIgnoreObject(static_cast<const void*>(const_cast<const T*>(ptr))); |
| 198 return ptr; |
| 199 } |
194 | 200 |
195 // Undo what an earlier IgnoreObject() call promised and asked to do. | 201 // Undo what an earlier IgnoreObject() call promised and asked to do. |
196 // At the time of this call 'ptr' must point at or inside of an active | 202 // At the time of this call 'ptr' must point at or inside of an active |
197 // allocated object which was previously registered with IgnoreObject(). | 203 // allocated object which was previously registered with IgnoreObject(). |
198 static void UnIgnoreObject(const void* ptr); | 204 static void UnIgnoreObject(const void* ptr); |
199 | 205 |
200 // ----------------------------------------------------------------------- // | 206 // ----------------------------------------------------------------------- // |
201 // Initialization; to be called from main() only. | |
202 | |
203 // Full starting of recommended whole-program checking. | |
204 static void InternalInitStart(); | |
205 | |
206 // ----------------------------------------------------------------------- // | |
207 // Internal types defined in .cc | 207 // Internal types defined in .cc |
208 | 208 |
209 class Allocator; | 209 class Allocator; |
210 struct RangeValue; | 210 struct RangeValue; |
211 | 211 |
212 private: | 212 private: |
213 | 213 |
214 // ----------------------------------------------------------------------- // | 214 // ----------------------------------------------------------------------- // |
215 // Various helpers | 215 // Various helpers |
216 | 216 |
217 // Create the name of the heap profile file. | 217 // Create the name of the heap profile file. |
218 // Should be deleted via Allocator::Free(). | 218 // Should be deleted via Allocator::Free(). |
219 char* MakeProfileNameLocked(); | 219 char* MakeProfileNameLocked(); |
220 | 220 |
221 // Helper for constructors | 221 // Helper for constructors |
222 void Create(const char *name, bool make_start_snapshot); | 222 void Create(const char *name, bool make_start_snapshot); |
223 | 223 |
224 enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE }; | 224 enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE }; |
225 | 225 |
226 // Helper for *NoLeaks and *SameHeap | 226 // Helper for *NoLeaks and *SameHeap |
227 bool DoNoLeaks(ShouldSymbolize should_symbolize); | 227 bool DoNoLeaks(ShouldSymbolize should_symbolize); |
228 | 228 |
| 229 // Helper for NoGlobalLeaks, also called by the global destructor. |
| 230 static bool NoGlobalLeaksMaybeSymbolize(ShouldSymbolize should_symbolize); |
| 231 |
229 // These used to be public, but they are now deprecated. | 232 // These used to be public, but they are now deprecated. |
230 // Will remove entirely when all internal uses are fixed. | 233 // Will remove entirely when all internal uses are fixed. |
231 // In the meantime, use friendship so the unittest can still test them. | 234 // In the meantime, use friendship so the unittest can still test them. |
232 static void* GetDisableChecksStart(); | 235 static void* GetDisableChecksStart(); |
233 static void DisableChecksToHereFrom(const void* start_address); | 236 static void DisableChecksToHereFrom(const void* start_address); |
234 static void DisableChecksIn(const char* pattern); | 237 static void DisableChecksIn(const char* pattern); |
235 friend void RangeDisabledLeaks(); | 238 friend void RangeDisabledLeaks(); |
236 friend void NamedTwoDisabledLeaks(); | 239 friend void NamedTwoDisabledLeaks(); |
237 friend void* RunNamedDisabledLeaks(void*); | 240 friend void* RunNamedDisabledLeaks(void*); |
238 friend void TestHeapLeakCheckerNamedDisabling(); | 241 friend void TestHeapLeakCheckerNamedDisabling(); |
| 242 // TODO(csilvers): remove this one, at least |
239 friend int main(int, char**); | 243 friend int main(int, char**); |
240 | 244 |
241 | 245 |
242 // Helper for DisableChecksIn | 246 // Actually implements IgnoreObject(). |
243 static void DisableChecksInLocked(const char* pattern); | 247 static void DoIgnoreObject(const void* ptr); |
244 | 248 |
245 // Disable checks based on stack trace entry at a depth <= | 249 // Disable checks based on stack trace entry at a depth <= |
246 // max_depth. Used to hide allocations done inside some special | 250 // max_depth. Used to hide allocations done inside some special |
247 // libraries. | 251 // libraries. |
248 static void DisableChecksFromToLocked(const void* start_address, | 252 static void DisableChecksFromToLocked(const void* start_address, |
249 const void* end_address, | 253 const void* end_address, |
250 int max_depth); | 254 int max_depth); |
251 | 255 |
252 // Helper for DoNoLeaks to ignore all objects reachable from all live data | 256 // Helper for DoNoLeaks to ignore all objects reachable from all live data |
253 static void IgnoreAllLiveObjectsLocked(const void* self_stack_top); | 257 static void IgnoreAllLiveObjectsLocked(const void* self_stack_top); |
(...skipping 24 matching lines...) Expand all Loading... |
278 | 282 |
279 // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked | 283 // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked |
280 // to discover and ignore all heap objects | 284 // to discover and ignore all heap objects |
281 // reachable from currently considered live objects | 285 // reachable from currently considered live objects |
282 // (live_objects static global variable in out .cc file). | 286 // (live_objects static global variable in out .cc file). |
283 // "name", "name2" are two strings that we print one after another | 287 // "name", "name2" are two strings that we print one after another |
284 // in a debug message to describe what kind of live object sources | 288 // in a debug message to describe what kind of live object sources |
285 // are being used. | 289 // are being used. |
286 static void IgnoreLiveObjectsLocked(const char* name, const char* name2); | 290 static void IgnoreLiveObjectsLocked(const char* name, const char* name2); |
287 | 291 |
288 // Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially | |
289 // calls DoMainHeapCheck | |
290 static void RunHeapCleanups(); | |
291 | |
292 // Do the overall whole-program heap leak check if needed; | 292 // Do the overall whole-program heap leak check if needed; |
293 // returns true when did the leak check. | 293 // returns true when did the leak check. |
294 static bool DoMainHeapCheck(); | 294 static bool DoMainHeapCheck(); |
295 | 295 |
296 // Type of task for UseProcMapsLocked | 296 // Type of task for UseProcMapsLocked |
297 enum ProcMapsTask { | 297 enum ProcMapsTask { |
298 RECORD_GLOBAL_DATA, | 298 RECORD_GLOBAL_DATA, |
299 DISABLE_LIBRARY_ALLOCS | 299 DISABLE_LIBRARY_ALLOCS |
300 }; | 300 }; |
301 | 301 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 static const void* GetAllocCaller(void* ptr); | 340 static const void* GetAllocCaller(void* ptr); |
341 friend void VerifyHeapProfileTableStackGet(); | 341 friend void VerifyHeapProfileTableStackGet(); |
342 | 342 |
343 // This gets to execute before constructors for all global objects | 343 // This gets to execute before constructors for all global objects |
344 static void BeforeConstructorsLocked(); | 344 static void BeforeConstructorsLocked(); |
345 friend void HeapLeakChecker_BeforeConstructors(); | 345 friend void HeapLeakChecker_BeforeConstructors(); |
346 | 346 |
347 // This gets to execute after destructors for all global objects | 347 // This gets to execute after destructors for all global objects |
348 friend void HeapLeakChecker_AfterDestructors(); | 348 friend void HeapLeakChecker_AfterDestructors(); |
349 | 349 |
| 350 // Full starting of recommended whole-program checking. |
| 351 friend void HeapLeakChecker_InternalInitStart(); |
| 352 |
| 353 // Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially |
| 354 // calls DoMainHeapCheck |
| 355 friend void HeapLeakChecker_RunHeapCleanups(); |
| 356 |
350 // ----------------------------------------------------------------------- // | 357 // ----------------------------------------------------------------------- // |
351 // Member data. | 358 // Member data. |
352 | 359 |
353 class SpinLock* lock_; // to make HeapLeakChecker objects thread-safe | 360 class SpinLock* lock_; // to make HeapLeakChecker objects thread-safe |
354 const char* name_; // our remembered name (we own it) | 361 const char* name_; // our remembered name (we own it) |
355 // NULL means this leak checker is a noop | 362 // NULL means this leak checker is a noop |
356 | 363 |
357 // Snapshot taken when the checker was created. May be NULL | 364 // Snapshot taken when the checker was created. May be NULL |
358 // for the global heap checker object. We use void* instead of | 365 // for the global heap checker object. We use void* instead of |
359 // HeapProfileTable::Snapshot* to avoid including heap-profile-table.h. | 366 // HeapProfileTable::Snapshot* to avoid including heap-profile-table.h. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 // (they run only if we are doing heap leak checking.) | 415 // (they run only if we are doing heap leak checking.) |
409 // 'body' should be the cleanup code to run. 'name' doesn't matter, | 416 // 'body' should be the cleanup code to run. 'name' doesn't matter, |
410 // but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls. | 417 // but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls. |
411 #define REGISTER_HEAPCHECK_CLEANUP(name, body) \ | 418 #define REGISTER_HEAPCHECK_CLEANUP(name, body) \ |
412 namespace { \ | 419 namespace { \ |
413 void heapcheck_cleanup_##name() { body; } \ | 420 void heapcheck_cleanup_##name() { body; } \ |
414 static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \ | 421 static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \ |
415 } | 422 } |
416 | 423 |
417 #endif // BASE_HEAP_CHECKER_H_ | 424 #endif // BASE_HEAP_CHECKER_H_ |
OLD | NEW |