The Science of Debugging
Chapter 5


5.3 Complex Bugs, Complex Logs

There's alot you can do with static printf messages, but there's quite a bit more information out there that you can make available by printing out the values of different variables. I can't think of any good single example that contains all the possible uses, so you'll have to make do with a small set of sample logs:

printf("%s has run perform_immort_vis",GET_NAME(ch));
printf("%s has an invis level of %d",GET_NAME(ch),GET_INVIS_LEV(ch));
printf("One plus two is %f",1.0+2.0);

Hopefully you get the idea. This can help in situations where the bugs are a bit more ... uhm.. complex. Believe it or not, logs don't always work to source bugs, especially crash bugs. This is because - many times, using the more complex printf logs causes the error itself!

Imagine that by the time the thread of execution reaches the perform_immort_vis(), that the pointer to ch has been corrupted. In our case, it's actually being freed half way through the function! It's now set to some random unknown value - that's what's causing the error you want to find!

Well, what do you think happens if you add the line

log("%s has run perform_immort_vis",GET_NAME(ch));

..to perform_immort_vis()? That's right, it'll crash. Doesn't help much.

As always, you want to be careful when you're using the variable argument features of printf(), you need to be doubly careful when you're using them for debugging. Nine times out of ten, you'll cause another crash.

When in doubt, try printing out absolute addresses if you really must, using the %p and %x formats. You may not get the exact data you want, but at least you can tell if it's valid if it's an area that was crashing. Of course, how you can tell a given address is accurate or not is another one of those things you'll have to pick up with experience.



Index
5.2 Simple Bugs, Simple Logs 5.4 Closing notes about logs.