GDB Usage #2 What if a backtrace is not informative? When you have a seg fault, the backtrace from gdb under windows might not help. Sometimes you get the "NO STACK" output from gdb, which generally means something has crashed even before the program starts. If you see that, double check for typos in your .scm files, but it may be necessary to be more systematic in finding the problem. The thing to do next is to run the program in the debugger, i.e. "gdb ./heatbugs.exe" (on linux systems, you do "gdb .lib/heatbugs" because the executable is hidden in a directory .lib). You set some break points. To break at line 50 of Heatbugs.m, for example, you start gdb with the program and then > break Heatbugs.m:50 Then when you type "run" the program will go up to line 50, and stop > There you can do various things, like n run next command in your code s step into next command. If your code calls a function from somewhere else, this will "step"into it. Usually you step once, then use n to continue with the next command in that function, where ever it is. c continue the program In a Swarm program, written in Obj-C, there are some things that may give information. One is print *self That lists the instance variables of an object, if you are in one. The ones that are integers will show their values, the ones that are objects will show addresses. One way to see troubles is if an object has an address of 0x0. That means it is NULL, or not created, or lost somehow. At the end of the most recent edition of the Swarm User guide, alex lancaster put an appendix on debugging, which does not help all that much, except he gives a link to a site about using the gdb with objective-C code. One thing in there is that objective-c does "name mangling", so you can't just set a break on a method name, even though the C manual says you ought to be able to. The method "step" gets mangled to _i_Heatbug__step. So if you ever did need to break on a function name, you could do it, and that resource that Alex linked to tells the ins and outs of it. Another thing you can do is call functions from the swarm library. While you are in gdb, it may be that you need to know what is in a list. In the swarm docs, it describes some debugging functions like "xprint()" and xfprint() and xfprintid(). These will give some information about what kind of object a thing is, how many items there are in a list, etc. So if you are stopped in gdb, and you want to know what is in "alist", and alist shows when you do print *self, then you type > call xfprint(self->alist) Sometimes you get a output like "no alist in context" or such. That's because you forgot some notation. I thought of this because I was reading the RedHat linux web site, and there is a nice, elementary essay on the usage of gdb. This is about linux, but since you are working in the cygnus environment, you will see the same things happen. This writeup shows how he uses breakpoings to isolate a problem spot, and then he does some footwork to figure what the problem is. Here's the reference: http://www.redhat.com/developer/whitepapers/intro_dev/debug.html I just ran gdb on Heatbugs and perhaps this will flavor it for you (gdb) break HeatbugModelSwarm.m:99 Breakpoint 1 at 0x8049d2d: file HeatbugModelSwarm.m, line 99. (gdb) run Starting program: /swarm/swarmapps-2.1/heatbugs-opt/.libs/heatbugs Breakpoint 1, _c_HeatbugModelSwarm__createBegin_ (self=0x804e240, _cmd=0x401ced20, aZone=0x80fcde0) at HeatbugModelSwarm.m:103 103 [probeLibrary setProbeMap: probeMap For: [self class]]; (gdb) print *self $1 = {class_pointer = 0x804e200} (gdb) break HeatbugModelSwarm.m:133 Breakpoint 2 at 0x8049deb: file HeatbugModelSwarm.m, line 133. (gdb) c Continuing. Breakpoint 2, _i_HeatbugModelSwarm__buildObjects (self=0x810c4d0, _cmd=0x804e638) at HeatbugModelSwarm.m:134 134 heat = [HeatSpace create: self setSizeX: worldXSize Y: worldYSize (gdb) print *self $2 = {isa = 0x804e240, zbits = 135443046, internalZone = 0x810fb30, syncType = 0x808b7c0, activity = 0x0, numBugs = 100, evaporationRate = 0.98999999999999999, diffuseConstant = 1, worldXSize = 80, worldYSize = 80, minIdealTemp = 17000, maxIdealTemp = 31000, minOutputHeat = 3000, maxOutputHeat = 10000, randomMoveProbability = 0, randomizeHeatbugUpdateOrder = 0 '\000', modelActions = 0x0, modelSchedule = 0x0, actionForEach = 0x0, heatbugList = 0x0, world = 0x0, heat = 0x0} (gdb) break HeatbugModelSwarm.m:156 Breakpoint 3 at 0x8049eae: file HeatbugModelSwarm.m, line 156. (gdb) c Continuing. Breakpoint 3, _i_HeatbugModelSwarm__buildObjects (self=0x810c4d0, _cmd=0x804e638) at HeatbugModelSwarm.m:158 158 for (i = 0; i < numBugs; i++) (gdb) n 166 idealTemp = [uniformIntRand (gdb) n 168 outputHeat = [uniformIntRand (gdb) n 174 hbug = [Heatbug createBegin: self]; (gdb) n 175 [hbug setWorld: world Heat: heat]; (gdb) n 176 hbug = [hbug createEnd]; (gdb) n 180 [heatbugList addLast: hbug]; (gdb) n 184 [hbug setIdealTemperature: idealTemp]; (gdb) n 185 [hbug setOutputHeat: outputHeat]; (gdb) n 186 [hbug setRandomMoveProbability: randomMoveProbability]; (gdb) n 188 [hbug setX: [uniformIntRand (gdb) print *self $3 = {isa = 0x804e240, zbits = 135443046, internalZone = 0x810fb30, syncType = 0x808b7c0, activity = 0x0, numBugs = 100, evaporationRate = 0.98999999999999999, diffuseConstant = 1, worldXSize = 80, worldYSize = 80, minIdealTemp = 17000, maxIdealTemp = 31000, minOutputHeat = 3000, maxOutputHeat = 10000, randomMoveProbability = 0, randomizeHeatbugUpdateOrder = 0 '\000', modelActions = 0x0, modelSchedule = 0x0, actionForEach = 0x0, heatbugList = 0x8144c90, world = 0x81401f0, heat = 0x813fa30} (gdb) call xfprint(self->heatbugList) 0x81453e0: Heatbug, display name: Heatbug There is only one bug in my list so far. Its memory address is 0x81453e0 Paul Johnson