diff --git a/lib/examples/cell_measurement.c b/lib/examples/cell_measurement.c index bfb8194df..6415257f0 100644 --- a/lib/examples/cell_measurement.c +++ b/lib/examples/cell_measurement.c @@ -163,6 +163,8 @@ int main(int argc, char **argv) { float cfo = 0; bool acks[SRSLTE_MAX_CODEWORDS] = {false}; + srslte_debug_handle_crash(argc, argv); + if (parse_args(&prog_args, argc, argv)) { exit(-1); } diff --git a/lib/examples/cell_search.c b/lib/examples/cell_search.c index 281e3d102..9ecc79c72 100644 --- a/lib/examples/cell_search.c +++ b/lib/examples/cell_search.c @@ -153,6 +153,8 @@ int main(int argc, char **argv) { uint32_t freq; uint32_t n_found_cells=0; + srslte_debug_handle_crash(argc, argv); + parse_args(argc, argv); printf("Opening RF device...\n"); diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 1d807973c..fa5483003 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -701,6 +701,8 @@ int main(int argc, char **argv) { srslte_refsignal_t csr_refs; srslte_refsignal_t mbsfn_refs; + srslte_debug_handle_crash(argc, argv); + #ifdef DISABLE_RF if (argc < 3) { usage(argv[0]); diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 681b75566..e8d4b1d00 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -341,6 +341,8 @@ int main(int argc, char **argv) { int sfn_offset; float cfo = 0; + srslte_debug_handle_crash(argc, argv); + parse_args(&prog_args, argc, argv); for (int i = 0; i< SRSLTE_MAX_CODEWORDS; i++) { diff --git a/lib/include/srslte/phy/utils/debug.h b/lib/include/srslte/phy/utils/debug.h index c88e1a3ce..11c7a23df 100644 --- a/lib/include/srslte/phy/utils/debug.h +++ b/lib/include/srslte/phy/utils/debug.h @@ -70,4 +70,6 @@ SRSLTE_API extern int srslte_verbose; #define ERROR(_fmt, ...) fprintf(stderr, "[ERROR in %s]:" _fmt "\n", __FUNCTION__, ##__VA_ARGS__) #endif /* CMAKE_BUILD_TYPE==Debug */ +void srslte_debug_handle_crash(int argc, char **argv); + #endif // DEBUG_H diff --git a/lib/src/phy/utils/debug.c b/lib/src/phy/utils/debug.c index 423abee6c..7cb9c0f11 100644 --- a/lib/src/phy/utils/debug.c +++ b/lib/src/phy/utils/debug.c @@ -24,7 +24,14 @@ * */ +#include +#include +#include +#include +#include + #include "srslte/phy/utils/debug.h" +#include "srslte/version.h" int srslte_verbose = 0; @@ -37,3 +44,57 @@ void get_time_interval(struct timeval * tdata) { tdata[0].tv_usec += 1000000; } } + +const static char crash_file_name[] = "./srsLTE.backtrace.crash"; +static int bt_argc; +static char **bt_argv; + +static void crash_handler(int sig) { + void *array[128]; + int size; + + /* Get all stack traces */ + size = backtrace(array, 128); + + FILE *f = fopen(crash_file_name, "a"); + if (!f) { + printf("srsLTE crashed... we could not save backtrace in '%s'...\n", crash_file_name); + } else { + char **symbols = backtrace_symbols(array, size); + + time_t lnTime; + struct tm *stTime; + char strdate[32]; + + time(&lnTime); + stTime = localtime(&lnTime); + + strftime(strdate, 32, "%d/%m/%Y %H:%M:%S", stTime); + + fprintf(f, "--- command='"); + for (int i = 0; i < bt_argc; i++) { + fprintf(f, "%s%s", (i == 0) ? "" : " ", bt_argv[i]); + } + fprintf(f, "' version=%s signal=%d date='%s' ---\n", SRSLTE_VERSION_STRING, sig, strdate); + + for (int i = 0; i < size; i++) { + fprintf(f, "\t%s\n", symbols[i]); + } + fprintf(f, "\n"); + + printf("srsLTE crashed... backtrace saved in '%s'...\n", crash_file_name); + fclose(f); + } + printf("--- exiting ---\n"); + exit(1); +} + +void srslte_debug_handle_crash(int argc, char **argv) { + bt_argc = argc; + bt_argv = argv; + + signal(SIGSEGV, crash_handler); + signal(SIGABRT, crash_handler); + signal(SIGILL, crash_handler); + signal(SIGFPE, crash_handler); +} diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 528878388..5cc4f5b1c 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -350,6 +350,8 @@ int main(int argc, char *argv[]) metrics_stdout metrics; enb *enb = enb::get_instance(); + srslte_debug_handle_crash(argc, argv); + cout << "--- Software Radio Systems LTE eNodeB ---" << endl << endl; parse_args(&args, argc, argv); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index cc0b07043..f1edaaf75 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -374,6 +374,9 @@ int main(int argc, char *argv[]) srslte::metrics_hub metricshub; signal(SIGINT, sig_int_handler); all_args_t args; + + srslte_debug_handle_crash(argc, argv); + parse_args(&args, argc, argv); srsue_instance_type_t type = LTE;