ATLAS Offline Software
AthMemoryAuditor.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 // AthMemoryAuditor.cxx
7 // Author: Rolf Seuster
8 
9 // This auditor is not thread-safe without signiicant work.
10 // Disable checking for now.
11 // We'll also report an ERROR is this is used in an MT job.
14 
15 #include "GaudiKernel/INamedInterface.h"
16 
17 #include "AthMemoryAuditor.h"
19 #include "GaudiKernel/ServiceHandle.h"
20 #include "GaudiKernel/IInterface.h"
21 #include "GaudiKernel/IHiveWhiteBoard.h"
22 
23 #include <cstdint>
24 #include <string.h>
25 #include <utility> // for std::pair
26 #include <stdlib.h> // for getenv
27 
28 // needed for placement new
29 #include <new>
30 
31 #include <cstddef>
32 #include <typeinfo>
33 #include <dlfcn.h>
34 #include <sstream>
35 
36 #include "memory_hooks-common.h"
38 #include "memory_hooks-tcmalloc.h"
39 
41 
43  ISvcLocator* pSvcLocator ) :
44  Auditor ( name, pSvcLocator ),
46  m_reported(true),
47  m_stmax(10),
48  m_defaultStacktraceDepth(0)
49 {
50  declareProperty("DefaultStacktraceDepth", m_defaultStacktraceDepth);
51  declareProperty("StacktraceDepthPerAlg", m_depthPerAlg);
52  declareProperty("MaxStacktracesPerAlg", m_stmax);
53  current_stage=1;
54 }
55 
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 }
110 
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 }
175 
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 }
613 
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 }
638 
639 void AthMemoryAuditor::before(StandardEventType evt, INamedInterface* comp)
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 }
686 
687 void AthMemoryAuditor::after(StandardEventType evt, INamedInterface*, const StatusCode&)
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 }
grepfile.info
info
Definition: grepfile.py:38
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
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
AthMemoryAuditor::finalize
virtual StatusCode finalize() override
Definition: AthMemoryAuditor.cxx:57
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
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
Definition: AthMemoryAuditor.cxx:13
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
AthMemoryAuditor.h
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
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
AthMemoryAuditor::AthMemoryAuditor
AthMemoryAuditor(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Definition: AthMemoryAuditor.cxx:42
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
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
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
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
extractSporadic.h
list h
Definition: extractSporadic.py:97
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
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
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
AthMemoryAuditor::initialize
virtual StatusCode initialize() override
Definition: AthMemoryAuditor.cxx:111
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
errorcheck.h
Helpers for checking error return status codes and reporting errors.
jobOptions.Initialize
Initialize
Definition: jobOptions.pA.py:28
node::getNext
node * getNext()
Definition: memory_hooks-stdcmalloc.h:102
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
AthMemoryAuditor::before
virtual void before(StandardEventType evt, INamedInterface *comp) override
Definition: AthMemoryAuditor.cxx:639
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DEBUG
#define DEBUG
Definition: page_access.h:11
memory_hooks-stdcmalloc.h
memory_hooks-common.h
AthMemoryAuditor::after
virtual void after(StandardEventType evt, INamedInterface *comp, const StatusCode &sc) override
Definition: AthMemoryAuditor.cxx:687
str
Definition: BTagTrackIpAccessor.cxx:11
memory_hooks-tcmalloc.h
aiStruct
Definition: memory_hooks-common.h:38
checker_macros.h
Define macros for attributes used to control the static checker.
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
node::getSize
size_t getSize()
Definition: memory_hooks-stdcmalloc.h:105
ServiceHandle< IInterface >