]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/signal.c
Add pool memory debug output
[bacula/bacula] / bacula / src / lib / signal.c
index 941c6f709185dabd92ab27ee4413f6ea6925410f..68ba78586b8915d5461b29e7cc1f2932898c9b19 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
@@ -15,7 +15,7 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
@@ -30,8 +30,6 @@
  *
  *   Kern Sibbald, April 2000
  *
  *
  *   Kern Sibbald, April 2000
  *
- *   Version $Id$
- *
  * Note, we probably should do a core dump for the serious
  * signals such as SIGBUS, SIGPFE, ...
  * Also, for SIGHUP and SIGUSR1, we should re-read the
  * Note, we probably should do a core dump for the serious
  * signals such as SIGBUS, SIGPFE, ...
  * Also, for SIGHUP and SIGUSR1, we should re-read the
@@ -53,7 +51,7 @@
 extern char my_name[];
 extern char *exepath;
 extern char *exename;
 extern char my_name[];
 extern char *exepath;
 extern char *exename;
-extern void print_jcr_dbg();
+extern bool prt_kaboom;
 
 static const char *sig_names[BA_NSIG+1];
 
 
 static const char *sig_names[BA_NSIG+1];
 
@@ -73,35 +71,58 @@ const char *get_signal_name(int sig)
 }
 
 /* defined in jcr.c */
 }
 
 /* defined in jcr.c */
-extern void _dbg_print_jcr(FILE *fp);
-/* defined in plugin.c */
-extern void _dbg_print_plugin(FILE *fp);
+extern void dbg_print_jcr(FILE *fp);
+/* defined in plugins.c */
+extern void dbg_print_plugin(FILE *fp);
+/* defined in lockmgr.c */
+extern void dbg_print_lock(FILE *fp);
 
 /*
  * !!! WARNING !!! 
  *
  * This function should be used ONLY after a violent signal. We walk through the
 
 /*
  * !!! 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.
+ * JCR chain without locking, Bacula should not be running.
  */
 static void dbg_print_bacula()
 {
    char buf[512];
 
  */
 static void dbg_print_bacula()
 {
    char buf[512];
 
-   snprintf(buf, sizeof(buf), "%s/bacula.%d.bactrace", 
-            working_directory, getpid());
-   FILE *fp = fopen(buf, "ab") ;
+   snprintf(buf, sizeof(buf), "%s/%s.%d.bactrace", 
+            working_directory, my_name, (int)getpid());
+   FILE *fp = fopen(buf, "a+") ;
    if (!fp) {
       fp = stderr;
    }
    if (!fp) {
       fp = stderr;
    }
+   
+   fprintf(stderr, "Dumping: %s\n", buf);
 
    /* Print also B_DB and RWLOCK structure 
     * Can add more info about JCR with dbg_jcr_add_hook()
     */
 
    /* Print also B_DB and RWLOCK structure 
     * Can add more info about JCR with dbg_jcr_add_hook()
     */
-   _dbg_print_jcr(fp);
-
-   _dbg_print_plugin(fp);
+   dbg_print_lock(fp);
+   dbg_print_jcr(fp);
+   dbg_print_plugin(fp);
 
    if (fp != stderr) {
 
    if (fp != stderr) {
+#define direct_print
+#ifdef direct_print
+      if (prt_kaboom) {
+         rewind(fp);
+         printf("\n\n ==== bactrace output ====\n\n");
+         while (fgets(buf, (int)sizeof(buf), fp) != NULL) {
+            printf("%s", buf);
+         }
+         printf(" ==== End baktrace output ====\n\n");
+      }
+#else
+      if (prt_kaboom) {
+         char buf1[512];
+         printf("\n\n ==== bactrace output ====\n\n");
+         snprintf(buf1, sizeof(buf1), "/bin/cat %s", buf);
+         system(buf1);
+         printf(" ==== End baktrace output ====\n\n");
+      }
+#endif
       fclose(fp);
    }
 }
       fclose(fp);
    }
 }
@@ -123,19 +144,22 @@ extern "C" void signal_handler(int sig)
       return;
    }
    already_dead++;
       return;
    }
    already_dead++;
