MCPcopy Create free account
hub / github.com/NetHack/NetHack / vms_traceback

Function vms_traceback

sys/vms/vmsunix.c:645–709  ·  view source on GitHub ↗

nethack has detected an internal error; try to give a trace of call stack */

Source from the content-addressed store, hash-verified

643/* nethack has detected an internal error; try to give a trace of call stack
644 */
645void
646vms_traceback(int how) /* 1: exit after traceback; 2: stay in debugger */
647{
648 /* assumes that a static initializer applies to the first union
649 field and that no padding will be placed between len and str */
650 union dbgcmd {
651 struct ascic {
652 unsigned char len; /* 8-bit length prefix */
653 char str[79]; /* could be up to 255, but we don't need so much */
654 } cmd_fields;
655 char cmd[1 + 79];
656 };
657#define DBGCMD(arg) { (unsigned char) (sizeof arg - sizeof ""), arg }
658 static union dbgcmd dbg[3] = {
659 /* prologue for less verbose feedback (when combined with
660 $ define/User_mode dbg$output _NL: ) */
661 DBGCMD("set Log SYS$OUTPUT: ; set Output Log,noTerminal,noVerify"),
662 /* enable modules with calls present on stack, then show those calls;
663 limit traceback to 18 stack frames to avoid scrolling off screen
664 (could check termcap LI and maybe give more, but we're operating
665 in a last-gasp environment so apply the KISS principle...) */
666 DBGCMD("set Module/Calls ; show Calls 18"),
667 /* epilogue; "exit" ends the sequence it's part of, but it doesn't
668 seem able to cause program termination when used separately;
669 instead of relying on it, we'll redirect debugger input to come
670 from the null device so that it'll get an end-of-input condition
671 when it tries to get a command from the user */
672 DBGCMD("exit"),
673 };
674#undef DBGCMD
675
676 /*
677 * If we've been linked /noTraceback then we can't provide any
678 * trace of the call stack. Linking that way is required if
679 * nethack.exe is going to be installed with privileges, so the
680 * SECURE configuration usually won't have any trace feedback.
681 */
682 if (!debuggable) {
683 ; /* debugger not available to catch lib$signal(SS$_DEBUG) */
684 } else if (how == 2) {
685 /* omit prologue and epilogue (dbg[0] and dbg[2]) */
686 (void) lib$signal(SS$_DEBUG, 1, dbg[1].cmd);
687 } else if (how == 1) {
688 /*
689 * Suppress most of debugger's initial feedback to avoid scaring
690 * users (and scrolling panic message off the screen). Also control
691 * debugging environment to try to prevent unexpected complications.
692 */
693 /* start up with output going to /dev/null instead of stdout;
694 once started, output is sent to log file that's actually stdout */
695 (void) vms_define("DBG$OUTPUT", "_NL:", 0);
696 /* take input from null device so debugger will see end-on-input
697 and quit if/when it tries to get a command from the user */
698 (void) vms_define("DBG$INPUT", "_NL:", 0);
699 /* bypass any debugger initialization file the user might have */
700 (void) vms_define("DBG$INIT", "_NL:", 0);
701 /* force tty interface by suppressing DECwindows/Motif interface */
702 (void) vms_define("DBG$DECW$DISPLAY", " ", 0);

Callers 1

NH_abortFunction · 0.85

Calls 2

vms_defineFunction · 0.85
vms_exitFunction · 0.85

Tested by

no test coverage detected