ATLAS Offline Software
leakcheck.h
Go to the documentation of this file.
1 // This file's extension implies that it's C, but it's really -*- C++ -*-.
2 
3 /*
4  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
5 */
6 
20 #ifndef TESTTOOLS_LEAKCHECK_H
21 #define TESTTOOLS_LEAKCHECK_H
22 
23 // Can't use CxxUtils/checker_macros.h here, since that would be circular dependency.
24 #ifdef ATLAS_GCC_CHECKERS
25 #pragma ATLAS no_check_thread_safety
26 #endif
27 
28 // gcc11 can emit Wmismatched-new-delete for our new/delete
29 // overloads. This is sensitive to optimisations and
30 // particulary inlining.
31 // Specifically, it can inline the delete and not
32 // the new. So it ends up seeing a new matched
33 // with a free.
34 //
35 // We try to disable the diagnostic
36 // and also we try to avoid inlining the functions.
37 //
38 #if __GNUC__ == 11
39 # pragma GCC diagnostic ignored "-Wmismatched-new-delete"
40 #endif
41 
42 
43 
44 #include <malloc.h>
45 #include <unordered_set>
46 #include <iostream>
47 #include <cassert>
48 
49 
50 namespace Athena_test {
51 std::unordered_set<void*>* allocs = nullptr;
53 {
54  LeakCheckDisable() : m_allocs(allocs) { allocs = nullptr; }
56  void insert(void* p) { if (m_allocs) m_allocs->insert(p); }
57  void erase(void* p) { if (m_allocs) m_allocs->erase(p); }
58  std::unordered_set<void*>* m_allocs;
59 };
60 } // namespace Athena_test
61 
62 #if __GNUC__ == 11
63 [[gnu::noinline]]
64 #endif
65 void* newImpl(std::size_t size)
66 {
67  void* ptr = malloc(size);
68  if (Athena_test::allocs) {
70  disable.insert(ptr);
71  }
72  return ptr;
73 }
74 
75 void* operator new(std::size_t size){
76  return newImpl(size);
77 }
78 #if __GNUC__ == 11
79 [[gnu::noinline]]
80 #endif
81 void deleteImpl (void* ptr) noexcept
82 {
83  if (Athena_test::allocs) {
85  disable.erase(ptr);
86  }
87  free(ptr);
88 }
89 
90 void operator delete (void* ptr) noexcept
91 {
92  deleteImpl(ptr);
93 }
94 
95 void operator delete (void* ptr, size_t) noexcept
96 {
97  deleteImpl(ptr);
98 }
99 
100 namespace Athena_test {
101 
102 
103 struct Leakcheck
104 {
106  ~Leakcheck();
107  std::unordered_set<void*>* m_old_allocs;
108  std::unordered_set<void*> m_allocs;
109 };
110 
111 
112 // Not inline; this file should NOT be included in any library.
114 {
116  if (!m_allocs.empty()) {
117  std::cerr << "Leaks!\n";
118  for (void* p : m_allocs)
119  std::cerr << " " << p << "\n";
120  assert (m_allocs.empty());
121  }
122 }
123 
124 
125 } // namespace Athena_test
126 
127 
128 #endif // not TESTTOOLS_LEAKCHECK_H
Athena_test::Leakcheck::m_old_allocs
std::unordered_set< void * > * m_old_allocs
Definition: leakcheck.h:107
Athena_test::Leakcheck::m_allocs
std::unordered_set< void * > m_allocs
Definition: leakcheck.h:108
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
Athena_test::Leakcheck::Leakcheck
Leakcheck()
Definition: leakcheck.h:105
Athena_test::Leakcheck
Definition: leakcheck.h:104
Athena_test::allocs
std::unordered_set< void * > * allocs
Definition: leakcheck.h:51
Athena_test::Leakcheck::~Leakcheck
~Leakcheck()
Definition: leakcheck.h:113
Athena_test::LeakCheckDisable::~LeakCheckDisable
~LeakCheckDisable()
Definition: leakcheck.h:55
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
Athena_test::LeakCheckDisable::erase
void erase(void *p)
Definition: leakcheck.h:57
newImpl
void * newImpl(std::size_t size)
Definition: leakcheck.h:65
Athena_test
functions & macros to test the difference between floats
Definition: InitGaudiGoogleTest.h:30
Athena_test::LeakCheckDisable::LeakCheckDisable
LeakCheckDisable()
Definition: leakcheck.h:54
TrigInDetValidation_Base.malloc
malloc
Definition: TrigInDetValidation_Base.py:129
Athena_test::LeakCheckDisable::insert
void insert(void *p)
Definition: leakcheck.h:56
Athena_test::LeakCheckDisable
Definition: leakcheck.h:53
Athena_test::LeakCheckDisable::m_allocs
std::unordered_set< void * > * m_allocs
Definition: leakcheck.h:58
deleteImpl
void deleteImpl(void *ptr) noexcept
Definition: leakcheck.h:81