MUSH crashes

MUSH crashes javelin Thu, 2004-03-18 13:41

Ok, your MUSH crashed. It happens. The good news is that if you compiled with debugging enabled (-g, and this is usually the default), you can usually figure out *where* in the code it crashed and *why*. Even if you personally can't correct the problem, such information is exactly what you'd want to post/mail if you were asking for help.

In order to get debugging information, your MUSH crash must have produced a core dump, which is a file called 'core' or 'netmud.core' or something similar in your game directory. This file is usually quite large. On some systems, you must be sure that your MUSH restart script does an 'ulimit -c unlimited' or you won't get complete core files.

You also need a debugger. Most systems have one of the following debugging programs: gdb (ideal), dbx (a good second choice), sdb (ick), adb (very ick). You (or your sysadmin) can ftp the source code for gdb from the GNU ftp site.

Using the gdb or dbx debugger

gdb and dbx are similar, so in the following examples I'll use them interchangably. If you'll be needing a copy of your debugging session to mail out, use the unix 'script' command to log everything ('script buglog', do your debugger stuff, then 'exit').

To run the debugger, go into your MUSH game directory and type:

gdb netmush core

The debugger will tell you how the process died, and what function it was executing at the time.

Getting and using a stack trace

That alone can be useful, but far more useful is a stack trace, which shows not only the function it was executing that caused it to crash, but which function called that fatal function (and with what parameters), which function called that, and so forth, back up to the very top function, main().

The command 'where' will print out a stack trace. The commands 'up' and 'down' will walk you up and down through the stack, showing the values of parameters that are being passed. You can also use the 'p' (print) command to print the values of other variables in each function.

Running the MUSH under gdb

If the crash occurs during the MUSH startup process (when analyzing or loading the db, for example), and doesn't leave a core dump, you have another option if you have gdb. You can actually run the MUSH from within the gdb debugger by going to the game directory and doing:

    gdb netmush
    run mush.cnf log/netmush.log

(According to Rhyanna, on some operating systems, typing 'handle SIGPIPE nostop' before running the mud will prevent the debugger from reporting SIGPIPE signals when players connect.)

When the MUSH crashes, you'll be told how and where, and be returned to gdb to analyze the crash. Gdb and dbx can do much more - you can tell them to run the MUSH until they hit a certain function and then wait for further instructions, step through code one line at a time, etc. Read the manual pages if you need to do these things.

Trashed stacks

Some crashes, alas, overwrite the memory containing the function stack, and produce a totally unhelpful core file. The only help I've found for this is to cross my fingers and run the MUSH again, hoping that the next crash will pick a different memory location to overwrite. In some cases, 'touch'ing all the MUSH source files (touch *.c) and recompiling can help, as can using 'make clean; make', but it's mostly superstition.