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"
2 #include "GaudiKernel/MsgStream.h"
3 #include "GaudiKernel/StatusCode.h"
4 
5 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
6 
7 using namespace std;
8 //
10 //
11 inline void toupper(std::string &s)
12 {
13  std::transform(s.begin(), s.end(), s.begin(),
14  (int(*)(int)) toupper);
15 }
16 
17 StatusCodeSvc::StatusCodeSvc(const std::string& name, ISvcLocator* svc )
18  : base_class( name, svc )
19 {
20 
21  declareProperty("Filter",m_pFilter);
22  declareProperty("AbortOnError",m_abort=false);
23  declareProperty("SuppressCheck", m_suppress=false);
24  declareProperty("IgnoreDicts",m_dict=true);
25 
26 }
27 
28 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
29 
30 
33 
35  if (!sc.isSuccess()) return sc;
36 
37  MsgStream log( msgSvc(), name() );
38  log << MSG::INFO << "initialize" << endmsg;
39 
40  for (const auto& itr : m_pFilter.value()) {
41  // we need to do this if someone has gotten to regFnc before initialize
42 
43  string fnc,lib;
44  parseFilter(itr,fnc,lib);
45 
46  if (!fnc.empty()) {
47  filterFnc(fnc);
48  m_filterfnc.insert(fnc);
49  }
50 
51  if (!lib.empty()) {
52  filterLib(lib);
53  m_filterlib.insert(lib);
54  }
55 
56  }
57 
58  return StatusCode::SUCCESS;
59 
60 }
61 
62 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
63 
66 
67  MsgStream log( msgSvc(), name() );
68  log << MSG::INFO << "reinitialize" << endmsg;
69 
70  return StatusCode::SUCCESS;
71 
72 }
73 
74 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
77  MsgStream log( msgSvc(), name() );
78 
79  if (!m_dat.empty()) {
80 
81  log << MSG::INFO << "listing all unchecked return codes:" << endmsg;
82 
83  list();
84 
85  } else {
86 
87  if (msgLevel(MSG::DEBUG))
88  log << MSG::DEBUG << "all StatusCode instances where checked" << endmsg;
89 
90  }
91 
92  return StatusCode::SUCCESS;
93 
94 }
95 
96 
97 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
98 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
99 
100 void
101 StatusCodeSvc::regFnc(const std::string& fnc, const std::string& lib) {
102 
103  if (m_state == Gaudi::StateMachine::OFFLINE ||
104  m_state == Gaudi::StateMachine::CONFIGURED) {
105  return;
106  }
107 
108  if (m_dict &&
109  (lib.compare(lib.length()-7, 7, "Dict.so") == 0 ||
110  lib.compare(lib.length()-8, 8, "Cling.so") == 0)) {
111  return;
112  }
113  // this appears only with gcc 4.9...
114  if (fnc == "_PyObject_GC_Malloc") return;
115  // GAUDI-1036
116  if (fnc == "PyThread_get_thread_ident") return;
117  if (fnc == "local") return;
118 
119  {
120  const string rlib = lib.substr(lib.rfind("/") + 1);
121 
122  if (m_filterfnc.find(fnc) != m_filterfnc.end() ||
123  m_filterlib.find(rlib) != m_filterlib.end() ) {
124  return;
125  }
126  }
127 
128  if (m_abort) {
129  MsgStream log( msgSvc(), name() );
130  log << MSG::FATAL << "Unchecked StatusCode in " << fnc << " from lib "
131  << lib << endmsg;
132  abort();
133  }
134 
135  string key = fnc + lib;
136 
137  auto itr = m_dat.find(key);
138 
139  if (itr != m_dat.end()) {
140  itr->second.count += 1;
141  } else {
142 
143  const string rlib = lib.substr(lib.rfind("/") + 1);
144 
145  StatCodeDat dat;
146  dat.fnc = fnc;
147  dat.lib = rlib;
148  dat.count = 1;
149 
150  m_dat[key] = dat;
151  }
152 
153 }
154 
155 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
156 
157 void
159 
160  MsgStream log( msgSvc(), name() );
161  log << MSG::INFO << endl;
162 
163 
164  std::ostringstream os;
165  os << "Num | Function | Source Library" << endl;
166  os << "----+--------------------------------+-------------------"
167  << "-----------------------" << endl;
168 
169 
170  for(const auto& itr : m_dat) {
171  const auto& dat = itr.second;
172 
173  os.width(3);
174  os.setf(ios_base::right,ios_base::adjustfield);
175  os << dat.count;
176 
177  os << " | ";
178  os.width(30);
179  os.setf(ios_base::left,ios_base::adjustfield);
180  os << dat.fnc;
181 
182  os << " | ";
183  os.setf(ios_base::left,ios_base::adjustfield);
184  os << dat.lib;
185 
186  os << endl;
187 
188  }
189 
190 
191  log << os.str() << endmsg;
192 
193 }
194 
195 
196 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
197 void
198 StatusCodeSvc::filterFnc(const std::string& str) {
199 
200  auto itr = std::find_if(m_dat.begin(),m_dat.end(),
201  [&](const std::pair<std::string,StatCodeDat>& d) {
202  return d.second.fnc == str;
203  });
204  if (itr!=std::end(m_dat)) m_dat.erase(itr);
205 
206 }
207 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
208 
209 void
210 StatusCodeSvc::filterLib(const std::string& str) {
211 
212  auto itr = std::find_if(m_dat.begin(),m_dat.end(),
213  [&](const std::pair<std::string,StatCodeDat>& d) {
214  return d.second.lib == str;
215  });
216  if (itr!=std::end(m_dat)) m_dat.erase(itr);
217 }
218 
219 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
220 
221 void
222 StatusCodeSvc::parseFilter(const string& str, string& fnc, string& lib) {
223 
224 
225  auto loc = str.find("=");
226  if (loc == std::string::npos) {
227  fnc = str;
228  lib = "";
229  } else {
230  string key = str.substr(0,loc);
231  string val = str.substr(loc+1);
232 
233  toupper(key);
234 
235  if (key == "FCN" || key == "FNC") {
236  fnc = val;
237  lib.clear();
238  } else if (key == "LIB") {
239  fnc.clear();
240  lib = val;
241  } else {
242  fnc.clear();
243  lib.clear();
244 
245  MsgStream log( msgSvc(), name() );
246  log << MSG::WARNING << "ignoring unknown token in Filter: " << str
247  << endmsg;
248  }
249  }
250 
251 }
252 
253 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
254 
BooleanProperty m_abort
Definition: StatusCodeSvc.h:42
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:63
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
BooleanProperty m_dict
Definition: StatusCodeSvc.h:42
StatusCode reinitialize() override
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
STL namespace.
void list() const override
std::map< std::string, StatCodeDat > m_dat
Definition: StatusCodeSvc.h:44
BooleanProperty m_suppress
Definition: StatusCodeSvc.h:42
void parseFilter(const std::string &str, std::string &fnc, std::string &lib)
StatusCode initialize() override
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
std::set< std::string > m_filterfnc
Definition: StatusCodeSvc.h:45
const TYPE & value() const
explicit conversion
Definition: Property.h:341
void regFnc(const std::string &func, const std::string &lib) override
StringArrayProperty m_pFilter
Definition: StatusCodeSvc.h:41
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
StatusCodeSvc(const std::string &name, ISvcLocator *svc)
void filterLib(const std::string &)
string s
Definition: gaudirun.py:245
void toupper(std::string &s)
void filterFnc(const std::string &)
StatusCode finalize() override
std::set< std::string > m_filterlib
Definition: StatusCodeSvc.h:45