Selaa lähdekoodia

Merge branch 'debug_buf'

* debug_buf:
  * Log flush_modes calls into buffer
  * Move some common debug code
  * Use sizeof() for buffer updating
  * Add debug buffer output on crash - please give to bryan if it ever comes up.
  * Enable auto-gdb backtracing in debug mode
Bryan Drewery 16 vuotta sitten
vanhempi
commit
ef8b39b6ae
6 muutettua tiedostoa jossa 59 lisäystä ja 9 poistoa
  1. 1 0
      doc/UPDATES
  2. 37 8
      src/debug.c
  3. 6 1
      src/debug.h
  4. 5 0
      src/egg_timer.c
  5. 3 0
      src/mod/irc.mod/irc.c
  6. 7 0
      src/net.c

+ 1 - 0
doc/UPDATES

@@ -127,6 +127,7 @@
   * Utilize CPRIVMSG/CNOTICE if available.
   * Chain WHO requests to try avoiding Max SendQ
   * More Auth channel commands are now available. Auth up and run +help to see them all.
+  * Add debug buffer output on crash - please give to bryan if it ever comes up.
 
 1.2.16.1
 * Fix linux compile errors

+ 37 - 8
src/debug.c

@@ -51,6 +51,8 @@
 
 bool		sdebug = 0;             /* enable debug output? */
 bool		segfaulted = 0;
+char	get_buf[GET_BUFS][SGRAB + 5];
+size_t	current_get_buf = 0;
 
 
 #ifdef DEBUG_CONTEXT
@@ -149,6 +151,15 @@ static void write_debug()
 }
 #endif /* DEBUG_CONTEXT */
 
+static void write_debug()
+{
+  putlog(LOG_MISC, "*", "** Paste to bryan:");
+  const size_t cur_buf = (current_get_buf == 0) ? GET_BUFS - 1 : current_get_buf - 1;
+  for (size_t i = 0; i < GET_BUFS; i++)
+    putlog(LOG_MISC, "*", "%c %02zu: %s", i == cur_buf ? '*' : '+', i, get_buf[i]);
+  putlog(LOG_MISC, "*", "** end");
+}
+
 #ifndef DEBUG
 static void got_bus(int) __attribute__ ((noreturn));
 #endif /* DEBUG */
@@ -156,9 +167,7 @@ static void got_bus(int) __attribute__ ((noreturn));
 static void got_bus(int z)
 {
   signal(SIGBUS, SIG_DFL);
-#ifdef DEBUG_CONTEXT
   write_debug();
-#endif
   fatal("BUS ERROR -- CRASHING!", 1);
 #ifdef DEBUG
   raise(SIGBUS);
@@ -176,11 +185,35 @@ static void got_segv(int z)
   segfaulted = 1;
   alarm(0);		/* dont let anything jump out of this signal! */
   signal(SIGSEGV, SIG_DFL);
-#ifdef DEBUG_CONTEXT
   write_debug();
-#endif
   fatal("SEGMENT VIOLATION -- CRASHING!", 1);
 #ifdef DEBUG
+  char gdb[1024] = "", btfile[256] = "", std_in[101] = "", *out = NULL;
+  unsigned int core = 0;
+
+  simple_snprintf(btfile, sizeof(btfile), ".gdb-backtrace-%d", getpid());
+
+  FILE *f = fopen(btfile, "w");
+
+  if (f) {
+    strlcpy(std_in, "bt 100\nbt 100 full\n", sizeof(stdin));
+//    simple_snprintf(stdin, sizeof(stdin), "detach\n");
+//    simple_snprintf(stdin, sizeof(stdin), "q\n");
+
+    simple_snprintf(gdb, sizeof(gdb), "gdb %s %d", binname, getpid());
+    shell_exec(gdb, std_in, &out, NULL);
+    fprintf(f, "%s\n", out);
+    fclose(f);
+    free(out);
+  }
+
+  //enabling core dumps
+  struct rlimit limit;
+  if (!getrlimit(RLIMIT_CORE, &limit)) {
+    limit.rlim_cur = limit.rlim_max;
+    if(!setrlimit(RLIMIT_CORE, &limit)) core = limit.rlim_cur;
+  }
+
   raise(SIGSEGV);
 #else
   exit(1);
@@ -191,9 +224,7 @@ static void got_fpe(int) __attribute__ ((noreturn));
 
 static void got_fpe(int z)
 {
-#ifdef DEBUG_CONTEXT
   write_debug();
-#endif
   fatal("FLOATING POINT ERROR -- CRASHING!", 0);
   exit(1);		/* for GCC noreturn */
 }
@@ -215,9 +246,7 @@ static void got_abort(int) __attribute__ ((noreturn));
 static void got_abort(int z)
 {
   signal(SIGABRT, SIG_DFL);
-#ifdef DEBUG_CONTEXT
   write_debug();
-#endif
   fatal("GOT SIGABRT -- CRASHING!", 1);
 #ifdef DEBUG
   raise(SIGSEGV);

+ 6 - 1
src/debug.h

@@ -12,6 +12,9 @@
 
 #undef DEBUG_CONTEXT
 
+#define GET_BUFS 5
+#define get_buf_inc() if (++current_get_buf == GET_BUFS) current_get_buf = 0;
+
 /*
  *    Handy aliases for memory tracking and core dumps
  */
@@ -29,8 +32,10 @@
 #define debug3(x,a1,a2,a3)      putlog(LOG_DEBUG,"*",x,a1,a2,a3)
 #define debug4(x,a1,a2,a3,a4)   putlog(LOG_DEBUG,"*",x,a1,a2,a3,a4)
 
-
+#include "net.h"
 extern bool		sdebug, segfaulted;
+extern size_t		current_get_buf;
+extern char		get_buf[GET_BUFS][SGRAB + 5];
 
 void setlimits();
 void sdprintf (const char *, ...) __attribute__((format(printf, 1, 2)));

+ 5 - 0
src/egg_timer.c

@@ -253,6 +253,11 @@ static bool process_timer(egg_timer_t* timer) {
 		deleted = 1;
 	}
 
+	if (timer->name) {
+		simple_snprintf(get_buf[current_get_buf], sizeof(get_buf[current_get_buf]), "Execing timer: %s", timer->name);
+		get_buf_inc();
+	}
+
 	callback(client_data);
 	return deleted;
 }

+ 3 - 0
src/mod/irc.mod/irc.c

@@ -1678,6 +1678,9 @@ flush_modes()
 
   memberlist *m = NULL;
 
+  strlcpy(get_buf[current_get_buf], "Idle", sizeof(get_buf[current_get_buf]));
+  get_buf_inc();
+
   for (register struct chanset_t *chan = chanset; chan; chan = chan->next) {
     for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
       if (m->delay && m->delay <= now) {

+ 7 - 0
src/net.c

@@ -1481,9 +1481,16 @@ bool socket_run() {
 
   int xx = sockgets(buf, &i);
 
+  get_buf[current_get_buf][0] = 0;
+
   if (xx >= 0) {		/* Non-error */
     if ((idx = findanyidx(xx)) != -1) {
       if (likely(dcc[idx].type->activity)) {
+        if (buf[0]) {
+          strlcpy(get_buf[current_get_buf], buf, sizeof(get_buf[current_get_buf]));
+          get_buf_inc();
+        }
+
         /* Traffic stats */
         if (dcc[idx].type->name) {
           if (!strncmp(dcc[idx].type->name, "BOT", 3))