15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2005, Google Inc.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All Rights Reserved.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: Maxim Lifantsev
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A file to ensure that components of heap leak checker run before
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// all global object constructors and after all global object
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructors.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file must be the last library any binary links against.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Otherwise, the heap checker may not be able to run early enough to
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// catalog all the global objects in your program.  If this happens,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and later in the program you allocate memory and have one of these
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "uncataloged" global objects point to it, the heap checker will
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// consider that allocation to be a leak, even though it's not (since
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the allocated object is reachable from global data and hence "live").
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>      // for abort()
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gperftools/malloc_extension.h>
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A dummy variable to refer from heap-checker.cc.  This is to make
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sure this file is not optimized out by the linker.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool heap_leak_checker_bcad_variable;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void HeapLeakChecker_AfterDestructors();  // in heap-checker.cc
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A helper class to ensure that some components of heap leak checking
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can happen before construction and after destruction
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of all global/static objects.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HeapLeakCheckerGlobalPrePost {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeapLeakCheckerGlobalPrePost() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (count_ == 0) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The 'new int' will ensure that we have run an initial malloc
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // hook, which will set up the heap checker via
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // MallocHook_InitAtFirstAllocation_HeapLeakChecker.  See malloc_hook.cc.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is done in this roundabout fashion in order to avoid self-deadlock
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // if we directly called HeapLeakChecker_BeforeConstructors here.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete new int;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This needs to be called before the first allocation of an STL
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // object, but after libc is done setting up threads (because it
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // calls setenv, which requires a thread-aware errno).  By
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // putting it here, we hope it's the first bit of code executed
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // after the libc global-constructor code.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MallocExtension::Initialize();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++count_;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~HeapLeakCheckerGlobalPrePost() {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (count_ <= 0)  abort();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --count_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (count_ == 0)  HeapLeakChecker_AfterDestructors();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Counter of constructions/destructions of objects of this class
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (just in case there are more than one of them).
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int count_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HeapLeakCheckerGlobalPrePost::count_ = 0;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The early-construction/late-destruction global object.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const HeapLeakCheckerGlobalPrePost heap_leak_checker_global_pre_post;
93