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 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.

View file

@ -13,7 +13,10 @@ emp_server \- Empire server
.BI \-e " configfile"
]
[
.BI \-R " random-seed"
.BI \-E " action"
]
[
.BI \-R " seed"
]
.if \nw \{\
.br
@ -42,14 +45,20 @@ pages within the game.
.TP
.B \-d
Debug mode. This will prevent the server from forking itself into the
background. It will also make it abort when it detects an internal
error. You normally want to use this flag if you are running
background. Implies -E abort. You normally want to use this flag if
you are running
.B emp_server
from within a debugger.
.TP
.BI \-e " configfile"
Use game configuration in \fIconfigfile\fR.
.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
Help. Print brief usage information and exit.
.if \nw \{\
@ -73,7 +82,7 @@ Uninstall the Windows Service with the specified name.\}
.B \-s
Enable thread stack checking.
.TP
.B \-R " random-seed"
.B \-R " seed"
Set the seed for random function.
.TP
.B \-v

View file

@ -46,8 +46,7 @@
#include "player.h"
#include "prototypes.h"
/* Debugging? If yes call abort() on internal error. */
int debug = 1;
enum oops_action oops_action = OOPS_ABORT;
static char logfile[32];
static int logfd = -1;
@ -133,7 +132,18 @@ int
oops(char *msg, char *file, int 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;
}

View file

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