The Gaudi Framework  v29r0 (ff2e7097)
StatusCodeSvc.cpp
Go to the documentation of this file.
1 #include "StatusCodeSvc.h"
3 
4 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5 
6 using namespace std;
7 //
9 //
10 inline void toupper( std::string& s ) { std::transform( s.begin(), s.end(), s.begin(), (int ( * )( int ))toupper ); }
11 
12 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
15 {
16 
18  if ( !sc.isSuccess() ) return sc;
19 
20  info() << "initialize" << endmsg;
21 
22  for ( const auto& itr : m_pFilter.value() ) {
23  // we need to do this if someone has gotten to regFnc before initialize
24 
25  string fnc, lib;
26  parseFilter( itr, fnc, lib );
27 
28  if ( !fnc.empty() ) {
29  filterFnc( fnc );
30  m_filterfnc.insert( fnc );
31  }
32 
33  if ( !lib.empty() ) {
34  filterLib( lib );
35  m_filterlib.insert( lib );
36  }
37  }
38 
39  return StatusCode::SUCCESS;
40 }
41 
42 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
43 
45 {
46 
47  info() << "reinitialize" << endmsg;
48 
49  return StatusCode::SUCCESS;
50 }
51 
52 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
54 {
55 
56  if ( !m_dat.empty() ) {
57 
58  info() << "listing all unchecked return codes:" << endmsg;
59 
60  list();
61 
62  } else {
63 
64  if ( msgLevel( MSG::DEBUG ) ) debug() << "all StatusCode instances where checked" << endmsg;
65  }
66 
67  return StatusCode::SUCCESS;
68 }
69 
70 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
71 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
72 
73 void StatusCodeSvc::regFnc( const std::string& fnc, const std::string& lib )
74 {
75 
76  if ( m_state == Gaudi::StateMachine::OFFLINE || m_state == Gaudi::StateMachine::CONFIGURED ) {
77  return;
78  }
79 
80  // A StatusCode instance may be create internally by ROOT dictionaries and,
81  // of course, it's not checked, so here we whitelist a few library names
82  // that are known to produce spurious reports.
83  if ( m_dict &&
84  ( lib.compare( lib.length() - 7, 7, "Dict.so" ) == 0 || lib.compare( lib.length() - 8, 8, "Cling.so" ) == 0 ||
85  lib.compare( lib.length() - 7, 7, "Core.so" ) == 0 ) ) {
86  return;
87  }
88  // this appears only with gcc 4.9...
89  if ( fnc == "_PyObject_GC_Malloc" ) return;
90  // GAUDI-1036
91  if ( fnc == "PyThread_get_thread_ident" ) return;
92  if ( fnc == "local" ) return;
93 
94  {
95  const string rlib = lib.substr( lib.rfind( "/" ) + 1 );
96 
97  if ( m_filterfnc.find( fnc ) != m_filterfnc.end() || m_filterlib.find( rlib ) != m_filterlib.end() ) {
98  return;
99  }
100  }
101 
102  if ( m_abort ) {
103  fatal() << "Unchecked StatusCode in " << fnc << " from lib " << lib << endmsg;
104  abort();
105  }
106 
107  string key = fnc + lib;
108 
109  auto itr = m_dat.find( key );
110 
111  if ( itr != m_dat.end() ) {
112  itr->second.count += 1;
113  } else {
114 
115  const string rlib = lib.substr( lib.rfind( "/" ) + 1 );
116 
117  StatCodeDat dat;
118  dat.fnc = fnc;
119  dat.lib = rlib;
120  dat.count = 1;
121 
122  m_dat[key] = dat;
123  }
124 }
125 
126 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
127 
129 {
130 
132  os << "Num | Function | Source Library" << endl;
133  os << "----+--------------------------------+-------------------"
134  << "-----------------------" << endl;
135 
136  for ( const auto& itr : m_dat ) {
137  const auto& dat = itr.second;
138 
139  os.width( 3 );
140  os.setf( ios_base::right, ios_base::adjustfield );
141  os << dat.count;
142 
143  os << " | ";
144  os.width( 30 );
145  os.setf( ios_base::left, ios_base::adjustfield );
146  os << dat.fnc;
147 
148  os << " | ";
149  os.setf( ios_base::left, ios_base::adjustfield );
150  os << dat.lib;
151 
152  os << endl;
153  }
154 
155  info() << endl << os.str() << endmsg;
156 }
157 
158 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
160 {
161 
162  auto itr = std::find_if( m_dat.begin(), m_dat.end(),
163  [&]( const std::pair<std::string, StatCodeDat>& d ) { return d.second.fnc == str; } );
164  if ( itr != std::end( m_dat ) ) m_dat.erase( itr );
165 }
166 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
167 
169 {
170 
171  auto itr = std::find_if( m_dat.begin(), m_dat.end(),
172  [&]( const std::pair<std::string, StatCodeDat>& d ) { return d.second.lib == str; } );
173  if ( itr != std::end( m_dat ) ) m_dat.erase( itr );
174 }
175 
176 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
177 
178 void StatusCodeSvc::parseFilter( const string& str, string& fnc, string& lib )
179 {
180 
181  auto loc = str.find( "=" );
182  if ( loc == std::string::npos ) {
183  fnc = str;
184  lib = "";
185  } else {
186  string key = str.substr( 0, loc );
187  string val = str.substr( loc + 1 );
188 
189  toupper( key );
190 
191  if ( key == "FCN" || key == "FNC" ) {
192  fnc = val;
193  lib.clear();
194  } else if ( key == "LIB" ) {
195  fnc.clear();
196  lib = val;
197  } else {
198  fnc.clear();
199  lib.clear();
200 
201  warning() << "ignoring unknown token in Filter: " << str << endmsg;
202  }
203  }
204 }
205 
206 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
207 
T setf(T...args)
StatusCode initialize() override
Definition: Service.cpp:64
T empty(T...args)
StatusCode reinitialize() override
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
T rfind(T...args)
T endl(T...args)
STL namespace.
T end(T...args)
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:33
STL class.
void parseFilter(const std::string &str, std::string &fnc, std::string &lib)
StatusCode initialize() override
T toupper(T...args)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
T width(T...args)
T clear(T...args)
STL class.
void regFnc(const std::string &func, const std::string &lib) override
T find(T...args)
T length(T...args)
T begin(T...args)
void filterLib(const std::string &)
string s
Definition: gaudirun.py:253
T substr(T...args)
T abort(T...args)
T transform(T...args)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
T compare(T...args)
void filterFnc(const std::string &)
void list() const override
StatusCode finalize() override