<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> <title>Dead Souls debugging</title> <link rel="icon" href="./favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="./favicon.ico" type="image/x-icon"> </head> <body> <big style="font-family: courier new,courier,monospace;"><big><big><span style="font-weight: bold;">Debugging in Dead Souls</span></big></big></big><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">So you've made some cool stuff but darn it, it doesn't work. There are various</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">tools available in the Dead Souls lib to hunt down the source of the problem:</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <a style="font-family: courier new,courier,monospace;" href="#1">1 elog</a><br style="font-family: courier new,courier,monospace;"> <a style="font-family: courier new,courier,monospace;" href="#2">2 dbxframe and dbxwhere</a><br style="font-family: courier new,courier,monospace;"> <a style="font-family: courier new,courier,monospace;" href="#3">3 tell_player() and debug()</a><br style="font-family: courier new,courier,monospace;"> <a style="font-family: courier new,courier,monospace;" href="#4">4 tail</a><br style="font-family: courier new,courier,monospace;"> <a style="font-family: courier new,courier,monospace;" href="#5">5 bk and restore</a><br style="font-family: courier new,courier,monospace;"> <br> <br style="font-family: courier new,courier,monospace;"> <big style="font-family: courier new,courier,monospace;"><big style="font-weight: bold; text-decoration: underline;"><big><a name="1"></a>elog</big></big></big><br style="font-family: courier new,courier,monospace;"> <pre style="font-family: courier new,courier,monospace;"><big>If the file is somewhere in your home directory, just type: <span style="font-weight: bold;">elog</span> <br><br>This will provide you a listing of the last few lines of your personal<br>error log. Warning lines tell you about code that works but should<br>be fixed in some way. Lines that don't contain the word "Warning" are<br>error lines: they indicate something about your code that prevents<br>it from working. For example:<br><br></big></pre> <hr style="width: 100%; height: 2px; font-family: courier new,courier,monospace;"><span style="font-family: courier new,courier,monospace;">> </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">update sample_room</span><br style="font-family: courier new,courier,monospace;"> <pre style="font-family: courier new,courier,monospace;"><big><span style="font-style: italic;"></span><span style="font-style: italic;">---<br>*Error in loading object '/realms/cratylus/area/room/sample_room'<br>Object: /secure/cmds/creators/update at line 148<br><br>'<function>' at /secure/save/creators/c/cratylus (<function>) at /:0<br>'cmdAll' at /secure/save/creators/c/cratylus (/lib/command.c) at line 84<br>'cmd' at /secure/cmds/creators/update at line 109<br>'eventUpdate' at /secure/cmds/creators/update at line 148<br>'CATCH' at /secure/cmds/creators/update at line 148<br>Trace written to /log/catch<br>/realms/cratylus/area/room/sample_room: Error in update<br>*Error in loading object '/realms/cratylus/area/room/sample_room'<br></span></big></pre> <hr style="width: 100%; height: 2px; font-family: courier new,courier,monospace;"> <pre style="font-family: courier new,courier,monospace;"><big><span style="font-style: italic;"><br></span><br> This output lets you know something is wrong, but<br>isn't very specific as to exactly what. If you look at your error<br>log, you probably will see something more detailed and helpful:<br><br><br></big></pre> <hr style="width: 100%; height: 2px; font-family: courier new,courier,monospace;"><span style="font-family: courier new,courier,monospace;">> </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">elog</span><br style="font-family: courier new,courier,monospace;"> <pre style="font-family: courier new,courier,monospace;"><big><span style="font-style: italic;">/log/errors/cratylus:</span><br style="font-style: italic;"><br style="font-style: italic;"><span style="font-style: italic;"></span><span style="font-style: italic;">/realms/cratylus/area/room/sample_room.c line 10: Undefined variable 'Sample'<br>/realms/cratylus/area/room/sample_room.c line 10: parse error<br></span></big></pre> <hr style="width: 100%; height: 2px; font-family: courier new,courier,monospace;"> <pre style="font-family: courier new,courier,monospace;"><big><span style="font-style: italic;"><br></span><br> Now you can see that the error is my syntax on<br>line 10. I would then use ed to examine the code, and specifically lines 9<br>through 11. It turns out that I forgot to put quotes around the room name, <br>so the parser tried to use it as a variable, which, of course, it couldn't.<br><br> If the file in question is in /secure, you'd type <span style="font-weight: bold;">elog secure</span> , or if<br>it's in /cmds, <span style="font-weight: bold;">elog cmds</span> , and so on.<br><span style="font-weight: bold;"><br> </span></big><br><big><big style="font-weight: bold; text-decoration: underline;"><big><a name="2"></a></big></big></big><big><big style="font-weight: bold; text-decoration: underline;"><big>dbxwhere</big></big></big><big><big style="font-weight: bold; text-decoration: underline;"><big> & dbxframe</big></big><span style="font-weight: bold;"><br></span></big><big><span style="font-weight: bold;"></span></big><big><span style="font-weight: bold;"><br> </span>Two<span style="font-weight: bold;"> </span>helpful debugging commands are dbxframe and dbxwhere. Let's<br>take a look at my broken sample_room.c file. We'll start with dbxwhere,<br>which lists for us the chain of events that led to the error. The<br>individual steps are called frames.<br><br>> <span style="font-weight: bold;">dbxwhere</span><br>*Error in loading object '/realms/cratylus/area/room/sample_room'<br>Object: /secure/cmds/creators/update at line 148<br><br>#0: '<function>' at /secure/save/creators/c/cratylus (<function>) at /:0<br>#1: 'cmdAll' at /secure/save/creators/c/cratylus (/lib/command.c) at line 84<br>#2: 'cmd' at /secure/cmds/creators/update at line 109<br>#3: 'eventUpdate' at /secure/cmds/creators/update at line 148<br>#4: 'CATCH' at /secure/cmds/creators/update at line 148<br></big></pre> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">The output is similar to the update error we saw above, but in enumerating the steps, </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">dbxwhere</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">lets us use </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">dbxframe</span><span style="font-family: courier new,courier,monospace;"> to get tighter detail on a given error frame:</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">> </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">dbxframe 4</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">------</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> /secure/cmds/creators/update.c:148 - CATCH(0)</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> ----------------------------------------------------------------</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> if( args == base_name(this_object()) ) {</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> this_player()->eventPrint("Cannot reload update after destruct.\n"</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> "It will be reloaded at next reference.");</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> return 0;</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> }</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> => tmp = catch(call_other(args, "???"));</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> if( !tmp ) {</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> if(identify(flags ^ U_AUTOMATED) ==</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> "8")this_player()->eventPrint(args + ": Ok");</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> return 1;</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> } else this_player()->eventPrint(args + ": Error in update\n" + tmp);</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> return 0;</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> We're now looking at the error context for error frame 4. The output of the command shows</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">us part of the file that was performing the evaluation when the error occurred, and even</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">points out the offending line using a text arrow: =></span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> In this particular case, the information is not that helpful. We are being told that</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">the error occurred while we were using the update command, and it failed at the line</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">where update does its thing. Duh, we knew that. The </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">elog</span><span style="font-family: courier new,courier,monospace;"> command was much more helpful.</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> Where this kind of tracing comes in handy is when you encounter a runtime error</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">when you're not updating a file. For example, if I tried to enter that room, rather than</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">update it, I'd get a big pukey error message and not know why. If you run into an</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">unexpected error, </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">dbxwhere</span><span style="font-family: courier new,courier,monospace;"> will help you pinpoint it if </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">elog</span><span style="font-family: courier new,courier,monospace;"> doesn't provide useful information,</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">and </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">dbxframe</span><span style="font-family: courier new,courier,monospace;"> will help detail the source of the problem.<br> <br> <big><big><br> <big><span style="font-weight: bold; text-decoration: underline;"></span></big></big></big></span><big style="font-family: courier new,courier,monospace;"><big style="font-weight: bold; text-decoration: underline;"><big><a name="3"></a></big></big></big><span style="font-family: courier new,courier,monospace;"><big><big><big><span style="font-weight: bold; text-decoration: underline;">tell_player(), debug()</span></big></big></big><br> <br> Sometimes it's hard to fix code if you don't know what it's doing. In<br> the above example, you might want to know what the variable "args" is, if<br> your code is behaving unexpectedly. You could find out by adding a line like:<br> <br> <span style="color: rgb(0, 0, 153);">tell_player("cratylus", "args is: "+identify(args));<br> <br> <span style="color: rgb(0, 0, 0);">or:</span><br> <br> </span><span style="color: rgb(0, 0, 153);">tell_player("cratylus", "%^BLUE%^args is: "+identify(args)+"%^RESET%^");</span></span><br style="color: rgb(0, 0, 153); font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"><span style="color: rgb(0, 0, 153);"></span><br> You could also use:<br> <br> <span style="color: rgb(0, 0, 153);">debug("args is: ", args);<br> <br> <span style="color: rgb(0, 0, 0);">or:</span><br> <br> </span><span style="color: rgb(0, 0, 153);">debug("args is: ", args, "blue");</span></span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"><span style="color: rgb(0, 0, 153);"></span><br> ...which has the advantage of being shorter to type and you'll get<br> the message more promptly. To be able to receive debug messages,<br> you need to enable your debugging mode by typing:<br> <br style="font-weight: bold;"> <span style="font-weight: bold;">debug on</span><br> <br> debug() is available in 2.0r20 and above.<br> </span><br style="font-family: courier new,courier,monospace;"> <pre style="font-weight: bold; text-decoration: underline; font-family: courier new,courier,monospace;"><big><big style="font-weight: bold; text-decoration: underline;"><big><a name="4"></a></big></big></big><big><big><big>tail</big></big></big></pre> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> This is a version of the unix tail command. It displays the last few lines of a file. </span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">This command is important for examining crucial log files:</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-weight: bold; font-family: courier new,courier,monospace;">tail /log/catch</span><big style="font-family: courier new,courier,monospace;"><br> <small style="font-weight: bold;">tail /log/runtime<br> </small></big><big style="font-family: courier new,courier,monospace;"><small style="font-weight: bold;">tail /log/player_errors<br> <br> <br> </small></big><big style="font-family: courier new,courier,monospace;"><big style="font-weight: bold; text-decoration: underline;"><big><a name="5"></a></big></big></big><big style="text-decoration: underline; font-family: courier new,courier,monospace;"><big><big><span style="font-weight: bold;">bk & restore</span><br> <br> </big></big></big><span style="font-family: courier new,courier,monospace;">These commands aren't so much for debugging as they are for safe coding. Before you</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">edit a file, it is a very good idea to back it up first. The </span><span style="font-weight: bold; font-family: courier new,courier,monospace;">bk</span><span style="font-family: courier new,courier,monospace;"> command lets you</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">quickly and conveniently back up a file before you edit it. When I typed:</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-weight: bold; font-family: courier new,courier,monospace;">bk sample_room</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">A file with a unique identifying number was created in my bak/ directory. If I</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">were to type it again, then sample_room.c would get copied again to bak/, with</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">a new unique number added to the name.</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> The number is basically the number of seconds elapsed since January 1, 1970.</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">Adding this number, we can keep track of which backed up version of a file</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">is most recent by looking at the name.</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> Suppose I edited a file called sample_npc.c. I use bk to back it up, make some changes,</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">then use bk again, make some more changes, but now it won't update. I don't</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">feel like debugging, I just need this file working again, so I want to restore from</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">backup. The sequence of commands would look something like this:</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-weight: bold; font-family: courier new,courier,monospace;">ed sample_npc.c</span><br style="font-weight: bold; font-family: courier new,courier,monospace;"> <span style="font-weight: bold; font-family: courier new,courier,monospace;">bk sample_npc</span><br style="font-weight: bold; font-family: courier new,courier,monospace;"> <span style="font-weight: bold; font-family: courier new,courier,monospace;">ed sample_npc.c</span><br style="font-weight: bold; font-family: courier new,courier,monospace;"> <span style="font-weight: bold; font-family: courier new,courier,monospace;">update sample_npc.c</span><br style="font-family: courier new,courier,monospace;"> <span style="color: rgb(204, 0, 0); font-family: courier new,courier,monospace;"><error occurs here></span><br style="font-family: courier new,courier,monospace;"> <span style="font-weight: bold; font-family: courier new,courier,monospace;">restore sample_npc</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> The reason identifying numbers are used is that you can also choose to</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">restore the second-to-last backup version of a file, and other previous</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">versions.</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> The very last backup version is effectively version 0, so it's not</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">necessary to specify a number. If I wanted to restore the version I backed</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">up before that one, I would type something like this:</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-weight: bold; font-family: courier new,courier,monospace;">restore sample_npc 1</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> And if I wanted the version before that one, I'd specify 2 instead of 1, </span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">and so on.</span><br style="font-family: courier new,courier,monospace;"> <br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;"> Please note that this is an intentionally simple system. There are</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">no menus, no version branches, or diff tracking. The reason for this is</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">that it is not a </span><span style="font-style: italic; font-family: courier new,courier,monospace;">versioning</span><span style="font-family: courier new,courier,monospace;"> system. It is a </span><span style="font-style: italic; font-family: courier new,courier,monospace;">backup</span><span style="font-family: courier new,courier,monospace;"> system. It is a convenient</span><br style="font-family: courier new,courier,monospace;"> <span style="font-family: courier new,courier,monospace;">tool to back out of screwups, not a development tool to test file versions.</span><br style="font-family: courier new,courier,monospace;"> <big style="font-family: courier new,courier,monospace;"><small style="font-weight: bold;"><br> <br> </small></big><a style="font-family: courier new,courier,monospace;" href="index.html">Dead Souls Homepage</a><br style="font-family: courier new,courier,monospace;"> <big style="font-family: courier new,courier,monospace;"><small style="font-weight: bold;"><br> <br> </small></big> </body> </html>