Tohle se mi často dělo u objektů s počítanou referencí. Jedno vlákno snížilo referenci a druhé z výšilo. Občas se to ale trefilo mezi, že ti pak byl schopen vyjít výpočet tak že 1 + 1 = 1 (protože druhé vlákno z toho udělalo 0 a 0 + 1 = 1. Pak došlo k tomu, že jedno vlákno uvolnilo paměť (čítač referencí klesl na nulu) a to druhé tam následně zapsalo jedničku. Člověče, dost mě šokovalo, jak často mi to takhle spadlo.
Jinak tahle chyba se detekuje tak, že v debug verzi je paměť vyplněná známou hodnotou. Hodně pak pomůže prozkoumat obsah změnené paměti, zda změna neodpovídá něčemu. Například já na to přišel tak, že jedno 32-bit slovo tam bylo inkrementováno (mám pocit, že se to vyplñuje CDCDCDCD a já tam viděl CECDCDCDCD, takže to bylo jasné). A pozor na to, že chyba se může objevit až za hodně dlouho. Doporučuju logovat alokace a při vzniku chyby si projít log a najít tu alokaci, která paměť alokovala a dealokovala.
Pokud používáš nějaké chytré pointery, tak čítače referencí by měly být měněny přinejmenším funkcí InterlockedIncrement / Decrement, namísto obyčejné ++
Jo, aspektem téhle chyby je, že vzniká náhodně. Pokud ti vzniká pravidelně, tak tam někde skutečně zapisuješ do dealokované paměti. Ale to by mělo jít debugerem snadno zjistit. |