ATLAS Offline Software
Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | List of all members
AthMemoryAuditor Class Reference

#include <AthMemoryAuditor.h>

Inheritance diagram for AthMemoryAuditor:
Collaboration diagram for AthMemoryAuditor:

Public Member Functions

 AthMemoryAuditor (const std::string &name, ISvcLocator *pSvcLocator)
 Constructor. More...
 
virtual StatusCode initialize () override
 
virtual StatusCode finalize () override
 
virtual void before (StandardEventType evt, INamedInterface *comp) override
 
virtual void after (StandardEventType evt, INamedInterface *comp, const StatusCode &sc) override
 
bool msgLvl (const MSG::Level lvl) const
 Test the output level. More...
 
MsgStream & msg () const
 The standard message stream. More...
 
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream. More...
 
void setLevel (MSG::Level lvl)
 Change the current logging level. More...
 

Static Public Attributes

static bool m_usetcmalloc =true
 

Private Member Functions

void report ()
 
std::string stageToString (long)
 
uint64_t sum (uint32_t a, uint32_t b)
 
MsgStream & msg () const
 The standard message stream. More...
 
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream. More...
 
void initMessaging () const
 Initialize our message level and MessageSvc. More...
 

Private Attributes

bool m_reported
 
int m_stmax
 
int m_defaultStacktraceDepth
 
std::vector< std::string > m_depthPerAlg
 
std::string m_nm
 Message source name. More...
 
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels) More...
 
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer. More...
 
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level. More...
 
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging) More...
 

Detailed Description

Definition at line 30 of file AthMemoryAuditor.h.

Constructor & Destructor Documentation

◆ AthMemoryAuditor()

AthMemoryAuditor::AthMemoryAuditor ( const std::string &  name,
ISvcLocator *  pSvcLocator 
)

Constructor.

Definition at line 42 of file AthMemoryAuditor.cxx.

43  :
44  Auditor ( name, pSvcLocator ),
46  m_reported(true),
47  m_stmax(10),
49 {
50  declareProperty("DefaultStacktraceDepth", m_defaultStacktraceDepth);
51  declareProperty("StacktraceDepthPerAlg", m_depthPerAlg);
52  declareProperty("MaxStacktracesPerAlg", m_stmax);
53  current_stage=1;
54 }

Member Function Documentation

◆ after()

void AthMemoryAuditor::after ( StandardEventType  evt,
INamedInterface *  comp,
const StatusCode &  sc 
)
overridevirtual

Definition at line 687 of file AthMemoryAuditor.cxx.

688 {
689  // Only handle these event types
690  if ( evt!=IAuditor::Initialize && evt!=IAuditor::ReInitialize &&
691  evt!=IAuditor::Execute && evt!=IAuditor::Finalize ) {
692  return;
693  }
694 
695  curIndex=1;
696  stacktraceDepth=m_defaultStacktraceDepth;
697  collectStacktraces=bool(m_defaultStacktraceDepth);
698 }

◆ before()

void AthMemoryAuditor::before ( StandardEventType  evt,
INamedInterface *  comp 
)
overridevirtual

Definition at line 639 of file AthMemoryAuditor.cxx.

640 {
641  // Only handle these event types
642  if ( evt!=IAuditor::Initialize && evt!=IAuditor::ReInitialize &&
643  evt!=IAuditor::Execute && evt!=IAuditor::Finalize ) {
644  return;
645  }
646 
647  context=(uintptr_t)(&(comp->name()));
648 
649  stacktraceDepth=m_defaultStacktraceDepth;
650  auto fit=arrayAlgIndex.find(comp->name());
651  if ( fit == arrayAlgIndex.end() )
652  {
653  // this allocation would show up as memory leak - suppress later printout by setting stage to zero
654  current_stage=0;
655  collectStacktraces=false;
656  arrayAlgIndex[comp->name()]=aiStruct(curIndex= ++curMaxIndex,m_defaultStacktraceDepth);
657  }
658  else
659  {
660  curIndex=fit->second.index;
661  stacktraceDepth=fit->second.stacktrace;
662  }
663  algorithms[curIndex]=comp->name();
664 
665  if (evt==IAuditor::Initialize) {
666  current_stage=3;
667  }
668  else if (evt==IAuditor::ReInitialize) {
669  current_stage=4;
670  collectStacktraces=bool(stacktraceDepth);
671  }
672  else if (evt==IAuditor::Execute) {
673  if(current_stage<1E6)
674  current_stage=1E6;
675  if (context && ( contextFirst == context ) )
676  ++current_stage;
677  if (context && ( contextFirst == 0 ) )
678  contextFirst = context;
679  collectStacktraces=bool(stacktraceDepth);
680  }
681  else if (evt==IAuditor::Finalize) {
682  current_stage=1E8-2;
683  collectStacktraces=bool(stacktraceDepth);
684  }
685 }

