swarm-support
[Top][All Lists]
Advanced

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

Exasperating memory corruption


From: William S. Shu
Subject: Exasperating memory corruption
Date: Wed, 19 May 1999 13:13:32 +0100

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.



reply via email to

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