New server option -E to choose what to do on oops

Three options: abort, crash-dump, nothing.  crash-dump works by
aborting a fork.  It isn't implemented for Windows.

The oops action is no longer tied to daemon mode, but -d still implies
-E abort for convenience.
This commit is contained in:
Markus Armbruster 2008-04-21 21:35:46 +02:00
parent beb8a7ceb4
commit 627e7d452d
4 changed files with 59 additions and 16 deletions

View file

@ -69,7 +69,12 @@
#define hours(x) (60*60*(x)) #define hours(x) (60*60*(x))
#define days(x) (60*60*24*(x)) #define days(x) (60*60*24*(x))
extern int debug; enum oops_action {
OOPS_ABORT,
OOPS_CRASH_DUMP,
OOPS_NOTHING
};
extern enum oops_action oops_action;
/* /*
* If EXPR is true, an internal error occured. * If EXPR is true, an internal error occured.

View file

@ -13,7 +13,10 @@ emp_server \- Empire server
.BI \-e " configfile" .BI \-e " configfile"
] ]
[ [
.BI \-R " random-seed" .BI \-E " action"
]
[
.BI \-R " seed"
] ]
.if \nw \{\ .if \nw \{\
.br .br
@ -42,14 +45,20 @@ pages within the game.
.TP .TP
.B \-d .B \-d
Debug mode. This will prevent the server from forking itself into the Debug mode. This will prevent the server from forking itself into the
background. It will also make it abort when it detects an internal background. Implies -E abort. You normally want to use this flag if
error. You normally want to use this flag if you are running you are running
.B emp_server .B emp_server
from within a debugger. from within a debugger.
.TP .TP
.BI \-e " configfile" .BI \-e " configfile"
Use game configuration in \fIconfigfile\fR. Use game configuration in \fIconfigfile\fR.
.TP .TP
.BI \-E " action"
What to do on recoverable internal error ("oops"): \fBabort\fP,
\fBcrash\-dump\fP (but continue), \fBnothing\fP (default).
.ie \nw \fBcrash-dump\fP is not implemented for Windows.
.el \fBcrash-dump\fP works by aborting a fork of the server process.
.TP
.B \-h .B \-h
Help. Print brief usage information and exit. Help. Print brief usage information and exit.
.if \nw \{\ .if \nw \{\
@ -73,7 +82,7 @@ Uninstall the Windows Service with the specified name.\}
.B \-s .B \-s
Enable thread stack checking. Enable thread stack checking.
.TP .TP
.B \-R " random-seed" .B \-R " seed"
Set the seed for random function. Set the seed for random function.
.TP .TP
.B \-v .B \-v

View file

@ -46,8 +46,7 @@
#include "player.h" #include "player.h"
#include "prototypes.h" #include "prototypes.h"
/* Debugging? If yes call abort() on internal error. */ enum oops_action oops_action = OOPS_ABORT;
int debug = 1;
static char logfile[32]; static char logfile[32];
static int logfd = -1; static int logfd = -1;
@ -133,7 +132,18 @@ int
oops(char *msg, char *file, int line) oops(char *msg, char *file, int line)
{ {
logerror("Oops: %s in %s:%d", msg ? msg : "bug", file, line); logerror("Oops: %s in %s:%d", msg ? msg : "bug", file, line);
if (debug) abort(); switch (oops_action) {
case OOPS_ABORT:
abort();
case OOPS_CRASH_DUMP:
#ifndef _WIN32
if (fork() == 0)
abort();
#endif
/* fall through */
case OOPS_NOTHING:
break;
}
return 1; return 1;
} }

View file

