Commit 1b92856c authored by Leif Walsh's avatar Leif Walsh

made do_backtrace an env function that uses errfile #201

fixes #201
parent ec97ac41
...@@ -463,6 +463,7 @@ static void print_db_env_struct (void) { ...@@ -463,6 +463,7 @@ static void print_db_env_struct (void) {
"int (*iterate_pending_lock_requests) (DB_ENV *env, iterate_requests_callback callback, void *extra)", "int (*iterate_pending_lock_requests) (DB_ENV *env, iterate_requests_callback callback, void *extra)",
"void (*set_loader_memory_size)(DB_ENV *env, uint64_t (*get_loader_memory_size_callback)(void))", "void (*set_loader_memory_size)(DB_ENV *env, uint64_t (*get_loader_memory_size_callback)(void))",
"uint64_t (*get_loader_memory_size)(DB_ENV *env)", "uint64_t (*get_loader_memory_size)(DB_ENV *env)",
"void (*env_do_backtrace) (DB_ENV *env)",
NULL}; NULL};
sort_and_dump_fields("db_env", true, extra); sort_and_dump_fields("db_env", true, extra);
...@@ -854,7 +855,6 @@ int main (int argc, char *const argv[] __attribute__((__unused__))) { ...@@ -854,7 +855,6 @@ int main (int argc, char *const argv[] __attribute__((__unused__))) {
printf("void db_env_set_num_bucket_mutexes(uint32_t) %s;\n", VISIBLE); printf("void db_env_set_num_bucket_mutexes(uint32_t) %s;\n", VISIBLE);
printf("int db_env_set_toku_product_name(const char*) %s;\n", VISIBLE); printf("int db_env_set_toku_product_name(const char*) %s;\n", VISIBLE);
printf("void db_env_try_gdb_stack_trace(const char *gdb_path) %s;\n", VISIBLE); printf("void db_env_try_gdb_stack_trace(const char *gdb_path) %s;\n", VISIBLE);
printf("void db_env_do_backtrace(void) %s;\n", VISIBLE);
printf("#if defined(__cplusplus) || defined(__cilkplusplus)\n}\n#endif\n"); printf("#if defined(__cplusplus) || defined(__cilkplusplus)\n}\n#endif\n");
printf("#endif\n"); printf("#endif\n");
......
...@@ -138,31 +138,30 @@ void toku_assert_set_fpointers(int (*toku_maybe_get_engine_status_text_pointer)( ...@@ -138,31 +138,30 @@ 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;
extern "C" void db_env_do_backtrace(void) __attribute__((__visibility__("default"))); // also declared in db.h for consumers of that API void db_env_do_backtrace(FILE *outf) {
extern "C" void db_env_do_backtrace(void) {
// backtrace // backtrace
#if !TOKU_WINDOWS #if !TOKU_WINDOWS
int n = backtrace(backtrace_pointers, N_POINTERS); int n = backtrace(backtrace_pointers, N_POINTERS);
fprintf(stderr, "Backtrace: (Note: toku_do_assert=0x%p)\n", toku_do_assert); fflush(stderr); fprintf(outf, "Backtrace: (Note: toku_do_assert=0x%p)\n", toku_do_assert); fflush(outf);
backtrace_symbols_fd(backtrace_pointers, n, fileno(stderr)); backtrace_symbols_fd(backtrace_pointers, n, fileno(outf));
#endif #endif
fflush(stderr); fflush(outf);
if (engine_status_num_rows && toku_maybe_get_engine_status_text_p) { 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) int buffsize = engine_status_num_rows * 128; // assume 128 characters per row (gross overestimate, should be safe)
char buff[buffsize]; char buff[buffsize];
toku_maybe_get_engine_status_text_p(buff, buffsize); toku_maybe_get_engine_status_text_p(buff, buffsize);
fprintf(stderr, "Engine status:\n%s\n", buff); fprintf(outf, "Engine status:\n%s\n", buff);
} else {
fprintf(outf, "Engine status function not available\n");
} }
else fprintf(outf, "Memory usage:\n");
fprintf(stderr, "Engine status function not available\n"); fflush(outf); // just in case malloc_stats() crashes, we still want engine status (and to know that malloc_stats() failed)
fprintf(stderr, "Memory usage:\n");
fflush(stderr); // just in case malloc_stats() crashes, we still want engine status (and to know that malloc_stats() failed)
if (malloc_stats_f) { if (malloc_stats_f) {
malloc_stats_f(); malloc_stats_f();
} }
fflush(stderr); fflush(outf);
if (do_assert_hook) do_assert_hook(); if (do_assert_hook) do_assert_hook();
if (toku_gdb_dump_on_assert) { if (toku_gdb_dump_on_assert) {
...@@ -172,7 +171,7 @@ extern "C" void db_env_do_backtrace(void) { ...@@ -172,7 +171,7 @@ extern "C" void db_env_do_backtrace(void) {
__attribute__((noreturn)) __attribute__((noreturn))
static void toku_do_backtrace_abort(void) { static void toku_do_backtrace_abort(void) {
db_env_do_backtrace(); db_env_do_backtrace(stderr);
#if TOKU_WINDOWS #if TOKU_WINDOWS
//Following commented methods will not always end the process (could hang). //Following commented methods will not always end the process (could hang).
......
...@@ -2452,6 +2452,14 @@ static uint64_t env_get_loader_memory_size(DB_ENV *env) { ...@@ -2452,6 +2452,14 @@ static uint64_t env_get_loader_memory_size(DB_ENV *env) {
return memory_size; return memory_size;
} }
static void env_do_backtrace(DB_ENV *env) {
if (env->i->errfile) {
db_env_do_backtrace(env->i->errfile);
} else {
db_env_do_backtrace(stderr);
}
}
static int static int
toku_env_create(DB_ENV ** envp, uint32_t flags) { toku_env_create(DB_ENV ** envp, uint32_t flags) {
int r = ENOSYS; int r = ENOSYS;
...@@ -2527,6 +2535,7 @@ toku_env_create(DB_ENV ** envp, uint32_t flags) { ...@@ -2527,6 +2535,7 @@ toku_env_create(DB_ENV ** envp, uint32_t flags) {
USENV(change_fsync_log_period); USENV(change_fsync_log_period);
USENV(set_loader_memory_size); USENV(set_loader_memory_size);
USENV(get_loader_memory_size); USENV(get_loader_memory_size);
USENV(do_backtrace);
#undef USENV #undef USENV
// unlocked methods // unlocked methods
......
...@@ -98,6 +98,7 @@ PATENT RIGHTS GRANT: ...@@ -98,6 +98,7 @@ PATENT RIGHTS GRANT:
#include <stdint.h> #include <stdint.h>
#include <errno.h> #include <errno.h>
#include <stdio.h>
#ifdef NDEBUG #ifdef NDEBUG
#error NDEBUG should not be set #error NDEBUG should not be set
...@@ -134,6 +135,7 @@ void toku_do_assert_expected_fail(uintptr_t/*expr*/, uintptr_t /*expected*/, con ...@@ -134,6 +135,7 @@ 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.
void db_env_do_backtrace(FILE *outf);
#if defined(GCOV) || TOKU_WINDOWS #if defined(GCOV) || TOKU_WINDOWS
#define assert(expr) toku_do_assert((expr) != 0, #expr, __FUNCTION__, __FILE__, __LINE__, get_maybe_error_errno()) #define assert(expr) toku_do_assert((expr) != 0, #expr, __FUNCTION__, __FILE__, __LINE__, get_maybe_error_errno())
......
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