Skip to content

Commit

Permalink
Add backward-cpp for better backtraces
Browse files Browse the repository at this point in the history
(especially in linux)
  • Loading branch information
ohm314 committed Oct 20, 2020
1 parent 07ad326 commit 0b11dc7
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@
[submodule "test/rxd/testdata"]
path = test/rxd/testdata
url = https://github.com/neuronsimulator/rxdtestdata
[submodule "external/backward"]
path = external/backward
url = https://github.com/bombela/backward-cpp.git
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ option(NRN_ENABLE_MPI "Enable MPI support" ${NRN_ENABLE_MPI_DEFAULT})
option(NRN_ENABLE_MEMACS "Enable use of memacs" ${NRN_ENABLE_EMACS})
option(NRN_ENABLE_RX3D "Enable rx3d support" ${NRN_ENABLE_RX3D_DEFAULT})
option(NRN_ENABLE_CORENEURON "Enable CoreNEURON support" ${NRN_ENABLE_CORENEURON_DEFAULT})
option(NRN_ENABLE_BACKTRACE "Enable pretty-printed backtraces" ${NRN_ENABLE_BACKTRACE_DEFAULT})
option(NRN_ENABLE_TESTS "Enable unit tests" ${NRN_ENABLE_TESTS_DEFAULT})
# note that if CoreNEURON is enabled then it is not necessary to enable this option
option(NRN_ENABLE_MOD_COMPATIBILITY "Enable CoreNEURON compatibility for MOD files" ${NRN_ENABLE_MOD_COMPATIBILITY_DEFAULT})
Expand Down Expand Up @@ -217,6 +218,12 @@ else()
set(PARANEURON 0)
endif()

# =============================================================================
# Enable backward
# =============================================================================
if(NRN_ENABLE_BACKTRACE)
add_external_project(backward)
endif()
# =============================================================================
# Enable Interviews
# =============================================================================
Expand Down
1 change: 1 addition & 0 deletions cmake/BuildOptionDefaults.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set(NRN_ENABLE_MPI_DEFAULT ON)
set(NRN_ENABLE_MEMACS_DEFAULT ON)
set(NRN_ENABLE_RX3D_DEFAULT ON)
set(NRN_ENABLE_CORENEURON_DEFAULT OFF)
set(NRN_ENABLE_BACKTRACE_DEFAULT OFF)
set(NRN_ENABLE_TESTS_DEFAULT OFF)
set(NRN_ENABLE_MODULE_INSTALL_DEFAULT ON)
set(NRN_ENABLE_PYTHON_DYNAMIC_DEFAULT OFF)
Expand Down
1 change: 1 addition & 0 deletions external/backward
Submodule backward added at 7cf6cc
5 changes: 5 additions & 0 deletions src/nrniv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ endif()

set_property(TARGET nrniv_lib PROPERTY OUTPUT_NAME nrniv)

# =============================================================================
# Link with backward-cpp if enabled
# =============================================================================
add_backward(nrniv_lib)

# =============================================================================
# Link with all libraries
# =============================================================================
Expand Down
9 changes: 8 additions & 1 deletion src/nrniv/backtrace_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@
#include <cxxabi.h>
#include <cstring>
#include <regex>
#include <string>
#include "backward.hpp"

/*
* Small utility to bring C++ symbol demangling to C
*/

extern "C" {

int parse_bt_symbol(char* backtrace_line, char* symbol, char* offset) {
int parse_bt_symbol(char* backtrace_line, void** addr, char* symbol, char* offset) {
std::regex btline("(\\d+)\\s+([\\w\\.]+)\\s+(0x[\\da-f]+)\\s+(\\w+)\\s+\\+\\s+(\\d+)");
std::cmatch backtrace_match;
if (std::regex_search(backtrace_line, backtrace_match, btline)) {
*addr = reinterpret_cast<void*>(std::stoul(backtrace_match[3].str(), nullptr, 16));
std::strcpy(symbol, backtrace_match[4].str().c_str());
std::strcpy(offset, backtrace_match[5].str().c_str());
backtrace_line[backtrace_match.position(4)-1] = '\0';
Expand All @@ -29,5 +32,9 @@ int cxx_demangle(char* symbol, char** funcname, size_t* funcname_sz) {
return status;
}

void backward_wrapper() {
backward::StackTrace st; st.load_here(32);
backward::Printer p; p.print(st);
}

}
4 changes: 3 additions & 1 deletion src/nrniv/backtrace_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
extern "C" {
#endif

extern int parse_bt_symbol(char* backtrace_line, char* symbol, char* offset);
extern void backward_wrapper();

extern int parse_bt_symbol(char* backtrace_line, void** addr, char* symbol, char* offset);

extern int cxx_demangle(char* symbol, char** funcname, size_t* funcname_sz);

Expand Down
13 changes: 8 additions & 5 deletions src/oc/hoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,9 @@ void hoc_coredump_on_error(void) {
pushx(1.);
}

void print_backward_bt() {
backward_wrapper();
}
void print_bt() {
#if HAVE_EXECINFO_H
const size_t nframes = 12;
Expand All @@ -759,7 +762,7 @@ void print_bt() {
char* symbol = malloc(sizeof(char)*funcname_size);
char* offset = malloc(sizeof(char)*10);
char* funcname = malloc(sizeof(char)*funcname_size);

void* addr = NULL;
// get void*'s for maximum last 16 entries on the stack
size = backtrace(frames, nframes);

Expand All @@ -769,7 +772,7 @@ void print_bt() {
bt_strings = backtrace_symbols(frames, size);
if (bt_strings) {
for(size_t i = 2; i < size; ++i) {
int status = parse_bt_symbol(bt_strings[i], symbol, offset);
int status = parse_bt_symbol(bt_strings[i], &addr, symbol, offset);
if (status) {
status = cxx_demangle(symbol, &funcname, &funcname_size);
if (status == 0) {
Expand Down Expand Up @@ -801,7 +804,7 @@ _fpreset();
matherr1();
#endif
Fprintf(stderr, "Floating point exception\n");
print_bt();
print_backward_bt();
if (coredump) {
abort();
}
Expand All @@ -813,7 +816,7 @@ _fpreset();
RETSIGTYPE sigsegvcatch(int sig) /* segmentation violation probably due to arg type error */
{
Fprintf(stderr, "Segmentation violation\n");
print_bt();
print_backward_bt();
/*ARGSUSED*/
if (coredump) {
abort();
Expand All @@ -826,7 +829,7 @@ RETSIGTYPE sigsegvcatch(int sig) /* segmentation violation probably due to arg t
RETSIGTYPE sigbuscatch(int sig)
{
Fprintf(stderr, "Bus error\n");
print_bt();
print_backward_bt();
/*ARGSUSED*/
if (coredump) {
abort();
Expand Down

0 comments on commit 0b11dc7

Please sign in to comment.