From ace8922bd6741cdac522ce8eee43dca4b3458c7c Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Thu, 6 Nov 2008 17:20:32 +0000 Subject: [PATCH] ebl update new "bactrace" option to dump information into a file instead of stderr git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7993 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/lib/jcr.c | 77 ++++++++++++++++++++-------------------- bacula/src/lib/message.c | 19 ---------- bacula/src/lib/message.h | 7 ---- bacula/src/lib/protos.h | 7 ++++ bacula/src/lib/signal.c | 49 +++++++++++++++++++++++-- 5 files changed, 92 insertions(+), 67 deletions(-) diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 6228e36690..ce849c8074 100644 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -836,44 +836,6 @@ static void unlock_jcr_chain() V(jcr_lock); } -/* - * This function should be used only after receiving a violent signal - * We walk through the JCR chain without doing any lock, bacula should - * not be running. - */ -void print_jcr_dbg() -{ - char buf1[128], buf2[128], buf3[128], buf4[128]; - - if (!jcrs) { - return; - } - - fprintf(stderr, "Attempt to dump current JCRs\n"); - - for (JCR *jcr = (JCR *)jcrs->first(); jcr ; jcr = (JCR *)jcrs->next(jcr)) { - if (!jcr) { /* protect us against something ? */ - continue; - } - - fprintf(stderr, "JCR=%p JobId=%i name=%s JobStatus=%c\n", - jcr, jcr->JobId, jcr->Job, jcr->JobStatus); - fprintf(stderr, "\tuse_count=%i threadid=0x%x\n", - jcr->use_count(), (int)jcr->my_thread_id); - fprintf(stderr, "\tJobType=%c JobLevel=%c\n", - jcr->get_JobType(), jcr->get_JobLevel()); - bstrftime(buf1, sizeof(buf1), jcr->sched_time); - bstrftime(buf2, sizeof(buf2), jcr->start_time); - bstrftime(buf3, sizeof(buf3), jcr->end_time); - bstrftime(buf4, sizeof(buf4), jcr->wait_time); - fprintf(stderr, "\tsched_time=%s start_time=%s\n\tend_time=%s wait_time=%s\n", - buf1, buf2, buf3, buf4); - fprintf(stderr, "\tdequeing=%i\n", jcr->dequeuing); - fprintf(stderr, "\tdb=%p db_batch=%p batch_started=%i\n", - jcr->db, jcr->db_batch, jcr->batch_started); - } -} - /* * Start walk of jcr chain * The proper way to walk the jcr chain is: @@ -1027,3 +989,42 @@ extern "C" void timeout_handler(int sig) { return; /* thus interrupting the function */ } + +/* + * !!! WARNING !!! + * + * This function should be used ONLY after a violent signal. We walk through the + * JCR chain without doing any lock, bacula should not be running. + */ +void _print_jcr_dbg(FILE *fp) +{ + char buf1[128], buf2[128], buf3[128], buf4[128]; + if (!jcrs) { + return; + } + + fprintf(fp, "Attempt to dump current JCRs\n"); + + for (JCR *jcr = (JCR *)jcrs->first(); jcr ; jcr = (JCR *)jcrs->next(jcr)) { + if (!jcr) { /* protect us against something ? */ + continue; + } + + fprintf(fp, "JCR=%p JobId=%i name=%s JobStatus=%c\n", + jcr, jcr->JobId, jcr->Job, jcr->JobStatus); + fprintf(fp, "\tuse_count=%i threadid=0x%x\n", + jcr->use_count(), (int)jcr->my_thread_id); + fprintf(fp, "\tJobType=%c JobLevel=%c\n", + jcr->get_JobType(), jcr->get_JobLevel()); + bstrftime(buf1, sizeof(buf1), jcr->sched_time); + bstrftime(buf2, sizeof(buf2), jcr->start_time); + bstrftime(buf3, sizeof(buf3), jcr->end_time); + bstrftime(buf4, sizeof(buf4), jcr->wait_time); + fprintf(fp, "\tsched_time=%s start_time=%s\n\tend_time=%s wait_time=%s\n", + buf1, buf2, buf3, buf4); + fprintf(fp, "\tdequeing=%i\n", jcr->dequeuing); + fprintf(fp, "\tdb=%p db_batch=%p batch_started=%i\n", + jcr->db, jcr->db_batch, jcr->batch_started); + } +} + diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index a7141d3387..e150e2c44f 100644 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -62,23 +62,6 @@ char con_fname[500]; /* Console filename */ FILE *con_fd = NULL; /* Console file descriptor */ brwlock_t con_lock; /* Console lock structure */ - -/* - * Global variables to get information about lock/unlock db access - */ -utime_t _db_lock_time = 0; -int _db_lock_recurse_count = 0; -pthread_t _db_lock_threadid; - -void print_lock_dbg() -{ - char buf[128]; - bstrutime(buf, sizeof(buf), _db_lock_time); - - fprintf(stderr, "lock info: recurse_count=%i threadid=0x%x time=%s\n", - _db_lock_recurse_count, (int)_db_lock_threadid, buf); -} - /* Forward referenced functions */ /* Imported functions */ @@ -1027,8 +1010,6 @@ t_msg(const char *file, int line, int level, const char *fmt,...) } } - - /* ********************************************************* * * print an error message diff --git a/bacula/src/lib/message.h b/bacula/src/lib/message.h index 5917de5af7..9d66f2eac8 100644 --- a/bacula/src/lib/message.h +++ b/bacula/src/lib/message.h @@ -164,11 +164,4 @@ extern DLL_IMP_EXP int console_msg_pending; extern DLL_IMP_EXP FILE * con_fd; /* Console file descriptor */ extern DLL_IMP_EXP brwlock_t con_lock; /* Console lock structure */ -/* Used to debug database lock - * which job takes the main DB access - */ -void print_lock_dbg(); -extern DLL_IMP_EXP utime_t _db_lock_time; -extern DLL_IMP_EXP int _db_lock_recurse_count; -extern DLL_IMP_EXP pthread_t _db_lock_threadid; diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index a9280769dc..6a424cc514 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -252,6 +252,13 @@ int generate_daemon_event(JCR *jcr, const char *event); void init_signals (void terminate(int sig)); void init_stack_dump (void); +/* Used to debug database lock + * which job takes the main DB access + */ +extern DLL_IMP_EXP utime_t _db_lock_time; +extern DLL_IMP_EXP int _db_lock_recurse_count; +extern DLL_IMP_EXP pthread_t _db_lock_threadid; + /* scan.c */ void strip_leading_space (char *str); void strip_trailing_junk (char *str); diff --git a/bacula/src/lib/signal.c b/bacula/src/lib/signal.c index 7840af6901..c4d4c913ea 100644 --- a/bacula/src/lib/signal.c +++ b/bacula/src/lib/signal.c @@ -72,6 +72,50 @@ const char *get_signal_name(int sig) } } +/* + * Global variables to get information about lock/unlock db access + */ +utime_t _db_lock_time = 0; +int _db_lock_recurse_count = 0; +pthread_t _db_lock_threadid; + +static void print_lock_dbg(FILE *fp) +{ + char buf[128]; + bstrutime(buf, sizeof(buf), _db_lock_time); + + fprintf(fp, "lock info: recurse_count=%i threadid=0x%x time=%s\n", + _db_lock_recurse_count, (int)_db_lock_threadid, buf); +} + +/* defined in jcr.c */ +extern void _print_jcr_dbg(FILE *fp); + +/* + * !!! WARNING !!! + * + * This function should be used ONLY after a violent signal. We walk through the + * JCR chain without doing any lock, bacula should not be running. + */ +static void print_bacula_dbg() +{ + char buf[512]; + + snprintf(buf, sizeof(buf), "%s/bacula.%d.bactrace", + working_directory, getpid()); + FILE *fp = fopen(buf, "ab") ; + if (!fp) { + fp = stderr; + } + + _print_jcr_dbg(fp); + print_lock_dbg(fp); + + if (fp != stderr) { + fclose(fp); + } +} + /* * Handle signals here */ @@ -169,9 +213,8 @@ extern "C" void signal_handler(int sig) waitpid(pid, NULL, 0); /* wait for child to produce dump */ Dmsg0(500, "Done waitpid\n"); fprintf(stderr, _("Traceback complete, attempting cleanup ...\n")); - /* print information about the current state into stderr */ - print_lock_dbg(); - print_jcr_dbg(); + /* print information about the current state into working/.bactrace */ + print_bacula_dbg(); exit_handler(sig); /* clean up if possible */ Dmsg0(500, "Done exit_handler\n"); } else { -- 2.39.5