WIP: Fancy backtrace interface

master
Perttu Ahola 2014-10-30 04:40:21 +02:00
parent a27b359aa7
commit ad73a0f098
4 changed files with 74 additions and 13 deletions

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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;
}