Some reading here:
the key enabler is the -finstrument-functions option to gcc.
Generate instrumentation calls for entry and exit to functions. Just after function entry and just before function exit, the following profiling functions will be called with the address of the current function and its call site. […]
void __cyg_profile_func_enter (void *this_fn,
void __cyg_profile_func_exit (void *this_fn,
Then adding a debug output with the address, combined with addr2line you can get full trace debugging of the code.
Of course this adds overhead, so is only useful when tracking down an issue or optimizing an application.