There seem to be many people in #wiidev who like developing applications for the GCN or the Wii but don't really know what to do when their program crashes (as in "****ing hexadecimals printed on the screen") except for adding debug printfs every few lines to track such crashes down and fix them afterwards. It looks like it is a common misunderstanding that you can only debug your code better when using a USB Gecko in combination with the GNU Debugger (gdb) which is included in devkitPPC. In fact, a gecko really helps when you've got to debug strange crashes but you can also make your debugging sessions easier without one by just using gdb and the informations the exception screen gives you. Most crashes can be easily debugged without any assembler knowledge but you'll need to know at least some basics in pretty rare cases when you are just unable to figure out why the program is crashing in some function/code line. However, I won't focus on such problems here as they are very rare and too special to be discussed.
Let's start with a very simple program where the crash is rather obvious:
// header stuffint main(int argc, char *argv[]){ // Video mode/ LibOGC init stuff goes here memcpy(NULL, "bla", 3); return 0;}
You probably know that writing data to the address NULL is a *really* bad idea and will cause an exception but let's assume that you do not know this and/or have much code around this memcpy so that this mistake is not that obvious. If you compile this program now and run it on your Wii you'll get a nice exception screen. At first you'll see a dump of all registers which is not really useful if you don't even know where to search for your bug. But the addresses directly below are on the other hand really useful to find this bug: These addresses represent your backtrace you would get when using the gdb stub with a USB gecko.
If you have not compiled your program with debugging symbols (add -g to your CFLAGS) or with some crazy optimizations (i.e. any optimizations -> remove -O[0-9s] from your CFLAGS) it is a good time to do this now and re-run your program in order to get an updated backtrace.
My exception screen says "80006df8 --> 8000446c --> 8001a4a4". We're going to use gdb now in order to translate the symbols to function names:
$ powerpc-gekko-gdb crashme.elfGNU gdb 6.8Copyright (C) 2008 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=powerpc-gekko"...(gdb) info symbol 0x80006df8memcpy + 48 in section .text(gdb) info symbol 0x8000446cmain + 196 in section .text(gdb) info symbol 0x8001a4a4__lwp_thread_handler in section .text(gdb)
Make sure to actually use the .elf and not the .dol file here since the latter one does not contain any debug symbols. To find the line responsible for the bug you now start the the most recent entry (i.e. the first one). It basically tells you that something bad happened in memcpy() which was called from main() (see the second address) which was called by __lwp_thread_handler. You can now use yet another gdb command to even get the line number from which you called memcpy() in main:
(gdb) info line *0x8000446cLine 38 of "/home/svpe/wiidev/crashme/source/main.c" starts at address 0x8000446c and ends at 0x80004470 .
By looking at line 38 of you main.c file now, you'll find that this line is in fact "return 0". You wouldn't expect to see a crash here but you should start looking at the previous code lines to see if something bad might happen there. In the given example we'll very quickly find out that the memcpy call one line before the return instruction has produced this crash and will need to be fixed.
This GDB method is much faster than adding printfs to your applications until you are sure at which line your crash actually happens and it also works on a much larger codebase than this small one-file example in about the same time
Debugging with a gecko is for sure even better as you can step through your code line by line but this method is a good replacement if can't afford or don't want to get one.