+   /* Don't use Emsg here as it may lock and thus block us */
    if (sig == SIGTERM) {
    if (sig == SIGTERM) {
-//    Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name);
+       syslog(LOG_DAEMON|LOG_ERR, "Shutting down Bacula service: %s ...\n", my_name);
    } else {
    } else {
-      Emsg2(M_FATAL, -1, _("Bacula interrupted by signal %d: %s\n"), sig, get_signal_name(sig));
+      fprintf(stderr, _("Bacula interrupted by signal %d: %s\n"), sig, get_signal_name(sig));
+      syslog(LOG_DAEMON|LOG_ERR, 
+         _("Bacula interrupted by signal %d: %s\n"), sig, get_signal_name(sig));
    }
 
 #ifdef TRACEBACK
    if (sig != SIGTERM) {
       struct sigaction sigdefault;
    }
 
 #ifdef TRACEBACK
    if (sig != SIGTERM) {
       struct sigaction sigdefault;
-      static char *argv[4];
+      static char *argv[5];
       static char pid_buf[20];
       static char btpath[400];
       static char pid_buf[20];
       static char btpath[400];
-      char buf[100];
+      char buf[400];
       pid_t pid;
       int exelen = strlen(exepath);
 
       pid_t pid;
       int exelen = strlen(exepath);
 
@@ -181,8 +205,10 @@ extern "C" void signal_handler(int sig)
          argv[0] = btpath;            /* path to btraceback */
          argv[1] = exepath;           /* path to exe */
          argv[2] = pid_buf;
          argv[0] = btpath;            /* path to btraceback */
          argv[1] = exepath;           /* path to exe */
          argv[2] = pid_buf;
-         argv[3] = (char *)NULL;
-         fprintf(stderr, _("Calling: %s %s %s\n"), btpath, exepath, pid_buf);
+         argv[3] = (char *)working_directory;
+         argv[4] = (char *)NULL;
+         fprintf(stderr, _("Calling: %s %s %s %s\n"), btpath, exepath, pid_buf,
+            working_directory);
          if (execv(btpath, argv) != 0) {
             berrno be;
             printf(_("execv: %s failed: ERR=%s\n"), btpath, be.bstrerror());
          if (execv(btpath, argv) != 0) {
             berrno be;
             printf(_("execv: %s failed: ERR=%s\n"), btpath, be.bstrerror());
@@ -202,20 +228,40 @@ extern "C" void signal_handler(int sig)
          Dmsg0(500, "Doing waitpid\n");
          waitpid(pid, NULL, 0);       /* wait for child to produce dump */
          Dmsg0(500, "Done waitpid\n");
          Dmsg0(500, "Doing waitpid\n");
          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 working/<file>.bactrace */
-         dbg_print_bacula();
-         exit_handler(sig);           /* clean up if possible */
-         Dmsg0(500, "Done exit_handler\n");
       } else {
          Dmsg0(500, "Doing sleep\n");
          bmicrosleep(30, 0);
       }
       fprintf(stderr, _("It looks like the traceback worked ...\n"));
       } else {
          Dmsg0(500, "Doing sleep\n");
          bmicrosleep(30, 0);
       }
       fprintf(stderr, _("It looks like the traceback worked ...\n"));
+      /* If we want it printed, do so */
+#ifdef direct_print
+      if (prt_kaboom) {
+         FILE *fd;
+         snprintf(buf, sizeof(buf), "%s/bacula.%s.traceback", working_directory, pid_buf); 
+         fd = fopen(buf, "r"); 
+         if (fd != NULL) {
+            printf("\n\n ==== Traceback output ====\n\n");
+            while (fgets(buf, (int)sizeof(buf), fd) != NULL) {
+               printf("%s", buf);
+            }
+            fclose(fd);
+            printf(" ==== End traceback output ====\n\n");
+         }
+      }
+#else
+      if (prt_kaboom) {
+         snprintf(buf, sizeof(buf), "/bin/cat %s/bacula.%s.traceback", working_directory, pid_buf);
+         fprintf(stderr, "\n\n ==== Traceback output ====\n\n");
+         system(buf);
+         fprintf(stderr, " ==== End traceback output ====\n\n");
+      }
+#endif
+      /* print information about the current state into working/<file>.bactrace */
+      dbg_print_bacula();
    }
 #endif
    }
 #endif
-
    exit_handler(sig);
    exit_handler(sig);
+   Dmsg0(500, "Done exit_handler\n");
 }
 
 /*
 }
 
 /*