gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Great debugging tip

#24947 - Gene Ostrowski - Fri Aug 13, 2004 8:03 pm

Not sure where to post this, but I stumbled across something that some of you may not yet know, and it was very helpful.

I had something happening in my program where it appeared to be locking up, and I could not track down the code where it was occurring.

Sometimes stepping through the GDB debugger is a slow and painful process, but I figured out a fast way to find out where it was hanging:

By using VBA in conjunction with the memory map, I was able to determine the exact routine that was causing the problem almost instantly.

VBA comes with a built-in disassembler that can be accessed through the Tools --> Disassemble menu. Load up your ROM and open up the Disassemble window while the game is running. Click on the "Automatic Update" box and you'll see your code executing. More importantly, it will show you the address that is currently executing (the left-most column on the screen).

You can then use NM to map out your symbols for you, so you can determine the routine that's associated within that address space. From the command-line, do something like:

nm -n MyGame.elf > MyGame.txt

to dump the memory map to a file (MyGame.txt) then open it up in a text editor. Scroll down for the routine that includes the address in question, and you can pinpoint the location of the problem. At least you'll know which routine it is.

Similarly, you can use the Tools -> Memory Viewer menu option to display a memory map. If you are needing to watch a variable because you think it contains an incorrect value, you can scan for the name in the text file, get its address, and use the memory viewer to watch the variable in real-time.

I used this method to find the routine that was hanging, and the variable that was being overwriten to a bad value.

Hope this helps someone!
_________________
------------------
Gene Ostrowski

#24950 - poslundc - Fri Aug 13, 2004 8:24 pm

Gene Ostrowski wrote:
Similarly, you can use the Tools -> Memory Viewer menu option to display a memory map. If you are needing to watch a variable because you think it contains an incorrect value, you can scan for the name in the text file, get its address, and use the memory viewer to watch the variable in real-time.


I generally use EWRAM for this purpose rather than bothering with the memory map. I just copy the variable I'm interested in to 0x02000000. Real easy to find that way.

This only works, of course, if you aren't using EWRAM for anything else (ie. your game isn't multiboot and you aren't using malloc/new).

Dan.

#24958 - expos1994 - Fri Aug 13, 2004 9:22 pm

Gene, thanks for the tip. I wasn't aware of the NM command to generate a map.
I was previously tracking my variables using Dan's method/VBA's memory viewer, and that made it hard, because usually the value I was tracking led me to be curious about another value whose address I didn't know. Then I'd have to change the code to put the address in EWRAM and start over, so this should help.

When I first started GBA programming, I couldn't find a suitable debugger, so I figured developing anything would be a major pain. After awhile I discovered that for my purposes, VBA provides all the debugging I need. Looking at the layout of VRAM, OAM attributes, the background layouts, and the memory viewer has answered most of my questions and helped me solve all of my problems.

With your tip I can actually start putting the disassembler to use. This should be a big help.

I do have one question though: Does anyone know where the function variables are stored? The variables whose scope is only local to the function. I would guess they are in IWRAM somewhere, but I don't see any mention of them in the map I generated with NM.

btw, what does NM stand for?

Thanks,

Chris

#24962 - torne - Fri Aug 13, 2004 10:06 pm

nm is 'names'. Local variables are stored on the stack.