Просмотр исходного кода

* Dumping stack on SIGSEGV now
* Now setting SIGSEGV to SIG_DFL only in a nested_debug


svn: 1047

Bryan Drewery 22 лет назад
Родитель
Сommit
8cf0807f4d
4 измененных файлов с 53 добавлено и 3 удалено
  1. 1 0
      doc/UPDATES
  2. 3 1
      src/cmds.c
  3. 48 2
      src/debug.c
  4. 1 0
      src/debug.h

+ 1 - 0
doc/UPDATES

@@ -26,6 +26,7 @@ This is a summary of ChangeLog basically.
 22.Added server 005 support, fixes many potential bugs.
 22.Added server 005 support, fixes many potential bugs.
 23.Fixed many bugs with color system, including color over relay/botcmd.
 23.Fixed many bugs with color system, including color over relay/botcmd.
 24.Recoded some of the AES core, fixed several outstanding bugs.
 24.Recoded some of the AES core, fixed several outstanding bugs.
+25.Now dumping the stack on SIGSEGV.
 
 
 1.1.7
 1.1.7
 
 

+ 3 - 1
src/cmds.c

@@ -2061,7 +2061,7 @@ static void cmd_debug(struct userrec *u, int idx, char *par)
 {
 {
   char *cmd = NULL;
   char *cmd = NULL;
 
 
-  if (!par[0])
+  if (!par[0]) 
     putlog(LOG_CMDS, "*", "#%s# debug", dcc[idx].nick);
     putlog(LOG_CMDS, "*", "#%s# debug", dcc[idx].nick);
 
 
   if (par[0])
   if (par[0])
@@ -2074,6 +2074,8 @@ static void cmd_debug(struct userrec *u, int idx, char *par)
     dprintf(idx, "Role: %d\n", role);
     dprintf(idx, "Role: %d\n", role);
   if (!cmd || (cmd &&!strcmp(cmd, "net")))
   if (!cmd || (cmd &&!strcmp(cmd, "net")))
     tell_netdebug(idx);
     tell_netdebug(idx);
+  if (!cmd || (cmd &&!strcmp(cmd, "stackdump")))
+    stackdump(idx);
 }
 }
 
 
 static void cmd_timers(struct userrec *u, int idx, char *par)
 static void cmd_timers(struct userrec *u, int idx, char *par)

+ 48 - 2
src/debug.c

@@ -25,6 +25,9 @@
 #include <sys/resource.h>
 #include <sys/resource.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <stdarg.h>
 #include <stdarg.h>
+#include <errno.h>
+#include <sys/mman.h>
+#define PAGESIZE 4096
 
 
 int		sdebug = 0;             /* enable debug output? */
 int		sdebug = 0;             /* enable debug output? */
 
 
@@ -109,6 +112,7 @@ void write_debug()
   int y;
   int y;
 
 
   if (nested_debug) {
   if (nested_debug) {
+    signal(SIGSEGV, SIG_DFL);
     /* Yoicks, if we have this there's serious trouble!
     /* Yoicks, if we have this there's serious trouble!
      * All of these are pretty reliable, so we'll try these.
      * All of these are pretty reliable, so we'll try these.
      *
      *
@@ -134,7 +138,7 @@ void write_debug()
       /* Use this lame method because shell_exec() or mail() may have caused another segfault :o */
       /* Use this lame method because shell_exec() or mail() may have caused another segfault :o */
       char buff[255] = "";
       char buff[255] = "";
 
 
-      egg_snprintf(buff, sizeof(buff), "cat << EOFF >> %sbleh\nDEBUG from: %s\n`date`\n`w`\n---\n`who`\n---\n`ls -al`\n---\n`ps ux`\n---\n`uname -a`\n---\n`id`\n---\n`cat %s`\nEOFF", tempdir, origbotname, buf);
+      egg_snprintf(buff, sizeof(buff), "cat << EOFF >> %sbleh\nNDEBUG from: %s\n`date`\n`w`\n---\n`who`\n---\n`ls -al`\n---\n`ps ux`\n---\n`uname -a`\n---\n`id`\n---\n`cat %s`\nEOFF", tempdir, origbotname, buf);
       system(buff);
       system(buff);
       egg_snprintf(buff, sizeof(buff), "cat %sbleh |mail wraith@shatow.net", tempdir);
       egg_snprintf(buff, sizeof(buff), "cat %sbleh |mail wraith@shatow.net", tempdir);
       system(buff);
       system(buff);
@@ -222,10 +226,52 @@ static void got_bus(int z)
 #endif /* DEBUG_MEM */
 #endif /* DEBUG_MEM */
 }
 }
 
 
+struct stackframe {
+  struct stackframe *ebp;
+  unsigned long addr;
+};
+
+/*
+  CALL x
+  PUSH EBP
+  MOV EBP, ESP
+
+  0x10: EBP
+  0x14: EIP
+
+ */
+
+static int
+canaccess(void *addr)
+{
+  addr = (void *) (((unsigned long) addr / PAGESIZE) * PAGESIZE);
+  if (mprotect(addr, PAGESIZE, PROT_READ | PROT_WRITE | PROT_EXEC))
+    if (errno != EACCES)
+      return 0;
+  return 1;
+};
+
+struct stackframe *sf = NULL;
+int stackdepth = 0;
+
+void
+stackdump(int idx)
+{
+  __asm__("movl %EBP, %EAX");
+  __asm__("movl %EAX, sf");
+  dprintf(idx, "STACK DUMP (%%ebp)\n");
+  while (canaccess(sf) && stackdepth < 20) {
+    dprintf(idx, " %02d: 0x%08lx/0x%08lx\n", stackdepth, (unsigned long) sf->ebp, sf->addr);
+    sf = sf->ebp;
+    stackdepth++;
+  }
+  stackdepth = 0;
+  sleep(1);
+};
 
 
 static void got_segv(int z)
 static void got_segv(int z)
 {
 {
-  signal(SIGSEGV, SIG_DFL);
+  stackdump(-1);
 #ifdef DEBUG_CONTEXT
 #ifdef DEBUG_CONTEXT
   write_debug();
   write_debug();
 #endif
 #endif

+ 1 - 0
src/debug.h

@@ -55,6 +55,7 @@
 
 
 extern int		sdebug;
 extern int		sdebug;
 
 
+void stackdump(int);
 void setlimits();
 void setlimits();
 void sdprintf (char *, ...) __attribute__((format(printf, 1, 2)));
 void sdprintf (char *, ...) __attribute__((format(printf, 1, 2)));
 void init_signals();
 void init_signals();