Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
17  if ( !sc.isSuccess() ) return sc;
18 
19  info() << "initialize" << endmsg;
20 
21  for ( const auto& itr : m_pFilter.value() ) {
22  // we need to do this if someone has gotten to regFnc before initialize
23 
24  string fnc, lib;
25  parseFilter( itr, fnc, lib );
26 
27  if ( !fnc.empty() ) {
28  filterFnc( fnc );
29  m_filterfnc.insert( fnc );
30  }
31 
32  if ( !lib.empty() ) {
33  filterLib( lib );
34  m_filterlib.insert( lib );
35  }
36  }
37 
38  return StatusCode::SUCCESS;
39 }
40 
41 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
42 
44 
45  info() << "reinitialize" << endmsg;
46 
47  return StatusCode::SUCCESS;
48 }
49 
50 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
52 
53  if ( !m_dat.empty() ) {
54 
55  info() << "listing all unchecked return codes:" << endmsg;
56 
57  list();
58 
59  } else {
60 
61  if ( msgLevel( MSG::DEBUG ) ) debug() << "all StatusCode instances where checked" << endmsg;
62  }
63 
64  return StatusCode::SUCCESS;
65 }
66 
67 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
68 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
69 
70 void StatusCodeSvc::regFnc( const std::string& fnc, const std::string& lib ) {
71 
72  if ( m_state == Gaudi::StateMachine::OFFLINE || m_state == Gaudi::StateMachine::CONFIGURED ) { return; }
73 
74  // A StatusCode instance may be create internally by ROOT dictionaries and,
75  // of course, it's not checked, so here we whitelist a few library names
76  // that are known to produce spurious reports.
77  if ( m_dict ) {
78  // ROOT's library names can end with either ".so" or ".so.x.y" with x.y the ROOT version in use
79  const auto len = lib.length();
80  if ( len >= 3 && lib.compare( len - 3, 3, ".so" ) == 0 ) {
81  if ( ( len >= 7 && ( lib.compare( len - 7, 4, "Dict" ) == 0 || lib.compare( len - 7, 4, "Core" ) == 0 ) ) ||
82  ( len >= 8 && lib.compare( len - 8, 5, "Cling" ) == 0 ) ) {
83  return;
84  }
85  } else if ( lib.rfind( "Dict.so" ) != std::string::npos || lib.rfind( "Cling.so" ) != std::string::npos ||
86  lib.rfind( "Core.so" ) != std::string::npos ) {
87  return;
88  }
89  }
90  // this appears only with gcc 4.9...
91  if ( fnc == "_PyObject_GC_Malloc" ) return;
92  // GAUDI-1036
93  if ( fnc == "PyThread_get_thread_ident" ) return;
94  if ( fnc == "local" ) return;
95 
96  {
97  const string rlib = lib.substr( lib.rfind( "/" ) + 1 );
98 
99  if ( m_filterfnc.find( fnc ) != m_filterfnc.end() || m_filterlib.find( rlib ) != m_filterlib.end() ) { return; }
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 
128 void StatusCodeSvc::list() const {
129 
131  os << "Num | Function | Source Library" << endl;
132  os << "----+--------------------------------+-------------------"
133  << "-----------------------" << endl;
134 
135  for ( const auto& itr : m_dat ) {
136  const auto& dat = itr.second;
137 
138  os.width( 3 );
139  os.setf( ios_base::right, ios_base::adjustfield );
140  os << dat.count;
141 
142  os << " | ";
143  os.width( 30 );
144  os.setf( ios_base::left, ios_base::adjustfield );
145  os << dat.fnc;
146 
147  os << " | ";
148  os.setf( ios_base::left, ios_base::adjustfield );
149  os << dat.lib;
150 
151  os << endl;
152  }
153 
154  info() << endl << os.str() << endmsg;
155 }
156 
157 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
159 
160  auto itr = std::find_if( m_dat.begin(), m_dat.end(),
161  [&]( const std::pair<std::string, StatCodeDat>& d ) { return d.second.fnc == str; } );
162  if ( itr != std::end( m_dat ) ) m_dat.erase( itr );
163 }
164 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
165 
167 
168  auto itr = std::find_if( m_dat.begin(), m_dat.end(),
169  [&]( const std::pair<std::string, StatCodeDat>& d ) { return d.second.lib == str; } );
170  if ( itr != std::end( m_dat ) ) m_dat.erase( itr );
171 }
172 
173 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
174 
175 void StatusCodeSvc::parseFilter( const string& str, string& fnc, string& lib ) {
176 
177  auto loc = str.find( "=" );
178  if ( loc == std::string::npos ) {
179  fnc = str;
180  lib = "";
181  } else {
182  string key = str.substr( 0, loc );
183  string val = str.substr( loc + 1 );
184 
185  toupper( key );
186 
187  if ( key == "FCN" || key == "FNC" ) {
188  fnc = val;
189  lib.clear();
190  } else if ( key == "LIB" ) {
191  fnc.clear();
192  lib = val;
193  } else {
194  fnc.clear();
195  lib.clear();
196 
197  warning() << "ignoring unknown token in Filter: " << str << endmsg;
198  }
199  }
200 }
201 
202 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
203 
T setf(T...args)
StatusCode initialize() override
Definition: Service.cpp:60
T empty(T...args)
StatusCode reinitialize() override
bool isSuccess() const
Definition: StatusCode.h:267
T rfind(T...args)
T endl(T...args)
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
STL namespace.
T end(T...args)
STL class.
void parseFilter(const std::string &str, std::string &fnc, std::string &lib)
#define DECLARE_COMPONENT(type)
StatusCode initialize() override
T toupper(T...args)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
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:312
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:192
T compare(T...args)
void filterFnc(const std::string &)
void list() const override
StatusCode finalize() override