◆ finalize()

StatusCode AthMemoryAuditor::finalize ( )
overridevirtual

Definition at line 57 of file AthMemoryAuditor.cxx.

58 {
59  // silence when called outside of athena
60  if ( current_stage > 1 )
61  {
62  if(m_usetcmalloc)
63  uninstall();
64  ATH_MSG_INFO("In finalize");
65  if(!m_reported)
66  {
67  report();
68  m_reported=true;
69  }
70 
71  ATH_MSG_INFO("");
72  ATH_MSG_INFO("Malloc Statistics:");
73  if(m_usetcmalloc)
74  {
75  ATH_MSG_INFO("number of mallocs : " << counter_tc_m);
76  ATH_MSG_INFO("number of frees : " << counter_tc_f);
77  ATH_MSG_INFO(" allocated then freed : " << counter_tc_mtf);
78  ATH_MSG_INFO("mmaped : " << counter_tc_mm);
79  ATH_MSG_INFO("munmaped : " << counter_tc_mum);
80  }
81  else
82  {
83  ATH_MSG_INFO("number of mallocs : " << counter_m);
84  ATH_MSG_INFO("number of frees : " << counter_f);
85  ATH_MSG_INFO(" no associated malloc : " << counter_fna);
86  ATH_MSG_INFO("number of reallocs : " << counter_r);
87  ATH_MSG_INFO(" to shrink : " << counter_rs);
88  ATH_MSG_INFO(" to grow : " << counter_rg);
89  ATH_MSG_INFO(" unknown : " << counter_rnr);
90  ATH_MSG_INFO(" used as malloc : " << counter_rm);
91  ATH_MSG_INFO(" used as free : " << counter_rf);
92  ATH_MSG_INFO("number of memalign : " << counter_ma);
93  }
94  // some memory statistics for debugging
95  if (this->msgLvl(MSG::DEBUG))
96  {
97  std::ifstream infile("/proc/self/status");
98  std::string line;
99  while (std::getline(infile, line))
100  {
102  }
103  }
104  // we are done. When cleaning up itself, crash might occure, so let's not free
105  // anything anymore...
106  finished=true;
107  }
108  return StatusCode::SUCCESS;
109 }

◆ initialize()

StatusCode AthMemoryAuditor::initialize ( )
overridevirtual

Definition at line 111 of file AthMemoryAuditor.cxx.

112 {
113  // Error out if this is a MT job --- we're not thread-safe!
114  ServiceHandle<IInterface> wbsvc ("EventDataSvc", "AthMemoryAuditor");
115  CHECK( wbsvc.retrieve() );
116  if (dynamic_cast<IHiveWhiteBoard*> (wbsvc.get()) != nullptr) {
117  ATH_MSG_ERROR ("AthMemoryAuditor requested in MT job --- not thread safe!");
118  return StatusCode::FAILURE;
119  }
120 
121  current_stage=2;
122 
123  m_reported=false;
124 
125  int l(0);
126  algorithms[l]="N/A";
127  arrayAlgIndex["N/A"]=aiStruct(l,m_defaultStacktraceDepth); ++l;
128  algorithms[l]="'framework'";
129  arrayAlgIndex["'framework'"]=aiStruct(l,m_defaultStacktraceDepth); ++l;
130 
131  stacktraceDepth=m_defaultStacktraceDepth;
132  collectStacktraces=bool(m_defaultStacktraceDepth);
133 
134  ATH_MSG_INFO("==> initialize");
135 
136  for(auto it=m_depthPerAlg.begin(); it!=m_depthPerAlg.end(); ++it )
137  {
138  ATH_MSG_INFO("INIT " << *it);
139  std::istringstream buffer(*it);
140  std::string s;
141  int r=0;
142  buffer >> s >> r;
143  ATH_MSG_INFO("INIT leaks in algorithm " << s << " will have stacktrace depth of " << r );
144  arrayAlgIndex[s]=aiStruct(l,r);
145  algorithms[l]=s;
146  ++l;
147  }
148  curMaxIndex=l-1;
149 
150  // replace test with coe from here
151  // perftest/Control/AthenaAuditors/src/TCMallocAuditor.cxx: MallocExtension::instance()->GetNumericProperty("generic.current_allocated_bytes", &m_value);
152  // TCTEST/Control/AthenaAuditors/src/FPEAuditor.cxx:bool MallocExtension::GetNumericProperty(const char* /* property */, size_t* /* value*/ ) { return true; }
153  // TCTEST/Control/AthenaAuditors/src/FPEAuditor.cxx: MallocExtension::instance()->GetNumericProperty("generic.current_allocated_bytes", &value);
154 
155  if ( ! initialized )
156  {
157  // If tcmalloc is not preloaded this call goes to our implementation which will set m_usetcmalloc to false
159 
160  if(m_usetcmalloc)
161  {
162  ATH_MSG_INFO("Using hooks for tcmalloc");
164  }
165  else
166  {
167  ATH_MSG_INFO("Using hooks for stdcmalloc");
168  ATH_MSG_WARNING("stdcmalloc is currently not well supported, consider using the much faster tcmalloc implementation");
169  my_init_hook();
170  }
171  }
172 
173  return StatusCode::SUCCESS;
174 }

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40 {
42  m_lvl = m_imsg ?
43  static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
44  MSG::INFO;
45 }

