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 // it must also be not already ignored at the time of this call. | 189 // call, it is ignored; but if it does, the object must not get deleted from |
| 190 // the heap later on. |
190 // | 191 // |
191 // 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 |
192 // 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 |
193 // whitelist objects referenced through it. | 194 // whitelist objects referenced through it. |
194 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 } |
195 | 200 |
196 // Undo what an earlier IgnoreObject() call promised and asked to do. | 201 // Undo what an earlier IgnoreObject() call promised and asked to do. |
197 // 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 |
198 // allocated object which was previously registered with IgnoreObject(). | 203 // allocated object which was previously registered with IgnoreObject(). |
199 static void UnIgnoreObject(const void* ptr); | 204 static void UnIgnoreObject(const void* ptr); |
200 | 205 |
201 // ----------------------------------------------------------------------- // | 206 // ----------------------------------------------------------------------- // |
202 // Initialization; to be called from main() only. | |
203 | |
204 // Full starting of recommended whole-program checking. | |
205 static void InternalInitStart(); | |
206 | |
207 // ----------------------------------------------------------------------- // | |
208 // Internal types defined in .cc | 207 // Internal types defined in .cc |
209 | 208 |
210 class Allocator; | 209 class Allocator; |
211 struct RangeValue; | 210 struct RangeValue; |
212 | 211 |
213 private: | 212 private: |
214 | 213 |
215 // ----------------------------------------------------------------------- // | 214 // ----------------------------------------------------------------------- // |
216 // Various helpers | 215 // Various helpers |
217 | 216 |
218 // Create the name of the heap profile file. | 217 // Create the name of the heap profile file. |
219 // Should be deleted via Allocator::Free(). | 218 // Should be deleted via Allocator::Free(). |
220 char* MakeProfileNameLocked(); | 219 char* MakeProfileNameLocked(); |
221 | 220 |
222 // Helper for constructors | 221 // Helper for constructors |
223 void Create(const char *name, bool make_start_snapshot); | 222 void Create(const char *name, bool make_start_snapshot); |
224 | 223 |
225 enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE }; | 224 enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE }; |
226 | 225 |
227 // Helper for *NoLeaks and *SameHeap | 226 // Helper for *NoLeaks and *SameHeap |
228 bool DoNoLeaks(ShouldSymbolize should_symbolize); | 227 bool DoNoLeaks(ShouldSymbolize should_symbolize); |
229 | 228 |
| 229 // Helper for NoGlobalLeaks, also called by the global destructor. |
| 230 static bool NoGlobalLeaksMaybeSymbolize(ShouldSymbolize should_symbolize); |
| 231 |
230 // These used to be public, but they are now deprecated. | 232 // These used to be public, but they are now deprecated. |
231 // Will remove entirely when all internal uses are fixed. | 233 // Will remove entirely when all internal uses are fixed. |
232 // 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. |
233 static void* GetDisableChecksStart(); | 235 static void* GetDisableChecksStart(); |
234 static void DisableChecksToHereFrom(const void* start_address); | 236 static void DisableChecksToHereFrom(const void* start_address); |
235 static void DisableChecksIn(const char* pattern); | 237 static void DisableChecksIn(const char* pattern); |
236 friend void RangeDisabledLeaks(); | 238 friend void RangeDisabledLeaks(); |
237 friend void NamedTwoDisabledLeaks(); | 239 friend void NamedTwoDisabledLeaks(); |
238 friend void* RunNamedDisabledLeaks(void*); | 240 friend void* RunNamedDisabledLeaks(void*); |
239 friend void TestHeapLeakCheckerNamedDisabling(); | 241 friend void TestHeapLeakCheckerNamedDisabling(); |
| 242 // TODO(csilvers): remove this one, at least |
240 friend int main(int, char**); | 243 friend int main(int, char**); |
241 | 244 |
242 | 245 |
243 // Helper for DisableChecksIn | 246 // Actually implements IgnoreObject(). |
244 static void DisableChecksInLocked(const char* pattern); | 247 static void DoIgnoreObject(const void* ptr); |
245 | 248 |
246 // Disable checks based on stack trace entry at a depth <= | 249 // Disable checks based on stack trace entry at a depth <= |
247 // max_depth. Used to hide allocations done inside some special | 250 // max_depth. Used to hide allocations done inside some special |
248 // libraries. | 251 // libraries. |
249 static void DisableChecksFromToLocked(const void* start_address, | 252 static void DisableChecksFromToLocked(const void* start_address, |
250 const void* end_address, | 253 const void* end_address, |
251 int max_depth); | 254 int max_depth); |
252 | 255 |
253 // 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 |
254 static void IgnoreAllLiveObjectsLocked(const void* self_stack_top); | 257 static void IgnoreAllLiveObjectsLocked(const void* self_stack_top); |
(...skipping 24 matching lines...) Expand all Loading... |
279 | 282 |
280 // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked | 283 // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked |
281 // to discover and ignore all heap objects | 284 // to discover and ignore all heap objects |
282 // reachable from currently considered live objects | 285 // reachable from currently considered live objects |
283 // (live_objects static global variable in out .cc file). | 286 // (live_objects static global variable in out .cc file). |
284 // "name", "name2" are two strings that we print one after another | 287 // "name", "name2" are two strings that we print one after another |
285 // 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 |
286 // are being used. | 289 // are being used. |
287 static void IgnoreLiveObjectsLocked(const char* name, const char* name2); | 290 static void IgnoreLiveObjectsLocked(const char* name, const char* name2); |
288 | 291 |
289 // Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially | |
290 // calls DoMainHeapCheck | |
291 static void RunHeapCleanups(); | |
292 | |
293 // Do the overall whole-program heap leak check if needed; | 292 // Do the overall whole-program heap leak check if needed; |
294 // returns true when did the leak check. | 293 // returns true when did the leak check. |
295 static bool DoMainHeapCheck(); | 294 static bool DoMainHeapCheck(); |
296 | 295 |
297 // Type of task for UseProcMapsLocked | 296 // Type of task for UseProcMapsLocked |
298 enum ProcMapsTask { | 297 enum ProcMapsTask { |
299 RECORD_GLOBAL_DATA, | 298 RECORD_GLOBAL_DATA, |
300 DISABLE_LIBRARY_ALLOCS | 299 DISABLE_LIBRARY_ALLOCS |
301 }; | 300 }; |
302 | 301 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 static const void* GetAllocCaller(void* ptr); | 340 static const void* GetAllocCaller(void* ptr); |
342 friend void VerifyHeapProfileTableStackGet(); | 341 friend void VerifyHeapProfileTableStackGet(); |
343 | 342 |
344 // This gets to execute before constructors for all global objects | 343 // This gets to execute before constructors for all global objects |
345 static void BeforeConstructorsLocked(); | 344 static void BeforeConstructorsLocked(); |
346 friend void HeapLeakChecker_BeforeConstructors(); | 345 friend void HeapLeakChecker_BeforeConstructors(); |
347 | 346 |
348 // This gets to execute after destructors for all global objects | 347 // This gets to execute after destructors for all global objects |
349 friend void HeapLeakChecker_AfterDestructors(); | 348 friend void HeapLeakChecker_AfterDestructors(); |
350 | 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 |
351 // ----------------------------------------------------------------------- // | 357 // ----------------------------------------------------------------------- // |
352 // Member data. | 358 // Member data. |
353 | 359 |
354 class SpinLock* lock_; // to make HeapLeakChecker objects thread-safe | 360 class SpinLock* lock_; // to make HeapLeakChecker objects thread-safe |
355 const char* name_; // our remembered name (we own it) | 361 const char* name_; // our remembered name (we own it) |
356 // NULL means this leak checker is a noop | 362 // NULL means this leak checker is a noop |
357 | 363 |
358 // Snapshot taken when the checker was created. May be NULL | 364 // Snapshot taken when the checker was created. May be NULL |
359 // for the global heap checker object. We use void* instead of | 365 // for the global heap checker object. We use void* instead of |
360 // 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... |
409 // (they run only if we are doing heap leak checking.) | 415 // (they run only if we are doing heap leak checking.) |
410 // '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, |
411 // but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls. | 417 // but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls. |
412 #define REGISTER_HEAPCHECK_CLEANUP(name, body) \ | 418 #define REGISTER_HEAPCHECK_CLEANUP(name, body) \ |
413 namespace { \ | 419 namespace { \ |
414 void heapcheck_cleanup_##name() { body; } \ | 420 void heapcheck_cleanup_##name() { body; } \ |
415 static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \ | 421 static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \ |
416 } | 422 } |
417 | 423 |
418 #endif // BASE_HEAP_CHECKER_H_ | 424 #endif // BASE_HEAP_CHECKER_H_ |
OLD | NEW |