split some code into separate files

new .h files: hacklib.h selvar.h stairs.h

new .c files: calendar.c, getpos.c, report.c, selvar.c, stairs.c,
              strutil.c, wizcmds.c

cleanup of hacklib.c and mdlib.c

hacklib contains functions that do not have to link with the core

relocate wiz commands from cmd.c to wizcmds.c

relocate CRASHREPORT stuff to report.c

relocate getpos stuff from do_name.c to getpos.c

remove temporary struct definition from extern.h

cross-compile PRE-section split into cross-pre1.370 and cross-pre2.370

Windows sys/windows/Makefile.nmake and sys/windows/Makefile.mingw32 and
visual studio project file updates

Unix sys/unix/Makefile.src, sys/unix/Makefile.utl

populate selvar.c and selvar.h

build on MS-DOS (not cross-compile) Makefile updates
for sys/msdos/Makefile.GCC (untested)

vms updates for above (untested)
This commit is contained in:
nhmall
2024-03-07 11:01:04 -05:00
parent c22900fb63
commit 50811037f3
43 changed files with 5913 additions and 5677 deletions
+82 -695
View File
@@ -37,9 +37,6 @@ static boolean should_query_disclose_option(int, char *);
static void dump_plines(void);
#endif
static void dump_everything(int, time_t);
#ifdef CRASHREPORT
static const char *get_saved_pline(int);
#endif
static void fixup_death(int);
static int wordcount(char *);
static void bel_copy1(char **, char *);
@@ -70,673 +67,6 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN;
#endif /* !SYSV */
#endif /* !AMIGA */
/* NB: CRASHREPORT implies PANICTRACE */
#if defined(PANICTRACE)
#include <errno.h>
#ifdef PANICTRACE_LIBC
#include <execinfo.h>
#endif
/* What do we try to in what order? Tradeoffs:
* libc: +no external programs required
* -requires newish libc/glibc
* -requires -rdynamic
* gdb: +gives more detailed information
* +works on more OS versions
* -requires -g, which may preclude -O on some compilers
*
* And the UI: if sysopt.crashreporturl, and defined(CRASHREPORT)
* we gather the stacktrace (etc) and launch a browser to submit a bug report
* otherwise we just use stdout. Requires libc for now.
*/
#ifdef SYSCF
# define SYSOPT_PANICTRACE_GDB sysopt.panictrace_gdb
# ifdef PANICTRACE_LIBC
# define SYSOPT_PANICTRACE_LIBC sysopt.panictrace_libc
# else
# define SYSOPT_PANICTRACE_LIBC 0
# endif
#else
# define SYSOPT_PANICTRACE_GDB (nh_getenv("NETHACK_USE_GDB") == 0 ? 0 : 2)
# ifdef PANICTRACE_LIBC
# define SYSOPT_PANICTRACE_LIBC 1
# else
# define SYSOPT_PANICTRACE_LIBC 0
# endif
#endif
static void NH_abort(char *);
#ifndef NO_SIGNAL
static void panictrace_handler(int);
#endif
static boolean NH_panictrace_libc(void);
static boolean NH_panictrace_gdb(void);
#ifndef NO_SIGNAL
/* called as signal() handler, so sent at least one arg */
/*ARGUSED*/
void
panictrace_handler(int sig_unused UNUSED)
{
#define SIG_MSG "\nSignal received.\n"
int f2;
#ifdef CURSES_GRAPHICS
if (iflags.window_inited && WINDOWPORT(curses)) {
extern void curses_uncurse_terminal(void); /* wincurs.h */
/* it is risky calling this during a program-terminating signal,
but without it the subsequent backtrace is useless because
that ends up being scrawled all over the screen; call is
here rather than in NH_abort() because panic() calls both
exit_nhwindows(), which makes this same call under curses,
then NH_abort() and we don't want to call this twice */
curses_uncurse_terminal();
}
#endif
f2 = (int) write(2, SIG_MSG, sizeof SIG_MSG - 1);
nhUse(f2); /* what could we do if write to fd#2 (stderr) fails */
NH_abort(NULL); /* ... and we're already in the process of quitting? */
}
void
panictrace_setsignals(boolean set)
{
#define SETSIGNAL(sig) \
(void) signal(sig, set ? (SIG_RET_TYPE) panictrace_handler : SIG_DFL);
#ifdef SIGILL
SETSIGNAL(SIGILL);
#endif
#ifdef SIGTRAP
SETSIGNAL(SIGTRAP);
#endif
#ifdef SIGIOT
SETSIGNAL(SIGIOT);
#endif
#ifdef SIGBUS
SETSIGNAL(SIGBUS);
#endif
#ifdef SIGFPE
SETSIGNAL(SIGFPE);
#endif
#ifdef SIGSEGV
SETSIGNAL(SIGSEGV);
#endif
#ifdef SIGSTKFLT
SETSIGNAL(SIGSTKFLT);
#endif
#ifdef SIGSYS
SETSIGNAL(SIGSYS);
#endif
#ifdef SIGEMT
SETSIGNAL(SIGEMT);
#endif
#undef SETSIGNAL
}
#endif /* NO_SIGNAL */
#ifdef CRASHREPORT
#define USED_FOR_CRASHREPORT
#else
#define USED_FOR_CRASHREPORT UNUSED
#endif
static void
NH_abort(char *why USED_FOR_CRASHREPORT)
{
int gdb_prio = SYSOPT_PANICTRACE_GDB;
int libc_prio = SYSOPT_PANICTRACE_LIBC;
static volatile boolean aborting = FALSE;
/* don't execute this code recursively if a second abort is requested
while this routine or the code it calls is executing */
if (aborting)
return;
aborting = TRUE;
#ifdef CRASHREPORT
if(!submit_web_report(1, "Panic", why))
#endif
{
#ifndef VMS
if (gdb_prio == libc_prio && gdb_prio > 0)
gdb_prio++;
if (gdb_prio > libc_prio) {
(void) (NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc()));
} else {
(void) (NH_panictrace_libc() || (gdb_prio && NH_panictrace_gdb()));
}
#else /* VMS */
/* overload otherwise unused priority for debug mode: 1 = show
traceback and exit; 2 = show traceback and stay in debugger */
/* if (wizard && gdb_prio == 1) gdb_prio = 2; */
vms_traceback(gdb_prio);
nhUse(libc_prio);
#endif /* ?VMS */
}
#ifndef NO_SIGNAL
panictrace_setsignals(FALSE);
#endif
NH_abort_;
}
#undef USED_FOR_CRASHREPORT
#ifdef CRASHREPORT
# include <fcntl.h>
# ifdef WIN32
# define HASH_PRAGMA_START
# define HASH_PRAGMA_END
# else
# define HASH_PRAGMA_START \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
# define HASH_PRAGMA_END _Pragma("GCC diagnostic pop");
# endif
# ifdef MACOS
# include <CommonCrypto/CommonDigest.h>
# define HASH_CONTEXTPTR(CTXP) \
unsigned char tmp[CC_MD4_DIGEST_LENGTH]; \
CC_MD4_CTX CTXP ## _; \
CC_MD4_CTX *CTXP = &CTXP ## _
# define HASH_INIT(ctxp) !CC_MD4_Init(ctxp)
# define HASH_UPDATE(ctx, ptr, len) !CC_MD4_Update(ctx, ptr, len)
# define HASH_FINISH(ctxp) !CC_MD4_Final(tmp, ctxp)
# define HASH_RESULT_SIZE(ctxp) CC_MD4_DIGEST_LENGTH
# define HASH_RESULT(ctx, inp) *inp = (unsigned char *) ctx
# define HASH_CLEANUP(ctxp)
# define HASH_OFLAGS O_RDONLY
# define HASH_BINFILE_DECL char *binfile = argv[0];
# ifdef BETA
# define HASH_BINFILE \
if (!binfile || !*binfile) { \
/* If this triggers, investigate CFBundleGetMainBundle */ \
/* or CFBundleCopyExecutableURL. */ \
raw_print( \
"BETA warning: crashreport_init called without useful info"); \
goto skip; \
}
# else
# define HASH_BINFILE() \
if (!binfile || !*binfile) { \
goto skip; \
}
# endif
# endif
# ifdef __linux__
# include "nhmd4.h"
# define HASH_CONTEXTPTR(CTXP) \
unsigned char tmp[NHMD4_DIGEST_LENGTH]; \
NHMD4_CTX CTXP ## _; \
NHMD4_CTX *CTXP = &CTXP ## _
# define HASH_INIT(ctxp) (nhmd4_init(ctxp), 0)
# define HASH_UPDATE(ctx, ptr, len) (nhmd4_update(ctx, ptr, len), 0)
# define HASH_FINISH(ctxp) (nhmd4_final(ctxp, tmp), 0)
# define HASH_RESULT_SIZE(ctxp) NHMD4_RESULTLEN
# define HASH_RESULT(ctx, inp) *inp = tmp
# define HASH_CLEANUP(ctxp)
# define HASH_OFLAGS O_RDONLY
# define HASH_BINFILE_DECL char binfile[PATH_MAX+1];
# define HASH_BINFILE() \
int len = readlink("/proc/self/exe", binfile, sizeof binfile - 1); \
if (len > 0) { \
binfile[len] = '\0'; \
} else { \
goto skip; \
}
# endif // __linux__
# ifdef WIN32
/* WIN32 takes too much code and is dependent on OS includes we can't
* pull in here, so we call out to code in sys/windows/windsys.c */
# define HASH_CONTEXTPTR(CTXP)
# define HASH_INIT(ctxp) win32_cr_helper('i', ctxp, NULL, 0)
# define HASH_UPDATE(ctxp, ptr, len) win32_cr_helper('u', ctxp, ptr, len)
# define HASH_FINISH(ctxp) win32_cr_helper('f', ctxp, NULL, 0)
# define HASH_CLEANUP(ctxp) win32_cr_helper('c', ctxp, NULL, 0)
# define HASH_RESULT_SIZE(ctxp) win32_cr_helper('s', ctxp, NULL, 0)
# define HASH_RESULT(ctxp, inp) win32_cr_helper('r', ctxp, inp, 0)
# define HASH_OFLAGS _O_RDONLY | _O_BINARY
# define HASH_BINFILE_DECL char *binfile;
# define HASH_BINFILE() \
if (win32_cr_helper('b', NULL, &binfile, 0)) { \
goto skip; \
}
# endif // WIN32
/* Binary ID - Use only as a hint to contact.html for recognizing our own
binaries. This is easily spoofed! */
static char bid[40];
/* ARGSUSED */
void
crashreport_init(int argc UNUSED, char *argv[] UNUSED)
{
static int once = 0;
if (once++) /* NetHackW.exe calls us twice */
return;
HASH_BINFILE_DECL;
HASH_PRAGMA_START
HASH_CONTEXTPTR(ctxp);
if (HASH_INIT(ctxp))
goto skip;
HASH_BINFILE(); /* Does "goto skip" on error. */
int fd = open(binfile, HASH_OFLAGS, 0);
if (fd == -1) {
# ifdef BETA
raw_printf("open e=%s", strerror(errno));
# endif
goto skip;
}
int segsize;
unsigned char segment[4096];
while (0 < (segsize = read(fd, segment, sizeof segment))) {
if (HASH_UPDATE(ctxp, segment, segsize))
goto skip;
}
if (segsize < 0) {
close(fd);
goto skip;
}
if (HASH_FINISH(ctxp))
goto skip;
close(fd);
static const char hex[] = "0123456789abcdef";
char *p = bid;
unsigned char *in;
HASH_RESULT(ctxp, &in);
uint8 cnt = (uint8) HASH_RESULT_SIZE(ctxp);
/* Just in case, make sure not to overflow the bid buffer.
Divide size by 2 because each octet in the hash uses two slots
in bid[] when formatted as a pair of hexadecimal digits. */
if (cnt >= (uint8) sizeof bid / 2)
cnt = (uint8) sizeof bid / 2 - 1;
while (cnt) {
/* sprintf(p, "%02x", *in++), p += 2; */
*p++ = hex[(*in >> 4) & 0x0f];
*p++ = hex[*in++ & 0x0f];
--cnt;
}
*p = '\0';
return;
skip:
Strcpy(bid, "unknown");
HASH_CLEANUP(ctxp);
HASH_PRAGMA_END
}
#undef HASH_CONTEXTPTR
#undef HASH_INIT
#undef HASH_UPDATE
#undef HASH_FINISH
#undef HASH_CLEANUP
#undef HASH_RESULT
#undef HASH_RESULT_SIZE
#undef HASH_PRAGMA_START
#undef HASH_PRAGMA_END
#undef HASH_BINFILE_DECL
#undef HASH_BINFILE
void
crashreport_bidshow(void)
{
#if defined(WIN32) && !defined(WIN32CON)
if (0 == win32_cr_helper('D', ctxp, bid, 0))
#endif
{
raw_print(bid);
#ifdef WIN32notyet
wait_synch();
#endif
}
}
/* Build a URL with a query string and try to launch a new browser window
* to report from panic() or impossible(). Requires libc support for
* the stacktrace. Uses memory on the stack to avoid memory allocation
* (on most platforms) (but libc can still do anything it wants). */
// No theoretial limit for URL length but reality is messy.
// This should work on all modern platforms.
#ifndef MAX_URL
# define MAX_URL 8192
#endif
#ifndef SWR_FRAMES
# define SWR_FRAMES 20
#endif
// mark holds the initial eos; if we can't get the value in
// then we can remove the whole item if desired. For other
// semantics, caller can handle mark.
#define SWR_ADD(str) \
utmp = strlen(str); \
mark = uend; \
if (utmp >= urem) \
goto full; \
strncpy(uend, str, utmp); \
uend += utmp; urem -= utmp; \
*uend = '\0';
// NB: on overflow this rolls us back to mark, so if we don't
// want to roll back to the last SWR_ADD, update mark before
// calling this macro.
#define SWR_ADD_URIcoded(str) \
if (swr_add_uricoded(str, &uend, &urem, mark)) \
goto full;
/* On overflow, truncate to markp (but only if markp != NULL). */
boolean
swr_add_uricoded(
const char *in,
char **out,
int *remaining,
char *markp)
{
while (*in) {
if (isalnum(*in) || strchr("_-.~", *in)) {
**out = *in;
(*out)++;
(*remaining)--;
} else if (*in == ' ') {
**out = '+';
(*out)++;
(*remaining)--;
} else {
if (*remaining <= 3) {
if (markp)
*out = markp, *remaining = 0;
**out = '\0';
return TRUE;
}
int x = snprintf(*out, *remaining, "%%%02X", *in);
*out += x;
*remaining -= x;
}
in++;
if (!*remaining) {
if (markp)
*out = markp, *remaining = 0;
**out = '\0';
return TRUE;
}
**out = '\0';
}
return FALSE; /* normal return */
}
static char url[MAX_URL]; // XXX too bad this isn't allocated as needed
static int urem = MAX_URL; // adjusted for gc.crash_urlmax below
static char *uend = url;
static int utmp; // used inside macros
static char *mark; // holds previous terminator (generally)
boolean
submit_web_report(int cos, const char *msg, const char *why)
{
urem = (gc.crash_urlmax < 0 || gc.crash_urlmax > MAX_URL)
? MAX_URL : min(MAX_URL,gc.crash_urlmax);
char temp[200];
char temp2[200];
int countpp = 0; /* pre and post traceback lines */
// URL loaded for creating reports to the NetHack DevTeam
// CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html
if (!sysopt.crashreporturl)
return FALSE;
SWR_ADD(sysopt.crashreporturl);
/* cos - operation, v - version */
Snprintf(temp, sizeof temp, "?cos=%d&v=1", cos);
SWR_ADD(temp);
/* msg==NULL for #bugreport */
if (msg) {
SWR_ADD("&subject=");
Snprintf(temp, sizeof temp, "%s report for NetHack %s",
msg, version_string(temp2, sizeof temp2 ));
SWR_ADD_URIcoded(temp);
}
SWR_ADD("&gitver=");
SWR_ADD_URIcoded(getversionstring(temp2, sizeof temp2));
if (gc.crash_name) {
SWR_ADD("&name=");
SWR_ADD_URIcoded(gc.crash_name);
}
if(gc.crash_email) {
SWR_ADD("&email=");
SWR_ADD_URIcoded(gc.crash_email);
}
// hardware: leave for user
// software: leave for user
// comments: leave for user
SWR_ADD("&details=");
if (why) {
SWR_ADD_URIcoded(why);
SWR_ADD_URIcoded("\n");
mark = uend;
countpp++;
}
SWR_ADD_URIcoded("bid: ");
SWR_ADD_URIcoded(bid);
SWR_ADD_URIcoded("\n");
mark = uend;
countpp++;
int count = 0;
if (cos == 1) {
#ifdef WIN32
count = win32_cr_gettrace(SWR_FRAMES, uend, MAX_URL - (uend - url));
uend = eos(url);
#else
void *bt[SWR_FRAMES];
int x;
char **info;
count = backtrace(bt, SIZE(bt));
info = backtrace_symbols(bt, count);
for (x = 0; x < count; x++) {
copynchars(temp, info[x], (int) sizeof temp - 1 - 1); /* \n\0 */
/* try to remove up to 16 blank spaces by removing 8 twice */
(void) strsubst(temp, " ", "");
(void) strsubst(temp, " ", "");
(void) strncat(temp, "\n", sizeof temp - 1);
# if 0 // __linux__
// not needed for MacOS
// XXX is it actually needed for linux? TBD
Snprintf(temp2, sizeof temp2, "[%02lu]\n", (unsigned long) x);
uend--; // remove the \n we added above
SWR_ADD_URIcoded(temp2);
# endif // linux
SWR_ADD_URIcoded(temp);
mark = uend;
}
#endif // !WIN32
}
#ifdef DUMPLOG_CORE
// config.h turns this on, but make it easy to turn off if needed
if (cos == 1) {
int k;
SWR_ADD_URIcoded("Latest messages:\n");
mark=uend;
countpp++;
for (k = 0; k < 5; k++) {
const char *line = get_saved_pline(k);
if (!line)
break;
SWR_ADD_URIcoded(line);
SWR_ADD_URIcoded("\n");
countpp++;
mark = uend;
}
}
#endif
// detailrows: Guess since we can't know the
// width of the window.
SWR_ADD("&detailrows=");
Snprintf(temp, sizeof temp, "%d", min(count + countpp, 30));
SWR_ADD_URIcoded(temp);
full:
;
//printf("URL=%ld '%s'\n",strlen(url),url);
#ifdef WIN32
int *rv = win32_cr_shellexecute(url);
// XXX TESTING
printf("ShellExecute returned: %p\n",rv); // >32 is ok
#else
const char *xargv[] = {
CRASHREPORT,
url,
NULL
};
int pid = fork();
extern char **environ;
if (pid == 0) {
char err[100];
#ifdef CRASHREPORT_EXEC_NOSTDERR
/* Keep the output clean - firefox spews useless errors on
* my system. */
(void) close(2);
(void) open("/dev/null", O_WRONLY);
#endif
(void) execve(CRASHREPORT, (char * const *) xargv, environ);
Sprintf(err, "Can't start " CRASHREPORT ": %s", strerror(errno));
raw_print(err);
} else {
int status;
errno = 0;
(void) waitpid(pid, &status, 0);
if (status) { /* XXX check could be more precise */
#ifdef BETA
/* Not useful at the moment. XXX */
char err[100];
Sprintf(err, "pid=%d e=%d status=%0x", wpid, errno, status);
raw_print(err);
#endif
return FALSE;
}
}
/* free(info); -- Don't risk it. */
#endif
return TRUE;
}
int
dobugreport(void)
{
if (!submit_web_report(2, NULL, "#bugreport command")) {
pline("Unable to send bug report. Please visit %s instead.",
(sysopt.crashreporturl && *sysopt.crashreporturl)
? sysopt.crashreporturl
: "https://www.nethack.org"
);
}
return ECMD_OK;
}
#endif /* CRASHREPORT */
#undef SWR_ADD
#undef SWR_ADD_URIcoded
#undef SWR_FRAMES
#undef SWR_HDR
#undef SWR_LINES
/*ARGSUSED*/
static boolean
NH_panictrace_libc(void)
{
#if 0 /* XXX how did this get left here? */
#ifdef CRASHREPORT
if (submit_web_report("Panic", why))
return TRUE;
#endif
#endif
#ifdef PANICTRACE_LIBC
void *bt[20];
int count, x;
char **info, buf[BUFSZ];
raw_print(" Generating more information you may report:\n");
count = backtrace(bt, SIZE(bt));
info = backtrace_symbols(bt, count);
for (x = 0; x < count; x++) {
copynchars(buf, info[x], (int) sizeof buf - 1);
/* try to remove up to 16 blank spaces by removing 8 twice */
(void) strsubst(buf, " ", "");
(void) strsubst(buf, " ", "");
raw_printf("[%02lu] %s", (unsigned long) x, buf);
}
/* free(info); -- Don't risk it. */
return TRUE;
#else
return FALSE;
#endif /* !PANICTRACE_LIBC */
}
/*
* fooPATH file system path for foo
* fooVAR (possibly const) variable containing fooPATH
*/
#ifdef PANICTRACE_GDB
# ifdef SYSCF
# define GDBVAR sysopt.gdbpath
# define GREPVAR sysopt.greppath
# else /* SYSCF */
# define GDBVAR GDBPATH
# define GREPVAR GREPPATH
# endif /* SYSCF */
#endif /* PANICTRACE_GDB */
static boolean
NH_panictrace_gdb(void)
{
#ifdef PANICTRACE_GDB
/* A (more) generic method to get a stack trace - invoke
* gdb on ourself. */
const char *gdbpath = GDBVAR;
const char *greppath = GREPVAR;
char buf[BUFSZ];
FILE *gdb;
if (gdbpath == NULL || gdbpath[0] == 0)
return FALSE;
if (greppath == NULL || greppath[0] == 0)
return FALSE;
sprintf(buf, "%s -n -q %s %d 2>&1 | %s '^#'",
gdbpath, ARGV0, getpid(), greppath);
gdb = popen(buf, "w");
if (gdb) {
raw_print(" Generating more information you may report:\n");
fprintf(gdb, "bt\nquit\ny");
fflush(gdb);
sleep(4); /* ugly */
pclose(gdb);
return TRUE;
} else {
return FALSE;
}
#else
return FALSE;
#endif /* !PANICTRACE_GDB */
}
#endif /* PANICTRACE */
/*
* The order of these needs to match the macros in hack.h.
*/
@@ -1222,31 +552,6 @@ dump_plines(void)
}
#endif /* DUMPLOG */
#ifdef CRASHREPORT
/* lineno==0 gives the most recent message (e.g.
"Do you want to call panic..." if called from #panic) */
static const char *
get_saved_pline(int lineno)
{
int p;
int limit = DUMPLOG_MSG_COUNT;
if (lineno >= DUMPLOG_MSG_COUNT)
return NULL;
p = (gs.saved_pline_index - 1) % DUMPLOG_MSG_COUNT;
while (limit--) {
if (gs.saved_plines[p]) { /* valid line */
if (lineno--) {
p = (p - 1 + DUMPLOG_MSG_COUNT) % DUMPLOG_MSG_COUNT;
} else {
return gs.saved_plines[p];
}
}
}
return NULL;
}
#endif /* CRASHREPORT */
/*ARGSUSED*/
static void
dump_everything(
@@ -2556,4 +1861,86 @@ build_english_list(char *in)
return out;
}
/* What do we try to in what order? Tradeoffs:
* libc: +no external programs required
* -requires newish libc/glibc
* -requires -rdynamic
* gdb: +gives more detailed information
* +works on more OS versions
* -requires -g, which may preclude -O on some compilers
*
* And the UI: if sysopt.crashreporturl, and defined(CRASHREPORT)
* we gather the stacktrace (etc) and launch a browser to submit a bug report
* otherwise we just use stdout. Requires libc for now.
*/
# ifdef SYSCF
# define SYSOPT_PANICTRACE_GDB sysopt.panictrace_gdb
# ifdef PANICTRACE_LIBC
# define SYSOPT_PANICTRACE_LIBC sysopt.panictrace_libc
# else
# define SYSOPT_PANICTRACE_LIBC 0
# endif
# else
# define SYSOPT_PANICTRACE_GDB (nh_getenv("NETHACK_USE_GDB") == 0 ? 0 : 2)
# ifdef PANICTRACE_LIBC
# define SYSOPT_PANICTRACE_LIBC 1
# else
# define SYSOPT_PANICTRACE_LIBC 0
# endif
# endif
# ifdef CRASHREPORT
#define USED_FOR_CRASHREPORT
# else
#define USED_FOR_CRASHREPORT UNUSED
# endif
void
NH_abort(char *why USED_FOR_CRASHREPORT)
{
#ifdef PANICTRACE
int gdb_prio = SYSOPT_PANICTRACE_GDB;
int libc_prio = SYSOPT_PANICTRACE_LIBC;
#endif
static volatile boolean aborting = FALSE;
/* don't execute this code recursively if a second abort is requested
while this routine or the code it calls is executing */
if (aborting)
return;
aborting = TRUE;
#ifdef PANICTRACE
#ifdef CRASHREPORT
if(!submit_web_report(1, "Panic", why))
#endif
{
#ifndef VMS
if (gdb_prio == libc_prio && gdb_prio > 0)
gdb_prio++;
if (gdb_prio > libc_prio) {
(void) (NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc()));
} else {
(void) (NH_panictrace_libc() || (gdb_prio && NH_panictrace_gdb()));
}
#else /* VMS */
/* overload otherwise unused priority for debug mode: 1 = show
traceback and exit; 2 = show traceback and stay in debugger */
/* if (wizard && gdb_prio == 1) gdb_prio = 2; */
vms_traceback(gdb_prio);
nhUse(libc_prio);
#endif /* ?VMS */
}
#ifndef NO_SIGNAL
panictrace_setsignals(FALSE);
#endif
#endif /* PANICTRACE */
NH_abort_;
}
#undef USED_FOR_CRASHREPORT
/*end.c*/