◆ msg() [1/4]

MsgStream & AthMessaging::msg
inlineprivate

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 92 of file AthMessaging.h.

165 {
166  MsgStream* ms = m_msg_tls.get();
167  if (!ms) {
168  if (!m_initialized.test_and_set()) initMessaging();
169  ms = new MsgStream(m_imsg,m_nm);
170  m_msg_tls.reset( ms );
171  }
172 
173  ms->setLevel (m_lvl);
174  return *ms;
175 }

◆ msg() [2/4]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 164 of file AthMessaging.h.

165 {
166  MsgStream* ms = m_msg_tls.get();
167  if (!ms) {
168  if (!m_initialized.test_and_set()) initMessaging();
169  ms = new MsgStream(m_imsg,m_nm);
170  m_msg_tls.reset( ms );
171  }
172 
173  ms->setLevel (m_lvl);
174  return *ms;
175 }

◆ msg() [3/4]

MsgStream & AthMessaging::msg
inlineprivate

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 99 of file AthMessaging.h.

180 { return msg() << lvl; }

◆ msg() [4/4]

MsgStream & AthMessaging::msg ( const MSG::Level  lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 179 of file AthMessaging.h.

180 { return msg() << lvl; }

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level  lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152 {
153  if (!m_initialized.test_and_set()) initMessaging();
154  if (m_lvl <= lvl) {
155  msg() << lvl;
156  return true;
157  } else {
158  return false;
159  }
160 }

◆ report()

void AthMemoryAuditor::report ( )
private

Definition at line 176 of file AthMemoryAuditor.cxx.

177 {
178  if ( current_stage > 1 )
179  {
180  current_stage = 0;
181 
182  std::cerr << "AthMemoryAuditor : Creating report\n";
183  std::cerr << "==================================\n";
184 
185  std::cerr << "-------------------------------------------------------------------------------------\n";
186  if(getenv("AtlasBaseDir"))
187  std::cerr << "| AtlasBaseDir : " << std::setw(66) << getenv("AtlasBaseDir") << " |\n";
188  if(getenv("AtlasVersion"))
189  std::cerr << "| AtlasVersion : " << std::setw(66) << getenv("AtlasVersion") << " |\n";
190  if(getenv("CMTCONFIG"))
191  std::cerr << "| CMTCONFIG : " << std::setw(66) << getenv("CMTCONFIG") << " |\n";
192  std::cerr << "-------------------------------------------------------------------------------------\n";
193  std::cerr << " Note: to see line numbers in below stacktrace you might consider running following :\n";
194  std::cerr << " atlasAddress2Line --file <logfile> [--alg <algorithm>]\n";
195  std::cerr << "-------------------------------------------------------------------------------------\n";
196 
197  std::cerr << "Report of summary of leaks\n";
198  std::cerr << "--------------------------\n";
199 
200  std::string str;
201  std::string str0("None");
202 
203  std::vector<unsigned long> leaksInStage(10,0);
204  std::vector<unsigned long> leakedMemInStage(10,0);
205 
206  myBlocks_tc *b=new myBlocks_tc();
207  myBlocks_tc *b2=new myBlocks_tc();
208 
209  struct info
210  {
211  uint32_t total_size;
212  std::vector<allocSet_tc::iterator> l;
213  std::vector<uintptr_t> hash;
214  };
215 
216  std::map<uint32_t,std::map<uint32_t,info> > accum;
217 
218  // first the code for tcmalloc
219  if(m_usetcmalloc)
220  {
221  for( allocSet_tc::iterator it=allocset_tc.begin(); it!=allocset_tc.end(); ++it )
222  {
223  unsigned int reportStage(0);
224  uint32_t stage = it->curstage;
225  size_t size = it->allocsize;
226  uint32_t context = it->algindex;
227  reportStage=stage;
228  if( stage >= 1E6 && stage < 9E7 )
229  reportStage=0;
230  if(stage == 1E6-10 )
231  reportStage=5;
232  if(stage == 9E7 )
233  reportStage=6;
234  if(stage == 1E8-2 )
235  reportStage=7;
236  leaksInStage[reportStage]++;
237  leakedMemInStage[reportStage]+=size;
238 
239  uintptr_t h(0);
240  if (it!=allocset_tc.end())
241  {
242  if(it->allocatedFrom.size()>=2)
243  h=(uintptr_t)it->allocatedFrom[1];
244  for ( unsigned int j = 2; j < it->allocatedFrom.size(); j++)
245  if(it->allocatedFrom[j])
246  h^=(uintptr_t)it->allocatedFrom[j];
247  }
248 
249  accum[stage][context].total_size+=size;
250  accum[stage][context].l.push_back(it);
251  accum[stage][context].hash.push_back(h);
252  }
253  }
254  else
255  {
256  for ( unsigned int reportStage(0); reportStage<8; ++reportStage )
257  {
258  for ( std::map<uint32_t,info>::const_iterator it=accum[reportStage].begin(); it!=accum[reportStage].end(); ++it )
259  std::cerr << " NOW " << it->first << " / " << it->second.total_size << "\n";
260 
261  // accum[stage][context].total_size+=size;
262  }
263  for ( unsigned int reportStage(0); reportStage<8; ++reportStage )
264  {
265  /* std::cerr << "INIT : s_first / s_last " << &s_first << " / " << &s_last << "\n";
266  std::cerr << "INIT : s_first / s_last "
267  << s_first.getNext() << " / " << s_last.getPrev() << "\n"; */
268 
269  node* nf(s_first.getNext());
270  node* np(s_first.getNext());
271  node* nn(s_first.getNext());
272  while ( nf != &s_last )
273  {
274  // std::cerr << "INIT : nf " << nf << "\n";
275  nn=nf->getNext();
276  size_t size = nf->getSize();
277 #if __GNUC__ >= 14
278  // gcc14 warns about the use of redzone here...
279  // when initialized with false, the constructor
280  // deliberately does not initialize anything
281  // (instead reinterpreting the computed pointer).
282 # pragma GCC diagnostic push
283 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
284 #endif
285  redzone *r = new ((void*)((uintptr_t)(nf)+deltaLow+size)) redzone( false );
286  uint32_t stage = r->getStage();
287  uint32_t context = r->getAlgIndex();
288 #if __GNUC__ >= 14
289 # pragma GCC diagnostic pop
290 #endif
291 
292  np=nf;
293  nf=nn;
294 
295  if( reportStage==0 )
296  if( stage < 1E6 || stage >= 9E7 )
297  continue;
298  if(reportStage==1)
299  if(stage != 1 )
300  continue;
301  if(reportStage==2)
302  if(stage != 2 )
303  continue;
304  if(reportStage==3)
305  if(stage != 3 )
306  continue;
307  if(reportStage==4)
308  if(stage != 4 )
309  continue;
310  if(reportStage==5)
311  if(stage != 1E6-10 )
312  continue;
313  if(reportStage==6)
314  if(stage != 9E7 )
315  continue;
316  if(reportStage==7)
317  if(stage != 1E8-2 )
318  continue;
319 
320  leaksInStage[reportStage]++;
321  leakedMemInStage[reportStage]+=size;
322 
323  uintptr_t h(0);
324  b->allocated=(uintptr_t)(np+np->getDeltaPayload());
325  allocSet_tc::iterator it = allocset_tc.find(*b);
326  if (it!=allocset_tc.end())
327  {
328  if(it->allocatedFrom.size()>=2)
329  h=(uintptr_t)it->allocatedFrom[1];
330  for ( unsigned int j = 2; j < it->allocatedFrom.size(); j++)
331  if(it->allocatedFrom[j])
332  h^=(uintptr_t)it->allocatedFrom[j];
333 
334  /* std::cerr << "RS find : "
335  << size << " " << it->allocsize << " | "
336  << stage << " " << it->curstage << "\n"; */
337 
338  it->allocsize = size;
339  it->curstage = stage;
340  // it->context = algindex;
341  }
342 
343  accum[stage][context].total_size+=size;
344  accum[stage][context].l.push_back(it);
345  accum[stage][context].hash.push_back(h);
346  }
347  }
348  }
349 
350  std::cerr << "Summary\n" ;
351  std::cerr << " " << leaksInStage[0] << " Reported leak(s) allocated in event loop, leaking " << leakedMemInStage[0] << " bytes\n";
352  std::cerr << " " << leaksInStage[1] << " Reported leak(s) allocated in constructors, leaking " << leakedMemInStage[1] << " bytes\n";
353  std::cerr << " " << leaksInStage[2] << " Reported leak(s) allocated before initialize, leaking " << leakedMemInStage[2] << " bytes\n";
354  std::cerr << " " << leaksInStage[3] << " Reported leak(s) allocated in initialize, leaking " << leakedMemInStage[3] << " bytes\n";
355  std::cerr << " " << leaksInStage[4] << " Reported leak(s) allocated in re-initialize, leaking " << leakedMemInStage[4] << " bytes\n";
356  std::cerr << " " << leaksInStage[5] << " Reported leak(s) allocated in begin-run, leaking " << leakedMemInStage[5] << " bytes\n";
357  std::cerr << " " << leaksInStage[6] << " Reported leak(s) allocated in end-run, leaking " << leakedMemInStage[6] << " bytes\n";
358  std::cerr << " " << leaksInStage[7] << " Reported leak(s) allocated in finalize, leaking " << leakedMemInStage[7] << " bytes\n";
359 
360  std::cerr << std::dec << "\n";
361 
362  for ( unsigned int reportStage(0); reportStage<8; ++reportStage )
363  {
364  switch(reportStage)
365  {
366  case 0: std::cerr << "Reporting leaks allocated in event loop\n"; break;
367  case 1: std::cerr << "Reporting leaks allocated in constructors\n"; break;
368  case 2: std::cerr << "Reporting leaks allocated before initialize\n"; break;
369  case 3: std::cerr << "Reporting leaks allocated in initialize\n"; break;
370  case 4: std::cerr << "Reporting leaks allocated in re-initialize\n"; break;
371  case 5: std::cerr << "Reporting leaks allocated in begin-run\n"; break;
372  case 6: std::cerr << "Reporting leaks allocated in end-run\n"; break;
373  case 7: std::cerr << "Reporting leaks allocated in finalize\n"; break;
374  }
375  // remember leaks
376  std::map<uint32_t,info> leaks;
377 
378  for(std::map<uint32_t,std::map<uint32_t,info> >::const_iterator outer_iter=accum.begin(); outer_iter!=accum.end(); ++outer_iter)
379  {
380  uint32_t stage = outer_iter->first;
381 
382  if( reportStage==0 )
383  if( stage < 1E6 || stage >= 9E7 )
384  continue;
385  if(reportStage==1)
386  if(stage != 1 )
387  continue;
388  if(reportStage==2)
389  if(stage != 2 )
390  continue;
391  if(reportStage==3)
392  if(stage != 3 )
393  continue;
394  if(reportStage==4)
395  if(stage != 4 )
396  continue;
397  if(reportStage==5)
398  if(stage != 1E6-10 )
399  continue;
400  if(reportStage==6)
401  if(stage != 9E7 )
402  continue;
403  if(reportStage==7)
404  if(stage != 1E8-2 )
405  continue;
406 
407  // add all leaks from this algorithm in this stage (event loop has several) and sort by size
408  for(std::map<uint32_t,info>::const_iterator inner_iter = outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter)
409  {
410  leaks[inner_iter->first].total_size+=inner_iter->second.total_size;
411  leaks[inner_iter->first].l.insert(leaks[inner_iter->first].l.end(), inner_iter->second.l.begin(), inner_iter->second.l.end());
412  leaks[inner_iter->first].hash.insert(leaks[inner_iter->first].hash.end(), inner_iter->second.hash.begin(), inner_iter->second.hash.end());
413  }
414  }
415 
416  // printout, sorted by size of leaks per algorithms in this step, largest first
417  while (! leaks.empty())
418  {
419  auto imax=leaks.begin();
420  for(auto iter=leaks.begin(); iter!=leaks.end(); ++iter)
421  if(imax->second.total_size < iter->second.total_size)
422  imax=iter;
423  uint32_t ai=imax->first;
424  std::map<uint32_t, std::string>::const_iterator ait=algorithms.find(ai);
425  if ( ait != algorithms.end() )
426  str=ait->second;
427  else
428  str=str0;
429  std::cerr << " Accumulated Leak(s) in algorithm " << str << " of total size " << imax->second.total_size << " bytes\n";
430 
431  auto fit=arrayAlgIndex.find(str);
432  if ( fit == arrayAlgIndex.end() )
433  {
434  std::cerr << "something is wrong \n";
435  abort();
436  }
437  else
438  {
439  stacktraceDepth=fit->second.stacktrace;
440  // std::cerr << " ROLF : stacktracesize " << stacktraceDepth << "\n";
441  if(stacktraceDepth > 0 )
442  {
443  std::vector<info> thisAlg;
444 
445  // print at most m_stmax stack traces per algorithm
446  int stmax=m_stmax;
447  for(unsigned int i_tr = 0; i_tr < imax->second.l.size(); ++i_tr )
448  {
449  info leakSum;
450 
451  size_t size = imax->second.l[i_tr]->allocsize;
452  // redzone *r = new ((void*)((uintptr_t)imax->second.l[i_tr]+deltaLow+size)) redzone( false );
453  uint32_t stage = imax->second.l[i_tr]->curstage;
454 
455  leakSum.total_size=size;
456  leakSum.l.push_back(imax->second.l[i_tr]);
457  leakSum.hash.push_back(stage);
458 
459  // std::cerr << " ROLF : stage " << stage << " " << size << "\n";
460 
461  // stage == 0 means, this leak was reported earlier with another leak with same stacktrace
462  if(stage>0)
463  {
464  b->allocated=(uintptr_t)imax->second.l[i_tr]->allocated;
465  allocSet_tc::iterator it = allocset_tc.find(*b);
466  if (it!=allocset_tc.end())
467  {
468  bool same=true;
469  unsigned int i_tr2 = i_tr+1;
470  while ( i_tr2 < imax->second.l.size() )
471  {
472  if ( imax->second.hash[i_tr] == imax->second.hash[i_tr2] )
473  {
474  size = imax->second.l[i_tr2]->allocsize;
475  // redzone *r2 = new ((void*)((uintptr_t)imax->second.l[i_tr2]+deltaLow+size)) redzone( false );
476  stage = imax->second.l[i_tr2]->curstage;
477 
478  if(stage>0)
479  {
480  b2->allocated=(uintptr_t)imax->second.l[i_tr2]->allocated;
481  allocSet_tc::iterator it2 = allocset_tc.find(*b2);
482  if (it2!=allocset_tc.end())
483  {
484  same=true;
485  for ( unsigned int j = 0; j < std::min(it->allocatedFrom.size(),it2->allocatedFrom.size()); j++)
486  if( same && it->allocatedFrom[j] && it2->allocatedFrom[j] )
487  if( it->allocatedFrom[j] != it2->allocatedFrom[j] )
488  same=false;
489  if(same)
490  {
491  // redzone *r2 = new ((void*)((uintptr_t)imax->second.l[i_tr2]+deltaLow+size)) redzone( false );
492  stage = imax->second.l[i_tr2]->curstage;
493 
494  leakSum.total_size+=size;
495  // how many leaks with same stacktrace ?
496  leakSum.l.push_back(imax->second.l[i_tr2]);
497  leakSum.hash.push_back(stage);
498 
499  // set stage to zero to suppress further printout
500  imax->second.l[i_tr2]->curstage=0;
501  }
502  }
503  }
504  }
505  ++i_tr2;
506  }
507 
508  }
509  thisAlg.push_back(leakSum);
510  }
511  }
512 
513  // now printout
514  int nleaks(0);
515  int mleaks(0);
516  uint32_t stage(0);
517 
518  while(thisAlg.size())
519  {
520  auto itmax = thisAlg.end();
521  itmax--;
522  // if(thisAlg.size()%100000==0)
523  // std::cerr << " RS " << thisAlg.size() << "\n";
524 
525  if(stmax>=0)
526  {
527  itmax = thisAlg.begin();
528  for(auto iter=thisAlg.begin(); iter!=thisAlg.end(); ++iter)
529  if(itmax->total_size < iter->total_size)
530  itmax=iter;
531 
532  stage = itmax->hash[0];
533  std::multimap<int,int> here;
534 
535  std::cerr << " " << itmax->l.size() << " leak(s) in algorithm " << str << " allocated in "
536  << stageToString(stage) << " with total size of " << itmax->total_size << " bytes";
537  if(itmax->l.size()>1)
538  {
539  for(auto i = itmax->l.begin(); i != itmax->l.end(); ++i )
540  here.insert(std::pair<int, int>((*i)->allocsize, 1));
541 
542  std::string s("");
543  auto it = here.end(); --it;
544  std::cerr << " (";
545  while( ! here.empty() )
546  {
547  std::cerr << s;
548  if( here.count(it->first) > 1 )
549  std::cerr << here.count(it->first) << "x";
550  std::cerr << it->first;
551  s=",";
552  here.erase(here.lower_bound(it->first),here.end());
553  it = here.end();
554  if ( ! here.empty() ) --it;
555  }
556  std::cerr << ")";
557  }
558  std::cerr << "\n";
559 
560  // print stacktrace
561  // b->allocated=(uintptr_t)itmax->l[0]->allocated;
562  // allocSet::iterator it = allocset.find(*b);
563  allocSet_tc::iterator it = itmax->l[0];
564 
565  // if (it!=allocset.end())
566  for ( unsigned int j = 1; j < it->allocatedFrom.size() ; j++)
567  {
568  if(it->allocatedFrom[j])
569  {
570  fprintf(stderr,"%7u ",j);
571  Dl_info info;
572  ptrdiff_t relative_address(0);
573  const char *libname = "N/A";
574  if (dladdr (it->allocatedFrom[j], &info) && info.dli_fname && info.dli_fname[0])
575  {
576  libname = info.dli_fname;
577  // difference of two pointers
578  uintptr_t p1=(uintptr_t)it->allocatedFrom[j];
579  uintptr_t p2=(uintptr_t)info.dli_fbase;
580  relative_address = (p1 > p2) ? p1 - p2 : p2 - p1;
581  if (strstr (info.dli_fname, ".so") == 0)
582  relative_address = p1;
583  }
584  fprintf(stderr," %s D[%p]\n",libname,(void*)relative_address);
585  }
586  }
587  }
588  else
589  {
590  nleaks++;
591  mleaks+=itmax->total_size;
592  }
593 
594  --stmax;
595 
596  thisAlg.erase(itmax);
597  }
598  if(nleaks>1)
599  std::cerr << " further " << nleaks << " leak(s) in algorithm " << str << " allocated in "
600  << stageToString(stage) << " with total size of " << mleaks << " bytes\n";
601 
602  }
603  }
604 
605  leaks.erase(imax);
606  }
607  }
608  // delete b;
609  // delete b2;
610 
611  }
612 }

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level  lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29 {
30  m_lvl = lvl;
31 }

◆ stageToString()

std::string AthMemoryAuditor::stageToString ( long  s)
private

Definition at line 614 of file AthMemoryAuditor.cxx.

615 {
616  std::string str("N/A");
617 
618  if( s >= 1E6 && s < 9E7 )
619  {
620  str="Event "; str+=std::to_string(s-1E6);
621  }
622  if( s == 1 )
623  str="Constructorx";
624  if( s == 2 )
625  str="before initialize";
626  if( s == 3 )
627  str="initialize";
628  if( s == 4 )
629  str="re-initialize";
630  if( s == 1E6-10 )
631  str="begin-run";
632  if( s == 9E7 )
633  str="end-run";
634  if( s == 1E8-2 )
635  str="finalize";
636  return str;
637 }

◆ sum()

uint64_t AthMemoryAuditor::sum ( uint32_t  a,
uint32_t  b 
)
inlineprivate

Definition at line 57 of file AthMemoryAuditor.h.

57 { return ((((uint64_t)a)<<32) + b); };

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging)

