|
@@ -8,6 +8,9 @@
|
|
#endif
|
|
#endif
|
|
#include <signal.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
|
+#ifdef DUMPSTACK
|
|
|
|
+#include <execinfo.h>
|
|
|
|
+#endif
|
|
|
|
|
|
#include "../common/mmo.h"
|
|
#include "../common/mmo.h"
|
|
#include "core.h"
|
|
#include "core.h"
|
|
@@ -31,6 +34,37 @@ void set_termfunc(void (*termfunc)(void))
|
|
term_func = termfunc;
|
|
term_func = termfunc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Added by Gabuzomeu
|
|
|
|
+//
|
|
|
|
+// This is an implementation of signal() using sigaction() for portability.
|
|
|
|
+// (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
|
|
|
|
+// Programming in the UNIX Environment_.
|
|
|
|
+//
|
|
|
|
+#ifndef SIGPIPE
|
|
|
|
+#define SIGPIPE SIGINT
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#ifndef POSIX
|
|
|
|
+#define compat_signal(signo, func) signal(signo, func)
|
|
|
|
+#else
|
|
|
|
+sigfunc *compat_signal(int signo, sigfunc *func)
|
|
|
|
+{
|
|
|
|
+ struct sigaction sact, oact;
|
|
|
|
+
|
|
|
|
+ sact.sa_handler = func;
|
|
|
|
+ sigemptyset(&sact.sa_mask);
|
|
|
|
+ sact.sa_flags = 0;
|
|
|
|
+#ifdef SA_INTERRUPT
|
|
|
|
+ sact.sa_flags |= SA_INTERRUPT; /* SunOS */
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (sigaction(signo, &sact, &oact) < 0)
|
|
|
|
+ return (SIG_ERR);
|
|
|
|
+
|
|
|
|
+ return (oact.sa_handler);
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
/*======================================
|
|
/*======================================
|
|
* CORE : Signal Sub Function
|
|
* CORE : Signal Sub Function
|
|
*--------------------------------------
|
|
*--------------------------------------
|
|
@@ -54,6 +88,49 @@ static void sig_proc(int sn)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*=========================================
|
|
|
|
+ * Dumps the stack using glibc's backtrace
|
|
|
|
+ *-----------------------------------------
|
|
|
|
+ */
|
|
|
|
+#ifdef DUMPSTACK
|
|
|
|
+static void sig_dump(int sn)
|
|
|
|
+{
|
|
|
|
+ FILE *fp;
|
|
|
|
+ void* array[20];
|
|
|
|
+
|
|
|
|
+ char **stack;
|
|
|
|
+ size_t size;
|
|
|
|
+ int no = 0;
|
|
|
|
+ char tmp[256];
|
|
|
|
+
|
|
|
|
+ // search for a usable filename
|
|
|
|
+ do {
|
|
|
|
+ sprintf(tmp,"save/stackdump_%04d.txt", ++no);
|
|
|
|
+ } while((fp = fopen(tmp,"r")) && (fclose(fp), no < 9999));
|
|
|
|
+ // dump the trace into the file
|
|
|
|
+ if ((fp = fopen (tmp,"w")) != NULL) {
|
|
|
|
+
|
|
|
|
+ fprintf(fp,"Exception: %s\n", strsignal(sn));
|
|
|
|
+ fprintf(fp,"Stack trace:\n");
|
|
|
|
+ size = backtrace (array, 20);
|
|
|
|
+ stack = backtrace_symbols (array, size);
|
|
|
|
+
|
|
|
|
+ for (no = 0; no < size; no++) {
|
|
|
|
+
|
|
|
|
+ fprintf(fp, "%s\n", stack[no]);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ fprintf(fp,"End of stack trace\n");
|
|
|
|
+
|
|
|
|
+ fclose(fp);
|
|
|
|
+ free(stack);
|
|
|
|
+ }
|
|
|
|
+ // When pass the signal to the system's default handler
|
|
|
|
+ compat_signal(sn, SIG_DFL);
|
|
|
|
+ raise(sn);
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
int get_svn_revision(char *svnentry) { // Warning: minor syntax checking
|
|
int get_svn_revision(char *svnentry) { // Warning: minor syntax checking
|
|
char line[1024];
|
|
char line[1024];
|
|
int rev = 0;
|
|
int rev = 0;
|
|
@@ -110,38 +187,6 @@ static void display_title(void)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-// Added by Gabuzomeu
|
|
|
|
-//
|
|
|
|
-// This is an implementation of signal() using sigaction() for portability.
|
|
|
|
-// (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
|
|
|
|
-// Programming in the UNIX Environment_.
|
|
|
|
-//
|
|
|
|
-#ifndef SIGPIPE
|
|
|
|
-#define SIGPIPE SIGINT
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-#ifndef POSIX
|
|
|
|
-#define compat_signal(signo, func) signal(signo, func)
|
|
|
|
-#else
|
|
|
|
-sigfunc *compat_signal(int signo, sigfunc *func)
|
|
|
|
-{
|
|
|
|
- struct sigaction sact, oact;
|
|
|
|
-
|
|
|
|
- sact.sa_handler = func;
|
|
|
|
- sigemptyset(&sact.sa_mask);
|
|
|
|
- sact.sa_flags = 0;
|
|
|
|
-#ifdef SA_INTERRUPT
|
|
|
|
- sact.sa_flags |= SA_INTERRUPT; /* SunOS */
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
- if (sigaction(signo, &sact, &oact) < 0)
|
|
|
|
- return (SIG_ERR);
|
|
|
|
-
|
|
|
|
- return (oact.sa_handler);
|
|
|
|
-}
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-
|
|
|
|
/*======================================
|
|
/*======================================
|
|
* CORE : MAINROUTINE
|
|
* CORE : MAINROUTINE
|
|
*--------------------------------------
|
|
*--------------------------------------
|
|
@@ -160,13 +205,24 @@ int main(int argc,char **argv)
|
|
compat_signal(SIGTERM,sig_proc);
|
|
compat_signal(SIGTERM,sig_proc);
|
|
compat_signal(SIGINT,sig_proc);
|
|
compat_signal(SIGINT,sig_proc);
|
|
|
|
|
|
- // Signal to create coredumps by system when necessary (crash)
|
|
|
|
- compat_signal(SIGSEGV, SIG_DFL);
|
|
|
|
-#ifndef _WIN32
|
|
|
|
- compat_signal(SIGBUS, SIG_DFL);
|
|
|
|
- compat_signal(SIGTRAP, SIG_DFL);
|
|
|
|
-#endif
|
|
|
|
|
|
+#ifndef DUMPSTACK
|
|
|
|
+ // Signal to create coredumps by system when necessary (crash)
|
|
|
|
+ compat_signal(SIGSEGV, SIG_DFL);
|
|
|
|
+ compat_signal(SIGFPE, SIG_DFL);
|
|
compat_signal(SIGILL, SIG_DFL);
|
|
compat_signal(SIGILL, SIG_DFL);
|
|
|
|
+ #ifndef _WIN32
|
|
|
|
+ compat_signal(SIGBUS, SIG_DFL);
|
|
|
|
+ compat_signal(SIGTRAP, SIG_DFL);
|
|
|
|
+ #endif
|
|
|
|
+#else
|
|
|
|
+ compat_signal(SIGSEGV, sig_dump);
|
|
|
|
+ compat_signal(SIGFPE, sig_dump);
|
|
|
|
+ compat_signal(SIGILL, sig_dump);
|
|
|
|
+ #ifndef _WIN32
|
|
|
|
+ compat_signal(SIGBUS, sig_dump);
|
|
|
|
+ compat_signal(SIGTRAP, SIG_DFL);
|
|
|
|
+ #endif
|
|
|
|
+#endif
|
|
|
|
|
|
display_title();
|
|
display_title();
|
|
|
|
|