@ -54,6 +54,7 @@
#include "file.h" #include "file.h"
#include "journal.h" #include "journal.h"
#include "land.h" #include "land.h"
#include "match.h"
#include "misc.h" #include "misc.h"
#include "nat.h" #include "nat.h"
#include "nuke.h" #include "nuke.h"
@ -92,13 +93,22 @@ static char pidfname[] = "server.pid";
/* Run as daemon? If yes, detach from controlling terminal etc. */ /* Run as daemon? If yes, detach from controlling terminal etc. */
static int daemonize = 1; static int daemonize = 1;
static void
help(char *program_name, char *complaint)
{
if (complaint)
fprintf(stderr, "%s: %s\n", program_name, complaint);
fprintf(stderr, "Try -h for help.\n");
}
static void static void
print_usage(char *program_name) print_usage(char *program_name)
{ {
printf("Usage: %s [OPTION]...\n" printf("Usage: %s [OPTION]...\n"
" -d debug mode\n" " -d debug mode, implies -E abort\n"
" -e CONFIG-FILE configuration file\n" " -e CONFIG-FILE configuration file\n"
" (default %s)\n" " (default %s)\n"
" -E ACTION what to do on oops: abort, crash-dump, nothing (default)\n"
" -h display this help and exit\n" " -h display this help and exit\n"
#ifdef _WIN32 #ifdef _WIN32
" -i install service `%s'\n" " -i install service `%s'\n"
@ -122,6 +132,7 @@ print_usage(char *program_name)
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
static char *oops_key[] = { "abort", "crash-dump", "nothing", NULL };
int flags = 0; int flags = 0;
#if defined(_WIN32) #if defined(_WIN32)
int install_service_set = 0; int install_service_set = 0;
@ -130,28 +141,36 @@ main(int argc, char **argv)
int remove_service_set = 0; int remove_service_set = 0;
#endif #endif
char *config_file = NULL; char *config_file = NULL;
int op, sig; int op, idx, sig;
unsigned seed = time(NULL); unsigned seed = time(NULL);
debug = 0; oops_action = OOPS_NOTHING;
#ifdef _WIN32 #ifdef _WIN32
# define XOPTS "iI:uU:" # define XOPTS "iI:uU:"
#else #else
# define XOPTS # define XOPTS
#endif #endif
while ((op = getopt(argc, argv, "de:hpsR:v" XOPTS)) != EOF) { while ((op = getopt(argc, argv, "de:E:hpsR:v" XOPTS)) != EOF) {
switch (op) { switch (op) {
case 'p': case 'p':
flags |= EMPTH_PRINT; flags |= EMPTH_PRINT;
/* fall through */ /* fall through */
case 'd': case 'd':
debug = 1; oops_action = OOPS_ABORT;
daemonize = 0; daemonize = 0;
break; break;
case 'e': case 'e':
config_file = optarg; config_file = optarg;
break; break;
case 'E':
idx = stmtch(optarg, oops_key, 0, sizeof(*oops_key));
if (idx < 0) {
help(argv[0], "invalid argument for -E");
return EXIT_FAILURE;
}
oops_action = idx;
break;
#if defined(_WIN32) #if defined(_WIN32)
case 'I': case 'I':
service_name = optarg; service_name = optarg;
@ -179,19 +198,19 @@ main(int argc, char **argv)
print_usage(argv[0]); print_usage(argv[0]);
return EXIT_SUCCESS; return EXIT_SUCCESS;
default: default:
fprintf(stderr, "Try -h for help.\n"); help(argv[0], NULL);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
#if defined(_WIN32) #if defined(_WIN32)
if ((debug || flags || config_file != NULL) && if ((!daemonize || flags || config_file != NULL) &&
remove_service_set) { remove_service_set) {
fprintf(stderr, "Can't use -p, -s, -d or -e with either " fprintf(stderr, "Can't use -p, -s, -d or -e with either "
"-u or -U options\n"); "-u or -U options\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if ((debug || flags) && install_service_set) { if ((!daemonize || flags) && install_service_set) {
fprintf(stderr, "Can't use -d, -p or -s with either " fprintf(stderr, "Can't use -d, -p or -s with either "
"-i or -I options\n"); "-i or -I options\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);