![]() |
Chapter 5 | ![]() |
If you're going to have to deal with a bug, hope it is a simple, repeatable, dependable bug. You want a bug that you can reproduce with ease, so you can quickly find the source of the problem. If the MUD always crashes when you type 'who', it's a pretty small leap of logic to assume that you're crashing in the do_who code.
If you're getting an error like this, log messages may be the answer. With just a few quick lines of code you can isolate the area where you code is failing. CircleMUD has a standard function called 'log' which - simply enough - prints out a message to the console/controlling terminal. The only difference between this function and just using printf, is that the log function includes a timestamp automatically. It's acutally useful enough that I end up writing a simliar function in most programs I write; of course, I don't use the function name 'log()'. That's insane - log() is a math function.
For our purposes, we'll just use the printf command, which I'm sure you're familiar with. If you want bonus points, go ahead and write something up that's a little more indepth. Aside from timestamping, I usually include a priority level with my logs as well, setting a global variable (or macro) that the logging function checks to determine if it should be displayed or not.
Let's go back to our example in the previous section with grep - we're having a crash with the 'visible' command. One thing to do would be to place log messages infront of each functional part of the code. In this case, I'll use the entire perform_immort_vis() because I have no clue why it's crashing, I'll go overboard so you get the idea.
void perform_immort_vis(struct char_data *ch) { printf("start of perform immort vis\n"); printf("Checking to see if a character is visible already!\n"); if (GET_INVIS_LEV(ch) == 0 && !AFF_FLAGGED(ch, AFF_HIDE | AFF_INVISIBLE)) { send_to_char("You are already fully visible.\r\n", ch); printf("character is already visible, returning\n"); return; } printf("Character is not visible yet\n"); printf("Freeing ch\n"); free(ch); printf("setting invis level to 0\n"); GET_INVIS_LEV(ch) = 0; printf("calling 'appear'\n"); appear(ch); printf("returned from 'appear'\n"); send_to_char("You are now fully visible.\r\n", ch); printf("exiting perform_immort_vis function\n"); }As you can see, I used a bit more than I had to. If this function were really causing crashes, I'd probably just target the call to 'appear()'. If the log message didn't appear, I'd know that it didn't get past the 'is visible already' portion of the code, and if it crashed afterwards, I'd know it was in the 'appear()' code. I'd make the snap assumption that a frequently used stock piece of code like 'send_to_char' was not responsible. This is one of those things that you need experience to guide you on though.
In any new code, you'll probably want to insert logging messages like those above for each piece you're concerned with. Though it is possible to write perfect code the first time, it's not likely, not even for people who are good at it - leaving log messages for debugging purposes is always a good trait. Unfortunately, Circle lacks debug message levels, so you'll probably want to pull those out after you're done with them, instead of just running the mud at a different debug level. Would make an easy project though!
![]() |
Index | ![]() |
5.1 What is it? | 5.3 Complex Bugs, Complex Logs |