ATLAS Offline Software
ValgrindSvc.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // ValgrindSvc.cxx
8 // Implementation file for class ValgrindSvc
9 // Author: S.Binet<binet@cern.ch>
10 // Frank Winklmeier
12 
13 // valgrind includes
14 #include "valgrind/valgrind.h"
15 #include "valgrind/memcheck.h"
16 #include "valgrind/callgrind.h"
17 
18 // FrameWork includes
19 #include "Gaudi/Property.h"
20 #include "GaudiKernel/IIncidentSvc.h"
21 #include "GaudiKernel/Incident.h"
22 #include "GaudiKernel/ServiceHandle.h"
23 #include "GaudiKernel/Memory.h"
24 
25 // Valkyrie includes
26 #include "ValgrindSvc.h"
27 
28 
30 // Public methods:
32 
33 // Constructors
35 ValgrindSvc::ValgrindSvc( const std::string& name,
36  ISvcLocator* pSvcLocator ) :
37  base_class(name, pSvcLocator),
38  m_eventCounter(0),
39  m_profileCounter(0)
40 {
41  //
42  // Property declaration
43  //
44  declareProperty( "ProfiledAlgs", m_algs,
45  "List of profiled algorithms" );
46 
47  declareProperty( "ProfiledIntervals", m_intervals,
48  "Intervals to profile (e.g. 'MyAlg.initialize:MyAlg.finalize'" );
49 
50  declareProperty( "DumpAfterEachEvent", m_dumpAfterEachEvent = false,
51  "Dump separate profile after each event" );
52 
53  declareProperty( "DumpAfterEachInterval", m_dumpAfterEachInterval = true,
54  "Dump separate profile after each interval in ProfiledIntervals" );
55 
56  declareProperty( "DumpAfterIncident", m_dumpAfterIncident,
57  "List of incidents on which to dump a profile");
58 
59  declareProperty( "IgnoreFirstNEvents", m_ignoreFirstNEvents = 0,
60  "Do not profile the first N events");
61 }
62 
63 // Destructor
66 {}
67 
68 // Athena Algorithm's Hooks
71 {
72  ATH_MSG_DEBUG ("Initializing " << name());
73 
74  ATH_MSG_INFO ("My process ID is [" << System::procID() << "]");
75 
76  const bool insideValgrind = static_cast<bool>(RUNNING_ON_VALGRIND);
77  if ( insideValgrind ) {
78  ATH_MSG_INFO ("=== Running from inside Valgrind ! Hi there! ===");
79  }
80  else {
81  ATH_MSG_WARNING ("=== Valgrind is not running! ===");
82  }
83 
84  // Use incidents in case there is no auditor configured
85  if (!m_algs.empty() || !m_intervals.empty()) {
86  ATH_CHECK( auditorSvc()->addAuditor("ValgrindAuditor") );
87  }
88 
89  // Register incidents
90  ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", this->name());
91  ATH_CHECK(incSvc.retrieve());
92  incSvc->addListener( this, IncidentType::BeginEvent );
93  incSvc->addListener( this, IncidentType::EndEvent );
94 
95  for(const std::string& incident : m_dumpAfterIncident) {
96  incSvc->addListener( this, incident );
97  }
98 
99  return StatusCode::SUCCESS;
100 
101 }
102 
104 {
105  ATH_MSG_INFO ("Finalizing " << name() << "...");
106  return StatusCode::SUCCESS;
107 }
108 
110 // Const methods:
112 
114 // Non-const methods:
116 
117 void ValgrindSvc::handle( const Incident& inc )
118 {
119  // Only use Begin/EndEvent incident if no profiled algorithm or interval is set
120  bool useEventIncident = m_intervals.empty() && m_algs.empty();
121 
122  // BeginEvent
123  if ( inc.type() == IncidentType::BeginEvent ) {
124  m_eventCounter++;
125  if ( useEventIncident && m_eventCounter > m_ignoreFirstNEvents) {
126  ATH_MSG_DEBUG ("[BeginEvent] Callgrind instrumentation ON.");
128  }
129  }
130 
131  // EndEvent
132  if ( inc.type() == IncidentType::EndEvent && (m_eventCounter > m_ignoreFirstNEvents) ) {
133  if ( useEventIncident ) {
135  ATH_MSG_DEBUG ("[EndEvent] Callgrind instrumentation OFF.");
136  }
137  if ( !m_algs.empty() && m_dumpAfterEachEvent ) {
139  ATH_MSG_INFO ("Creating callgrind profile #" << profileCount()
140  << " for event #" << m_eventCounter);
141  }
142  }
143 
144  // Optional additional dumps for user specified incidents
145  if ( std::find(m_dumpAfterIncident.begin(),
146  m_dumpAfterIncident.end(),
147  inc.type()) != m_dumpAfterIncident.end() ) {
149  ATH_MSG_INFO (" Creating callgrind profile #" << profileCount()
150  << " after incident [" << inc.type() << "].");
151  }
152 
153 }
154 
155 
157 // Protected methods:
159 
161 // Const methods:
163 
165 // Non-const methods:
167 
169 {
170  CALLGRIND_START_INSTRUMENTATION;
171 }
172 
174 {
175  CALLGRIND_STOP_INSTRUMENTATION;
176 }
177 
179 {
180  CALLGRIND_TOGGLE_COLLECT;
181 }
182 
183 void ValgrindSvc::callgrindDumpStats( std::ostream& /*out*/ )
184 {
185  CALLGRIND_DUMP_STATS;
187 }
188 
190 {
191  VALGRIND_DO_LEAK_CHECK;
192 }
ValgrindSvc::m_dumpAfterIncident
std::vector< std::string > m_dumpAfterIncident
List of incidents on which to create a profile dump.
Definition: ValgrindSvc.h:95
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
ValgrindSvc::m_eventCounter
unsigned int m_eventCounter
Internal event counter for BeginEvent incident.
Definition: ValgrindSvc.h:98
ValgrindSvc::handle
virtual void handle(const Incident &incident) override
incident service handle for Begin/EndEvent
Definition: ValgrindSvc.cxx:117
ValgrindSvc::callgrindToggleCollect
virtual void callgrindToggleCollect() override
Toggle callgrind event collection.
Definition: ValgrindSvc.cxx:178
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
ValgrindSvc.h
ValgrindSvc::m_intervals
std::vector< std::string > m_intervals
List of auditor intervals to profile Syntax: "MessageSvc.initialize:MessageSvc.finalize".
Definition: ValgrindSvc.h:83
ValgrindSvc::m_dumpAfterEachInterval
bool m_dumpAfterEachInterval
Dump separate profile after each interval.
Definition: ValgrindSvc.h:89
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ValgrindSvc::m_ignoreFirstNEvents
unsigned int m_ignoreFirstNEvents
Don't profile on the first N events.
Definition: ValgrindSvc.h:92
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ValgrindSvc::valgrindDoLeakCheck
virtual void valgrindDoLeakCheck() override
Do a leak check now.
Definition: ValgrindSvc.cxx:189
ValgrindSvc::m_dumpAfterEachEvent
bool m_dumpAfterEachEvent
Dump separate profile after each event.
Definition: ValgrindSvc.h:86
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ValgrindSvc::callgrindStartInstrumentation
virtual void callgrindStartInstrumentation() override
Start callgrind instrumentation.
Definition: ValgrindSvc.cxx:168
ValgrindSvc::m_algs
std::vector< std::string > m_algs
List of algorithms to profile If list is empty, profile between begin/end event.
Definition: ValgrindSvc.h:79
ValgrindSvc::m_profileCounter
unsigned int m_profileCounter
Counter of created profiles.
Definition: ValgrindSvc.h:101
ValgrindSvc::ValgrindSvc
ValgrindSvc(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Definition: ValgrindSvc.cxx:35
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
ValgrindSvc::~ValgrindSvc
virtual ~ValgrindSvc()
Destructor:
Definition: ValgrindSvc.cxx:65
ValgrindSvc::initialize
virtual StatusCode initialize() override
Gaudi Service Implementation.
Definition: ValgrindSvc.cxx:70
ValgrindSvc::callgrindStopInstrumentation
virtual void callgrindStopInstrumentation() override
Stop callgrind instrumentation.
Definition: ValgrindSvc.cxx:173
ValgrindSvc::finalize
virtual StatusCode finalize() override
Definition: ValgrindSvc.cxx:103
ValgrindSvc::callgrindDumpStats
virtual void callgrindDumpStats(std::ostream &out) override
Dump callgrind profiling stats.
Definition: ValgrindSvc.cxx:183
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
ServiceHandle< IIncidentSvc >
ValgrindSvc::profileCount
virtual unsigned int profileCount() override
Number of created callgrind profiles.
Definition: ValgrindSvc.h:69