libcsdbg  1.28
C++ exception (and generic) stack trace debug library
void csdbg::__cyg_profile_func_exit ( void *  this_fn,
void *  call_site 
)

In code compiled with -finstrument-functions, g++ injects code to call this function at the end of instrumented functions. By implementing this function (and __cyg_profile_func_enter), libcsdbg simulates the call stack of each thread.

Parameters
[in]this_fnthe address of the returning function
[in]call_sitethe address that the program counter will return to
Note
If an exception occurs, the process exits

Definition at line 147 of file tracer.cpp.

References __D_ASSERT, csdbg::filter::apply(), csdbg::process::current_thread(), csdbg::plugin::end(), csdbg::tracer::filter_count(), csdbg::tracer::get_filter(), csdbg::tracer::get_plugin(), csdbg::util::header(), csdbg::process::ilookup(), csdbg::tracer::interface(), likely, csdbg::util::lock(), csdbg::process::lookup(), csdbg::filter::mode(), csdbg::tracer::plugin_count(), csdbg::tracer::proc(), csdbg::thread::returned(), unlikely, and csdbg::util::unlock().

148 {
149  __D_ASSERT(this_fn != NULL);
150  __D_ASSERT(call_site != NULL);
151 
152  util::lock();
153  tracer *iface = tracer::interface();
154 
155  __D_ASSERT(iface != NULL);
156  if ( unlikely(iface == NULL) ) {
157  util::unlock();
158  return;
159  }
160 
161 #ifdef CSDBG_WITH_PLUGIN
162  /* Call all plugin exit functions in the reverse order they were registered */
163  for (i32 i = iface->plugin_count() - 1; likely(i >= 0); i--)
164  try {
165  iface->get_plugin(i)->end(this_fn, call_site);
166  }
167 
168  catch (exception &x) {
169  std::cerr << x;
170  }
171 
172  catch (std::exception &x) {
173  std::cerr << x;
174  }
175 
176  catch (...) {
177  util::header(std::cerr, "x");
178  std::cerr << "plugin " << std::dec << i << ": unidentified exception\r\n";
179  }
180 #endif
181 
182  try {
183  mem_addr_t addr = reinterpret_cast<mem_addr_t> (this_fn);
184  process *proc = iface->proc();
185 
186 #ifdef CSDBG_WITH_FILTER
187  mem_addr_t base = 0;
188  const i8 *path = proc->ilookup(addr, base);
189 
190  /* Call all the module filters in the order they were registered */
191  if ( likely(path != NULL) )
192  for (u32 i = 0, sz = iface->filter_count(); likely(i < sz); i++) {
193  filter *filt = iface->get_filter(i);
194  if ( likely(filt->mode()) )
195  continue;
196 
197  if ( unlikely(filt->apply(path)) ) {
198  util::unlock();
199  return;
200  }
201  }
202 #endif
203 
204  /*
205  * Lookup the process namespace to resolve the returning function symbol. If
206  * it gets resolved update the simulated call stack of the current thread
207  */
208  const i8 *nm = proc->lookup(addr);
209  if ( likely(nm != NULL) ) {
210 #ifdef CSDBG_WITH_FILTER
211  /* Call all the symbol filters in the order they were registered */
212  for (u32 i = 0, sz = iface->filter_count(); likely(i < sz); i++) {
213  filter *filt = iface->get_filter(i);
214  if ( likely(!filt->mode()) )
215  continue;
216 
217  if ( unlikely(filt->apply(nm)) ) {
218  util::unlock();
219  return;
220  }
221  }
222 #endif
223 
224  proc->current_thread()->returned();
225  }
226 
227  util::unlock();
228  return;
229  }
230 
231  catch (exception x) {
232  std::cerr << x;
233  }
234 
235  catch (std::exception x) {
236  std::cerr << x;
237  }
238 
239  util::unlock();
240  exit(EXIT_FAILURE);
241 }
char i8
8-bit signed integer
Definition: config.hpp:72
#define likely(expr)
Offer a hint (positive) to the pipeline branch predictor.
Definition: config.hpp:344
unsigned int u32
32-bit unsigned integer
Definition: config.hpp:102
int i32
32-bit signed integer
Definition: config.hpp:82
unsigned long long mem_addr_t
64-bit memory address
Definition: config.hpp:120
#define unlikely(expr)
Offer a hint (negative) to the pipeline branch predictor.
Definition: config.hpp:349
#define __D_ASSERT(x)
Assertion macro.
Definition: config.hpp:268

+ Here is the call graph for this function: