Commit 422e4d88 authored by Leif Walsh's avatar Leif Walsh

added errcall path to backtrace for tokumx Tokutek/mongo#1028

parent 86d2d49e
...@@ -138,6 +138,39 @@ void toku_assert_set_fpointers(int (*toku_maybe_get_engine_status_text_pointer)( ...@@ -138,6 +138,39 @@ void toku_assert_set_fpointers(int (*toku_maybe_get_engine_status_text_pointer)(
bool toku_gdb_dump_on_assert = false; bool toku_gdb_dump_on_assert = false;
void (*do_assert_hook)(void) = NULL; void (*do_assert_hook)(void) = NULL;
void db_env_do_backtrace_errfunc(toku_env_err_func errfunc, const void *env) {
// backtrace
#if !TOKU_WINDOWS
int n = backtrace(backtrace_pointers, N_POINTERS);
errfunc(env, 0, "Backtrace: (Note: toku_do_assert=0x%p)\n", toku_do_assert);
char **syms = backtrace_symbols(backtrace_pointers, n);
if (syms) {
for (char **symstr = syms; symstr != NULL && (symstr - syms) < n; ++symstr) {
errfunc(env, 0, *symstr);
}
//free(syms);
}
#endif
if (engine_status_num_rows && toku_maybe_get_engine_status_text_p) {
int buffsize = engine_status_num_rows * 128; // assume 128 characters per row (gross overestimate, should be safe)
char buff[buffsize];
toku_maybe_get_engine_status_text_p(buff, buffsize);
errfunc(env, 0, "Engine status:\n%s\n", buff);
} else {
errfunc(env, 0, "Engine status function not available\n");
}
errfunc(env, 0, "Memory usage:\n");
if (malloc_stats_f) {
malloc_stats_f();
}
if (do_assert_hook) do_assert_hook();
if (toku_gdb_dump_on_assert) {
toku_try_gdb_stack_trace(nullptr);
}
}
void db_env_do_backtrace(FILE *outf) { void db_env_do_backtrace(FILE *outf) {
// backtrace // backtrace
#if !TOKU_WINDOWS #if !TOKU_WINDOWS
......
...@@ -2453,6 +2453,9 @@ static uint64_t env_get_loader_memory_size(DB_ENV *env) { ...@@ -2453,6 +2453,9 @@ static uint64_t env_get_loader_memory_size(DB_ENV *env) {
} }
static void env_do_backtrace(DB_ENV *env) { static void env_do_backtrace(DB_ENV *env) {
if (env->i->errcall) {
db_env_do_backtrace_errfunc((toku_env_err_func) toku_env_err, (const void *) env);
}
if (env->i->errfile) { if (env->i->errfile) {
db_env_do_backtrace((FILE *) env->i->errfile); db_env_do_backtrace((FILE *) env->i->errfile);
} else { } else {
......
...@@ -135,6 +135,9 @@ void toku_do_assert_expected_fail(uintptr_t/*expr*/, uintptr_t /*expected*/, con ...@@ -135,6 +135,9 @@ void toku_do_assert_expected_fail(uintptr_t/*expr*/, uintptr_t /*expected*/, con
// #define GCOV // #define GCOV
extern void (*do_assert_hook)(void); // Set this to a function you want called after printing the assertion failure message but before calling abort(). By default this is NULL. extern void (*do_assert_hook)(void); // Set this to a function you want called after printing the assertion failure message but before calling abort(). By default this is NULL.
// copied here from ydb-internal.h to avoid inclusion hell, the void * is really a DB_ENV but we don't have that type here
typedef void (*toku_env_err_func)(const void * env, int error, const char *fmt, ...);
void db_env_do_backtrace_errfunc(toku_env_err_func errfunc, const void *env);
void db_env_do_backtrace(FILE *outf); void db_env_do_backtrace(FILE *outf);
#if defined(GCOV) || TOKU_WINDOWS #if defined(GCOV) || TOKU_WINDOWS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment