I have encountered another bug, this one is not as easily fixed though
From my limited understanding, what happens is that during the processing of a DSA a database runs out of free entries and uses realloc() to enlarge the available memory (DATABASES::Enlarge()), then the processing of the DSA continues but because the pointer to some 'master object' (e.g. argument 'pDBMaster' to Execute()) still points to the old allocation area, the access sometime later falls into a freed memory area.
How to trigger the bug: In Conflux, pick a character then go down the stairs next to the half-open black door ("Foul smells and vapors" message) and follow the corridor to the area with the munching trees. Waiting for about 10 seconds in that room at the bottom of the stairs will trigger the bug.
If my guess is correct I could imagine an easy fix to be to make sure the database is large enough before starting to process a DSA, assuming the number of entries allocated during the DSA has a fixed maximum or is known in advance.
Some gory details follow.
Backtrace from a breakpoint at the realloc() call (before the invalid access occurs (the first line is from a debug printf):
Code: Select all
enlarging DB 3: from 10318 to 10418 entries (10 per entry)
Breakpoint 1, DATABASES::Enlarge (this=0x8179de0, dbNum=3) at data.cpp:859
859 MALLOC064);
(gdb) bt
#0 DATABASES::Enlarge (this=0x8179de0, dbNum=3) at data.cpp:859
#1 0x080ebe8c in DATABASES::FindEmptyDBEntry (this=0x8179de0, dbType=dbACTUATOR, important=true) at data.cpp:973
#2 0x0808191a in FindEmptyDB3Entry (important=59) at CSBCode.cpp:4926
#3 0x080ad49c in CopyItem (origRN=...) at DSA.cpp:1771
#4 0x080ae71d in EX_ADD (exPkt=<value optimized out>, cmdOffset=<value optimized out>) at DSA.cpp:2026
#5 EX_AMPERSAND (exPkt=<value optimized out>, cmdOffset=<value optimized out>) at DSA.cpp:2520
#6 0x080b4f27 in Execute (RNmaster=<value optimized out>, RNslave=<value optimized out>, pDBMaster=<value optimized out>, pMaster=0x82a2ba8,
pSlave=0x82a2ba8, curState=1, msgType=1, locrMaster=..., locrSlave=..., subroutineLevel=1, filter=false) at DSA.cpp:5136
#7 0x080b62e2 in EX_GOSUB (exPkt=...) at DSA.cpp:804
#8 0x080b5e52 in Execute (RNmaster=<value optimized out>, RNslave=<value optimized out>, pDBMaster=<value optimized out>, pMaster=0x82a2ba8, pSlave=0x82a2ba8, curState=1, msgType=0, locrMaster=..., locrSlave=..., subroutineLevel=0, filter=false) at DSA.cpp:5242
#9 0x080b6785 in ProcessDSATimer6 (objSlave=..., pTimer=0xbfffebb0, locrSlave=..., filter=<value optimized out>, dsaVars=0xbfffe97a) at DSA.cpp:5437
#10 0x080e085c in ProcessTT_STONEROOM (pTimer=0xbfffebb0, index=197) at Timer.cpp:2200
#11 0x0808646c in ProcessTimers () at CSBCode.cpp:6412
#12 0x0808932e in _MainLoop () at CSBCode.cpp:617
The error message from valgrind of the invalid access:
Code: Select all
==3396== Thread 1:
==3396== Invalid read of size 2
==3396== at 0x80E7306: DB3::ParameterA() (data.cpp:1339)
==3396== by 0x80AC82C: GetTarget(TARGETTYPE, EXECUTIONPACKET&, bool) (DSA.cpp:597)
==3396== by 0x80ACE68: EX_MESSAGE(EXECUTIONPACKET&, bool, char) (DSA.cpp:667)
==3396== by 0x80B5DCF: Execute(RN, RN, DB3*, DSA*, DSA*, int, int, LOCATIONREL, LOCATIONREL, int, bool) (DSA.cpp:5221)
==3396== by 0x80B62E1: EX_GOSUB(EXECUTIONPACKET&) (DSA.cpp:804)
==3396== by 0x80B5E51: Execute(RN, RN, DB3*, DSA*, DSA*, int, int, LOCATIONREL, LOCATIONREL, int, bool) (DSA.cpp:5242)
==3396== by 0x80B6784: ProcessDSATimer6(RN, TIMER const*, LOCATIONREL, bool, DSAVARS*) (DSA.cpp:5437)
==3396== by 0x80E085B: ProcessTT_STONEROOM(TIMER*, unsigned int) (Timer.cpp:2200)
==3396== Address 0x6456c28 is 100,128 bytes inside a block of size 103,180 free'd
==3396== at 0x4025A7D: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3396== by 0x808A314: UI_realloc(void*, int, unsigned int) (CSBUI.cpp:2270)
==3396== by 0x80E97F1: DATABASES::Enlarge(int) (data.cpp:857)
==3396== by 0x80EBDFB: DATABASES::FindEmptyDBEntry(DBTYPE, bool) (data.cpp:971)
==3396== by 0x8081919: FindEmptyDB3Entry(bool) (CSBCode.cpp:4926)
==3396== by 0x80AD49B: CopyItem(RN) (DSA.cpp:1771)
==3396== by 0x80AE71C: EX_AMPERSAND(EXECUTIONPACKET&, int) (DSA.cpp:2026)
==3396== by 0x80B4F26: Execute(RN, RN, DB3*, DSA*, DSA*, int, int, LOCATIONREL, LOCATIONREL, int, bool) (DSA.cpp:5136)
I will try to provide additional info if needed.