VerySillyMUD: A Lesson About Compiler Warnings
Series [ VerySillyMUD ]
This post is part of my “VerySillyMUD” series, chronicling an attempt to refactor an old MUD into working condition [ 1 ].
In our last post, we managed to get the MUD executable to build, and attempted to run it, with somewhat lackluster results:
Fortunately, we get a file and line number with this error, so let’s take a look:
Hmm, we seem to not be able to change into whatever directory is represented by dir. Scrolling up through the source we see that this can be set via a command-line argument:
…but we didn’t provide one, so it must have a default value. A
little further up and we see it gets set to DFLT_DIR
; a quick
grep
gives us:
Aha! It’s looking for the lib
directory, which
doesn’t exist in the src
directory but does exist as a
top-level directory in the project. Let’s try pointing it there:
Great! There are a lot of error messages in here about “unknown auxiliary codes” but the MUD seems to have started. Let’s try to connect as a client:
Ok! Let’s proceed and create a character to play:
A quick look over at the terminal where the server was running shows this in the log:
Oh, joy. Looks like we’ll have to run this in a debugger to see where it’s barfing.
Uh, this is segfaulting in a C library routine? What’s going on here? The source code line where this is happening is:
A little more poking around in the debugger shows that all the
pointers here (d->pwd
, arg
, and
d->character->player.name
) are all well-formatted,
null-terminated strings. What’s going on?
I will spare you, good reader, quite a bit of head scratching and
Googling, but here’s ultimately what happened: there is no function
prototype for crypt()
defined or included in this source code
file, and the C compiler is making the assumption that it returns an
int
, which is a 32-bit quantity. In actuality, crypt
returns a char *
, which on a 64-bit machine like I have, is a
64-bit value; the return value is getting truncated, and when it is
likewise passed to strncpy
that expects a pointer, we’re off
again, and the pointer passed in is essentially garbage. Now that I’ve
figured out what the issue is, I would not be surprised if we had a
compiler warning about this. Sure enough:
Remember when I said previously that I was generally a fan of “treat compiler warnings as errors”? Looks like I should have taken my own advice. In the next episode, I’ll go ahead and clean all of those up.
[ 1 ] SillyMUD was a derivative of DikuMUD, which was originally created by Sebastian Hammer, Michael Seifert, Hans Henrik Stærfeldt, Tom Madsen, and Katja Nyboe.