diff --git a/public/libbacktrace/backtrace.hpp b/public/libbacktrace/backtrace.hpp index d95c4025..159b68bd 100644 --- a/public/libbacktrace/backtrace.hpp +++ b/public/libbacktrace/backtrace.hpp @@ -94,7 +94,10 @@ extern struct backtrace_state *backtrace_create_state ( data to be loaded directly from the file with base_address=0. The caller is responsible for converting runtime virtual addresses to ELF virtual addresses before passing them to backtrace_pcinfo - or backtrace_syminfo. */ + or backtrace_syminfo. + The filename is copied into state-owned memory (the file is opened + lazily on first use), so the caller's buffer need not outlive this + call. */ extern struct backtrace_state *backtrace_create_state_for_file ( const char *filename, int threaded, diff --git a/public/libbacktrace/state.cpp b/public/libbacktrace/state.cpp index e7d6160f..af620577 100644 --- a/public/libbacktrace/state.cpp +++ b/public/libbacktrace/state.cpp @@ -81,11 +81,20 @@ backtrace_create_state_for_file (const char *filename, int threaded, backtrace_error_callback error_callback, void *data) { - struct backtrace_state *state; + /* The state opens the file lazily on first use (fileline_initialize), + so it must own the filename: the caller's buffer may be freed as + soon as this returns. */ + const size_t len = strlen (filename) + 1; + char *copy = (char*)backtrace_alloc (NULL, len, error_callback, data); + if (copy == NULL) + return NULL; + memcpy (copy, filename, len); - state = backtrace_create_state (filename, threaded, error_callback, data); - if (state != NULL) - state->external_file = 1; + struct backtrace_state *state = + backtrace_create_state (copy, threaded, error_callback, data); + if (state == NULL) + return NULL; + state->external_file = 1; return state; }