PORTWRITEARRAY leaks the contents of its array and some other nodes which it allocates. The leak seems to be due to the bizare way in which lportwritearray read from the input array:
// fill buffer with elements of the array
for (int i = 0; i < count; i++)
{
NODE * item = litem(cons_list(make_intnode(i + getarrorg(obj)), obj));
txbuffer[i] = getint(cnv_node_to_numnode(item));
}
You can see that it invokes litem without freeing the cons_list arguments, the returned item or the output form cnv_node_to_numnode.
This leak is reproducible in MSWLogo 6.5b and all version of FMSLogo up through 7.2.0.
How Reproducible:
Every Time
Steps to Reproduce:
Run the following program
MAKE "array ARRAY 10000
REPEAT 10000 [ SETITEM REPCOUNT :array 0 ]
SHOW NODES
PORTOPEN "anyport
REPEAT 10 [ IGNORE PORTWRITEARRAY 10000 :array ]
SHOW NODES
What Happens:
The second call to NODES shows about 5000 more nodes in use (the first item in the list) than the first call, even though no additional state was saved in the FMSLogo environment.
Expected Result:
The second call to NODES shows about the same number of nodes in use as the first call.
Note: this is easier to observe with debug version of FMSLogo, since that will print out every leaked allocations on shutdown. They look like:
Memory Leaks detected!
Leaked 286368 bytes in 7685 blocks
(id= 158654) 32 bytes at 0x0585EB40: < 0 > DA DA DA DA 00 30 DA DA
(id= 158653) 32 bytes at 0x0585EB08: < 0 > DA DA DA DA 00 30 DA DA
(id= 158652) 32 bytes at 0x0585EAD0: < > DA DA DA DA 00 03 DA DA
(id= 158651) 32 bytes at 0x0585EA98: < 0 > DA DA DA DA 00 30 DA DA
(id= 158650) 32 bytes at 0x0585EA60: < 0 > DA DA DA DA 00 30 DA DA
(id= 158649) 32 bytes at 0x0585EA28: < > DA DA DA DA 00 03 DA DA
...
(id= 150504) 32 bytes at 0x057E4088: < > DA DA DA DA 00 03 DA DA
(id= 150503) 32 bytes at 0x057E4168: < 0 > DA DA DA DA 00 30 DA DA
(id= 150502) 32 bytes at 0x057E4BD8: < 0 > DA DA DA DA 00 30 DA DA
(id= 150501) 32 bytes at 0x057E4050: < > DA DA DA DA 00 03 DA DA
(id= 18799) 32 bytes at 0x057E62F0: < > DA DA DA DA 00 03 DA DA
(id= 18767) 32 bytes at 0x057E7180: < $ > DA DA DA DA 00 24 DA DA
The fix for this will be available in FMSlogo 7.3.0.
The fix for [#514] made in [r4565] fixed most of the leak by rewriting the bizare way in which
lportwritearrayread from the input array. This left only a leak for bad input where the original node wasn't an INTEGER, but could be converted to one, as in:This aspect was fixed in [r4570] by adding a missing
gcrefcall.Related
Bugs:
#514Commit: [r4565]
Commit: [r4570]