contents   index   previous   next

Memory Tracking


The second main benefit of the ScriptEase ISDK debug code is that it internally tracks all memory allocated. When memory is allocated or freed, it is filled with garbage values so memory that is freed but later accessed will contain garbage and thus be likely to cause an immediate problem. If your program crashes, look at the data structure involved. If it is working with a dynamically-allocated memory and has the hex value 0xEE (for instance, the pointer 0xEEEEEEEE), it is likely an uninitialized value, since all allocated memory is filled with this value. If you instead find 0xBD (or 0xBDBDBDBD as a pointer), you are using memory that has since been freed. Of course, you'll then need to track down why you are using bad memory, but at least you know that you are.


Second, on exit, all memory is examined, and if some memory was not freed, it will be reported (in the jsedebug.log file, described above.) Special markers are written before and after each memory block, so if you have gone outside the bounds of the allocated memory, this too will be caught. These reports tell you the file name and line number that the memory was allocated on.


Occassionally, there will be a crash in these routines themselves. If the function crashing is in src/misc/jsemem.c, this is such a case. This happens when the internal lists have become corrupted. The most common cause is writing past the bounds of an allocation. While we buffer allocations with a few bytes on either end, sometimes a runaway program will write well beyond these safety margins and lead to this problem.


You can have memory allocated by your program included in this memory tracking code by using the ScriptEase memory allocation routines. Here are the prototypes for these functions. They function similarly to their C standard library counterparts except each takes an secontext as a parameter and will perform garbage collection if not enough memory is available. Each returns NULL if the requested memory could not be allocated even after collecting. In this case, a memory allocation failure error object is also set as the SE_RETURN,SE_VALUE member pair and the error flag is turned on. If you are in a wrapper function when this happens, you can immediately return from it and have the memory failure error be the return of your wrapper function.


void *seGCMalloc(secontext se,size_t size);

void *seGCRealloc(secontext se,void *orig,size_t newsize);

secharptr seGCStrdup(secontext se,seconstcharptr orig);

secharptr seGCStrndup(secontext se,seconstcharptr orig,size_t len);

void seGCFree(secontext se,void *item);