Definition at line 141 of file AthMessaging.h.

◆ m_defaultStacktraceDepth

int AthMemoryAuditor::m_defaultStacktraceDepth
private

Definition at line 52 of file AthMemoryAuditor.h.

◆ m_depthPerAlg

std::vector<std::string> AthMemoryAuditor::m_depthPerAlg
private

Definition at line 53 of file AthMemoryAuditor.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_reported

bool AthMemoryAuditor::m_reported
private

Definition at line 50 of file AthMemoryAuditor.h.

◆ m_stmax

int AthMemoryAuditor::m_stmax
private

Definition at line 51 of file AthMemoryAuditor.h.

◆ m_usetcmalloc

bool AthMemoryAuditor::m_usetcmalloc =true
static

Definition at line 46 of file AthMemoryAuditor.h.


The documentation for this class was generated from the following files:
grepfile.info
info
Definition: grepfile.py:38
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
AthMessaging::m_lvl
std::atomic< MSG::Level > m_lvl
Current logging level.
Definition: AthMessaging.h:138
plotting.yearwise_luminosity_vs_mu.comp
comp
Definition: yearwise_luminosity_vs_mu.py:23
beamspotman.r
def r
Definition: beamspotman.py:676
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
checkFileSG.line
line
Definition: checkFileSG.py:75
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
run.infile
string infile
Definition: run.py:13
python.FPGATrackSimAnalysisConfig.stage
stage
Definition: FPGATrackSimAnalysisConfig.py:558
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
deltaLow
const unsigned int deltaLow
Definition: memory_hooks-stdcmalloc.h:70
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
AthMemoryAuditor::m_reported
bool m_reported
Definition: AthMemoryAuditor.h:50
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
skel.it
it
Definition: skel.GENtoEVGEN.py:396
get_generator_info.stderr
stderr
Definition: get_generator_info.py:40
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
PlotPulseshapeFromCool.np
np
Definition: PlotPulseshapeFromCool.py:64
my_init_tcmalloc
void my_init_tcmalloc()
Definition: memory_hooks-tcmalloc.h:136
python.TrigEgammaFastCaloHypoTool.same
def same(val, tool)
Definition: TrigEgammaFastCaloHypoTool.py:12
AthMessaging::m_imsg
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
Definition: AthMessaging.h:135
python.SystemOfUnits.ms
int ms
Definition: SystemOfUnits.py:132
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
myBlocks_tc::allocated
uintptr_t allocated
Definition: memory_hooks-common.h:68
redzone
Definition: memory_hooks-stdcmalloc.h:123
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
LArPulseShapeRunConfig.Execute
Execute
Definition: LArPulseShapeRunConfig.py:62
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
AthMemoryAuditor::report
void report()
Definition: AthMemoryAuditor.cxx:176
AthMessaging::AthMessaging
AthMessaging()
Default constructor:
AthMemoryAuditor::m_usetcmalloc
static bool m_usetcmalloc
Definition: AthMemoryAuditor.h:46
createCoolChannelIdFile.buffer
buffer
Definition: createCoolChannelIdFile.py:12
myBlocks_tc
Definition: memory_hooks-common.h:66
TrigConf::MSGTC::Level
Level
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:21
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
AthMessaging::msgLvl
bool msgLvl(const MSG::Level lvl) const
Test the output level.
Definition: AthMessaging.h:151
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
lumiFormat.i
int i
Definition: lumiFormat.py:85
AthMemoryAuditor::stageToString
std::string stageToString(long)
Definition: AthMemoryAuditor.cxx:614
extractSporadic.h
list h
Definition: extractSporadic.py:97
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
imax
int imax(int i, int j)
Definition: TileLaserTimingTool.cxx:33
AthMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AthMessaging.h:164
MuonValidation_CreateResolutionProfiles.fit
def fit(h, emin, emax)
Definition: MuonValidation_CreateResolutionProfiles.py:69
AthMemoryAuditor::m_depthPerAlg
std::vector< std::string > m_depthPerAlg
Definition: AthMemoryAuditor.h:53
AthMemoryAuditor::m_stmax
int m_stmax
Definition: AthMemoryAuditor.h:51
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
jobOptions.Initialize
Initialize
Definition: jobOptions.pA.py:28
a
TList * a
Definition: liststreamerinfos.cxx:10
AthMemoryAuditor::m_defaultStacktraceDepth
int m_defaultStacktraceDepth
Definition: AthMemoryAuditor.h:52
SCT_ConditionsAlgorithms::CoveritySafe::getenv
std::string getenv(const std::string &variableName)
get an environment variable
Definition: SCT_ConditionsUtilities.cxx:17
h
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
AthMessaging::m_nm
std::string m_nm
Message source name.
Definition: AthMessaging.h:129
DEBUG
#define DEBUG
Definition: page_access.h:11
str
Definition: BTagTrackIpAccessor.cxx:11
AthMessaging::initMessaging
void initMessaging() const
Initialize our message level and MessageSvc.
Definition: AthMessaging.cxx:39
aiStruct
Definition: memory_hooks-common.h:38
AthMessaging::m_msg_tls
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
Definition: AthMessaging.h:132
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
node
Definition: memory_hooks-stdcmalloc.h:74
uninstall
void uninstall()
Definition: memory_hooks-tcmalloc.h:130
ServiceHandle< IInterface >