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