WIP: Fancy backtrace interface
This commit is contained in:
parent
a27b359aa7
commit
ad73a0f098
@ -137,6 +137,7 @@ static void log_backtrace(void* const *trace, int trace_size, const ss_ &title)
|
||||
// The first stack frame points to this functiton
|
||||
backtrace_buffer_len = 0;
|
||||
bt_print("\n %s", cs(title));
|
||||
int first_real_i = 1;
|
||||
for(int i = 1; i < trace_size; i++){
|
||||
char cmdbuf[500];
|
||||
// Parse symbol to get file name
|
||||
@ -164,11 +165,20 @@ static void log_backtrace(void* const *trace, int trace_size, const ss_ &title)
|
||||
address, cs(file_path));
|
||||
ss_ addr2line_output = exec_get_stdout_without_newline(cmdbuf);
|
||||
|
||||
// Clean up the beginning of the backtrace (for whatever reason there
|
||||
// often seems to be two basic_string-related lines at the beginnong of
|
||||
// the backtrace)
|
||||
if(i <= 2 && i <= first_real_i &&
|
||||
addr2line_output.find("/basic_string.h") != ss_::npos){
|
||||
first_real_i = i + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(addr2line_output.size() > 4){
|
||||
bt_print(" #%i %s", i-1, cs(addr2line_output));
|
||||
bt_print(" #%i %s", i-first_real_i, cs(addr2line_output));
|
||||
log_d(MODULE, " = %s", cs(cppfilt_symbol));
|
||||
} else {
|
||||
bt_print(" #%i %s", i-1, cs(cppfilt_symbol));
|
||||
bt_print(" #%i %s", i-first_real_i, cs(cppfilt_symbol));
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,6 +234,26 @@ void log_exception_backtrace(const ss_ &title)
|
||||
log_backtrace(last_exception_frames, last_exception_num_frames, title);
|
||||
}
|
||||
|
||||
void get_current_backtrace(StoredBacktrace &result)
|
||||
{
|
||||
result.exception_name.clear();
|
||||
result.num_frames = backtrace(result.frames, 16);
|
||||
}
|
||||
|
||||
void get_exception_backtrace(StoredBacktrace &result)
|
||||
{
|
||||
result.exception_name = last_exception_name;
|
||||
result.num_frames = last_exception_num_frames;
|
||||
for(int i = 0; i < result.num_frames; i++){
|
||||
result.frames[i] = last_exception_frames[i];
|
||||
}
|
||||
}
|
||||
|
||||
void log_backtrace(const StoredBacktrace &result, const ss_ &title)
|
||||
{
|
||||
log_backtrace(result.frames, result.num_frames, title);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// vim: set noet ts=4 sw=4:
|
||||
|
@ -22,6 +22,18 @@ void log_exception_backtrace(const ss_ &title)
|
||||
log_i(MODULE, "Backtrace logging not implemented on Windows");
|
||||
}
|
||||
|
||||
void get_current_backtrace(StoredBacktrace &result)
|
||||
{
|
||||
}
|
||||
|
||||
void get_exception_backtrace(StoredBacktrace &result)
|
||||
{
|
||||
}
|
||||
|
||||
void log_backtrace(const StoredBacktrace &result, const ss_ &title)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// vim: set noet ts=4 sw=4:
|
||||
|
@ -15,8 +15,19 @@ namespace interface
|
||||
void init_signal_handlers(const SigConfig &config);
|
||||
|
||||
void log_current_backtrace(const ss_ &title="Current backtrace:");
|
||||
|
||||
void log_exception_backtrace(const ss_ &title="Exception backtrace:");
|
||||
|
||||
struct StoredBacktrace {
|
||||
void *frames[16];
|
||||
int num_frames = 0;
|
||||
ss_ exception_name;
|
||||
};
|
||||
|
||||
void get_current_backtrace(StoredBacktrace &result);
|
||||
void get_exception_backtrace(StoredBacktrace &result);
|
||||
|
||||
void log_backtrace(const StoredBacktrace &result,
|
||||
const ss_ &title="Stored backtrace:");
|
||||
}
|
||||
}
|
||||
// vim: set noet ts=4 sw=4:
|
||||
|
@ -103,10 +103,14 @@ struct ModuleContainer
|
||||
thread->start();
|
||||
}
|
||||
// Initialize in thread
|
||||
std::exception_ptr eptr;
|
||||
bool ok = execute_direct_cb([&](interface::Module *module){
|
||||
module->init();
|
||||
});
|
||||
}, eptr);
|
||||
(void)ok; // Ignored; fails generally on SIGINT at statup
|
||||
if(eptr){
|
||||
std::rethrow_exception(eptr);
|
||||
}
|
||||
}
|
||||
void thread_request_stop(){
|
||||
interface::MutexScope ms(mutex);
|
||||
@ -152,7 +156,8 @@ struct ModuleContainer
|
||||
module->event(event.type, event.p.get());
|
||||
}
|
||||
// If returns false, the module thread is stopping and cannot be called
|
||||
bool execute_direct_cb(const std::function<void(interface::Module*)> &cb){
|
||||
bool execute_direct_cb(const std::function<void(interface::Module*)> &cb,
|
||||
std::exception_ptr &result_exception){
|
||||
log_t(MODULE, "execute_direct_cb[%s]: Waiting for direct_cb to be free",
|
||||
cs(info.name));
|
||||
direct_cb_free_sem.wait(); // Wait for direct_cb to be free
|
||||
@ -195,12 +200,16 @@ struct ModuleContainer
|
||||
" exception", cs(info.name));
|
||||
/*interface::debug::log_current_backtrace(
|
||||
"Backtrace for M["+info.name+"]'s caller:");*/
|
||||
std::rethrow_exception(eptr);
|
||||
interface::debug::StoredBacktrace bt;
|
||||
interface::debug::get_current_backtrace(bt);
|
||||
interface::debug::log_backtrace(bt,
|
||||
"Backtrace for M["+info.name+"]'s caller:");
|
||||
result_exception = eptr;
|
||||
} else {
|
||||
log_t(MODULE, "execute_direct_cb[%s]: Execution finished",
|
||||
cs(info.name));
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -966,13 +975,12 @@ struct CState: public State, public interface::Server
|
||||
}
|
||||
|
||||
// Execute callback in module thread
|
||||
bool ok = mc->execute_direct_cb(cb);
|
||||
std::exception_ptr eptr;
|
||||
bool ok = mc->execute_direct_cb(cb, eptr);
|
||||
(void)ok; // Unused
|
||||
/*if(!ok && !caller_module_name.empty()){
|
||||
throw interface::TargetModuleStopped("access_module(): Module \""+
|
||||
module_name+"\" is stopping (called by \""+
|
||||
caller_module_name+"\")");
|
||||
}*/
|
||||
if(eptr){
|
||||
std::rethrow_exception(eptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user