swarm-support
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Exasperating memory corruption


From: Jan Kreft
Subject: Re: Exasperating memory corruption
Date: Wed, 19 May 1999 14:04:47 +0100 (BST)

Hi,

this is not really helping you right now, but I'm wondering why you have
three different parallel Swarms. Why not have one Model Swarm with the
schedule and three subSwarms Person, Mosquito, MalariaPop. If these
subSwarms are only containers for a list of agents, an AgentList class
with three instances for each type of agent should be all you need. I
think you're making it more difficult than needed, but I'm probably
missing something.

HTH, Jan.

On Wed, 19 May 1999, William S. Shu wrote:

> I have an exasperating problem of memory corruption which is a bit
> elaborate.  Would be grateful if I am indicated likely causes.  (suspicious
> code fragments attached).
> 
>   Some questions rising in my mind are the following:
>  - can objects created in separate swarms not freely interact?
>  - can only objects in a given swarm be scheduled together? (even though
> things seem to work at times)
>  - what can so corrupt memory that it affects access to locations and local
> variables?  It is easier to understand corruption of data values, not memory
> location (addresses) to parameters and local variables.
> 
> 
> Details follow:
> ---------------
> 
> I have three separate swarms each holding lists of objects from one of
> Person, Mosquito and MalariaPop classes respectively. Only the personMS
> (person model Swarm) is activated.  For now, the others simply hold their
> objects.  operations on these model swarms, or their list of objects, are
> scheduled in the personMS.
> 
> My program seems to run okay (does not crash) when I have no methods for the
> class Mosquito.  (Actually, I have a degenerate form of -step that prints
> "replace Me!" every 1000 times or so).  It did run overnight (over 24 hours)
> with no crash. However, after about 13,000-15,000 time steps, a displayed
> graph blanked out; lines could be seen only after a zoom in in the correct
> place (a hidden fault??).
> 
> Now,  I add methods to the Mosquito class; most of the methods for the
> mosquito class are the ones which run under Person class.  (Person and
> Mosquito have the same instance variables and most of the methods for the
> mosquito class are the same as for Person class.)  Unfortunately, the
> program crashes when run.
> 
> Inspection using GDB 4.17.1 (which I assume is okay) shows that the program
> code is corrupted somehow.  eg.,
> 1) the same location is passed for two *distinct* parameters
> 2) modifying one integer variable (not a pointer!) affects others, even
> across method calls!
> 
> In the past, the position of crashes has been erratic as I edited code and
> weeded out other bugs.  For a given version of compiled code, crashes are
> around the same place for multiple runs.  However, the only thing common
> with the crashes is that I try to get Person and Mosquito objects to
> interact
> 
> Currently, it crashes when Person tries to kill mosquitoes by issuing:
>     [self killMosquito:
>      [mosquitoModelSwarm getWorld] range:2]; // kill mosquitoes in range
> 
> Here, getWorld returns the id of the world (Grid2d) in which mosquitoes are
> found.  (Person objects have their own separate world). Method
> killMosquito:range: gets a point from this world by and "kills" via dropDead
> (ie. remove, note drop) the mosquito object found.  Non-Mosquito Objects are
> left alone.  It uses the method chooseNeighbourX:Y:range: to select the
> point.  And it is in this mehtod call that the memory corruption is first
> detected.
> 
> 
> I developed the programs under Swarm 1.3.1, but now run it under Swarm 1.4.1
> which was downloaded a few days ago (everything via Swarm home page)
> Debugger: GNU gdb 4.17.1 Copyright 1998
> 
> 
> 
> interface (with abuse of syntax) follows:
> -----------------------------------------
> 
> // creating model swarms.  SmlModelSwarm holds all the code for creating
> model swarms.
> @interface SmlModelSwarm:Population:SmlSwarm:Swarm {IVar} ... @end
> 
> 
> // These derive from SmlSwarm.  Have no instance variables (IVars).  The
> method -step does nothing, for now.  All others, apart from -buildObjects,
> simply invoke super to do the work.  Their -buildObjects methods only differ
> in the initial number And kind of inhabitants created.  (Thus, PersonMS
> creates Person objects, etc.)
> @interface PersonMS:SmlModelSwarm {No IVars}
> - dropDead;     // Die (for any reason)
> - step;      // does nothing now!
> 
> + createBegin: aZone;    // extra methods you
> - createEnd;     // provide for Swarms
> - buildObjects;
> - buildActions;
> - activateIn: swarmContext;
> @end
> 
> @interface MosquitoMS:SmlModelSwarm {No IVars} ... same as PersonMS ... @end
> 
> @interface MalariaPopMS:SmlModelSwarm {No IVars} ... same as PersonMS ... @e
> nd
> 
> 
> // MalariaPOp derives from Swarm, but is used, for now, only as an object.
> It is created (and destroyed) and holds values that are accessed.  I do not
> expect it misbehave (on this account) because it is a Swarm not a
> SwarmObject
> 
> @interface MalariaPop:Population:SmlSwarm:Swarm {IVar} ... @end
> 
> // IVar for Mosquito and Person are identical; most methods are identical
> 
> @interface Person:SmlObject:SwarmObject {IVar } ... @end
> 
> @interface Mosquito:SmlObject:SwarmObject {IVar } ... @end
> 
> 
> 
> 
> code follows
> ------------
> 
> 
> ###################################
> Person.m
> =============
> - killMosquito: (id) wld range: (int) d { // kill mosquitoes within d
>   int i, count;
>   int x, y;
>   id obj;
> 
>   count = random_int(0, PSN_XPDCNT_MSQ_KILL); // max no of mosquitoes to
> kill
> 
>   for (i = 0; i < count; ++i) {
>     x = position.x;    // use my coordinates for ref.
>     y = position.y;
> 
>     [modelSwarm chooseNeighbourX: &x Y: &y range: d];
> 
>     obj = [wld getObjectAtX: x Y: y];  // get object at position
>     if ([obj isKindOf: [Mosquito class]]) { // ensure its a mosquito!
>       [obj dropDead];    // kill it; not bury (ie drop)
>     }
> 
>   }
>   //  printf("\n%s: killMosquito:_range_: not yet implemented\n", [self
> getDisplayName]);
> }
> 
> 
> - step {
> //...
> 
>   // step2a: Takes drug if sick: same as kill malaria germs (if > 200).
>   // Actually, should take it regularly over fixed period.
> 
>   if ([[self getActivatePanel] xpdReceiveTreatment: self]) {
>     [self receiveTreatment];  // receive treatment against disease
>   }
> 
>   // step2b: Kill mosquitoes (in its world) if within surroundings.
>   if ([[self getActivatePanel] xpdKillMosquito: self]) {
>     [self killMosquito:
>      [mosquitoModelSwarm getWorld] range:2]; // kill mosquitoes
>   }
> 
> //...
> }
> 
> ###################################
> Mosquito.m
> =============
> 
> - (id) getPerson: (id)wld range: (int)d {  // get person within d
>   int i, count;
>   int x, y;
>   id obj;
> 
>   count = random_int(0, MSQ_XPDCNT_PSN_BITE); // max no of persons to bite
> 
>   x = position.x;    // use my coordinates
>   y = position.y;
> 
>   for (i = 0; i < count; ++i) {
>     [personModelSwarm chooseNeighbourX: &x Y: &y range: d];
> 
>     obj = [wld getObjectAtX: x Y: y];  // get object at position
>     if ([obj isKindOf: [Person class]]) { // ensure its a mosquito!
>       return obj;    // return person found
>     }
> 
>   }
> 
>   return nil;
> }
> 
> 
> 
> 
> ###################################
> SmlModelSwarm.m
> =============
> 
> // choose one of nearest neighbouring positions within 'vision'.
> - chooseNeighbourX: (int *)newX Y: (int *) newY range: (int) vision {
>   int x, y;
> 
> 
>   if (vision <= 0) {
>     return;     // no change of position
>   } else if (vision >= 2) {
>     x = *newX;     // set to current pos (default)
>     y = *newY;
>     //    while ((x = *newX) && (y = *newY)) {
>       x = [uniformIntRand
>      getIntegerWithMin: x - vision + 1 withMax: x + vision - 1];
>       y = [uniformIntRand
>      getIntegerWithMin: y - vision + 1 withMax: y + vision - 1];
>       //    }
>   }
> 
>   *newX = [self makeValidX: (x + 1)];  // set to validated values
>   *newY = [self makeValidY: (y - 1)];
> 
>   return;
> }
> 
> 
> 
> // These methods ensure coordinates are valid in my world, based
> // on its type of 2-D representation (e.g. flat, sphere, dough-nut (torus))
> 
> // FOR NOW: assume dough-nut world: wrap value into valid range along axis
> // !!! FOR NOW: use valueSpace Coordinates !!!
> - (int) makeValidX: (int) x {   // make x-coord valid
>   return [valueSpace makeValidX: x];
> }
> 
> - (int) makeValidY: (int) y {   // make y-coord valid
>   return [valueSpace makeValidY: y];
> }
> 
> - makeValidPoint: (Point *) pt {  // make p valid
>   pt->x = [valueSpace makeValidX: pt->x];
>   pt->y = [valueSpace makeValidY: pt->y];
> }
> 
> 
> - buildActions
> {
> 
>   [super buildActions];
> 
>   //
>   // MOVE MUCH OF THESE TO INDIVIDUAL MODEL SWARMS !!!
>   ////
> 
>   // Create the list of simulation actions. We put these in an action
>   // group, because we want these actions to be executed in a specific
>   // order, but these steps should take no (simulated) time. The
>   // M(foo) means "The message called <foo>". You can send a message
>   // To a particular object, or ForEach object in a collection.
> 
>   // Note we update the ValueSpace in two phases: first run diffusion,
>   // then run "updateWorld" to actually enact the changes the agents
>   // have made. The ordering here is significant!
> 
>   // masterClock: ticks private clock and sets its events.
> 
> 
> 
>   //!!! FOR NOW: step through mosquito and malarial here!
>   // MOVE TO APPROPRIATE SWARMS LATER !!!
>   mosquitoMSList = [mosquitoModelSwarm getAgentMSList];
>   malariaPopMSList = [malariaPopModelSwarm getAgentMSList];
> 
> 
> 
>   modelActions = [ActionGroup create: [self getZone]];
>   [modelActions createActionTo:      valueSpace  message: M(stepRule)];
>   [modelActions createActionTo:      masterClock message: M(stepChrono)];
>   [modelActions createActionForEach: agentMSList message: M(step)];
>   [modelActions createActionTo:      self        message: M(step)];
> 
> 
>   // --- BEGIN MOVE TO APPROPRIATE SWARMS LATER !!!
> 
>   [modelActions createActionForEach: mosquitoMSList   message: M(step)];
>   [modelActions
>     createActionTo: mosquitoModelSwarm   message: M(step)];
> 
>   [modelActions createActionForEach: malariaPopMSList message: M(step)];
>   [modelActions
>     createActionTo: malariaPopModelSwarm message: M(step)];
> 
>   [modelActions
>     createActionTo: mosquitoModelSwarm   message: M(dropAgents)];
>   [modelActions
>     createActionTo: malariaPopModelSwarm message: M(dropAgents)];
> 
>   // --- END MOVE TO APPROPRIATE SWARMS LATER !!!
> 
> 
>   [modelActions createActionTo:      self        message: M(dropAgents)];
>   [modelActions createActionTo:      valueSpace  message: M(updateLattice)];
> 
> 
>   // Then we create a schedule that executes the modelActions. modelActions
>   // is an ActionGroup, by itself it has no notion of time. In order to
>   // have it executed in time, we create a Schedule that says to use
>   // the modelActions ActionGroup at particular times.
>   // This schedule has a repeat interval of 1, it will loop every time step.
>   // The action is executed at time 0 relative to the beginning of the loop.
> 
>   // This is a simple schedule, with only one action that is just
>   // repeated every time. See mousetraps for more complicated schedules.
> 
>   modelSchedule = [Schedule createBegin: [self getZone]];
>   [modelSchedule setRepeatInterval: 1];
>   modelSchedule = [modelSchedule createEnd];
>   [modelSchedule at: 0 createAction: modelActions];
> 
>   return self;
> }
> 
> 
> 
> ###################################
> ValueSpace.m
> ============
> 
> // These methods ensure coordinates are valid in my world, based
> // on its type of 2-D representation (e.g. flat, sphere, dough-nut (torus))
> 
> // FOR NOW: assume dough-nut world: wrap value into valid range along axis
> - (int) makeValidX: (int) x {   // make x-coord valid
> 
>   // NOTE: !!! assumes |x| < xMax and so result must be positive
>   return (x + reference.xMax) % reference.xMax;
> }
> 
> - (int) makeValidY: (int) y {   // make y-coord valid
> 
>   // NOTE: !!! assumes |y| < yMax and so result must be positive
>   return (y + reference.yMax) % reference.yMax;
> }
> 
> - makeValidPoint: (Point *) pt {  // make p valid
>   pt->x = [self makeValidX: pt->x];
>   pt->y = [self makeValidY: pt->y];
> }
> 
> 
> 
>                   ==================================
>    Swarm-Support is for discussion of the technical details of the day
>    to day usage of Swarm.  For list administration needs (esp.
>    [un]subscribing), please send a message to <address@hidden>
>    with "help" in the body of the message.
> 
> 


                  ==================================
   Swarm-Support is for discussion of the technical details of the day
   to day usage of Swarm.  For list administration needs (esp.
   [un]subscribing), please send a message to <address@hidden>
   with "help" in the body of the message.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]