View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0004168 | The Dark Mod | SEED | public | 27.06.2015 15:10 | 29.06.2015 04:09 |
Reporter | SteveL | Assigned To | SteveL | ||
Priority | high | Severity | block | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | TDM 2.03 | ||||
Target Version | TDM 2.04 | Fixed in Version | TDM 2.04 | ||
Summary | 0004168: SEED deletes heap memory it doesn't own | ||||
Description | SEED causes debug builds to crash by deleting heap memory that it doesn't own. Possibly a double-deletion. This makes maps using it impossible to debug without deleting all the SEED entities first, invalidating save games from those maps, and it'll prevent us extending the system to cover modelled architecture. | ||||
Steps To Reproduce | Have SEED combine a pair of LOD models. In play, at the first LOD transition, the game will crash with an assertion error. | ||||
Additional Information | The crash arises in unrelated code, caused by heap corruption, after a map shut down has already been triggered. Call stack for the point where the map shut down gets triggered: - TheDarkMod.exe!_wassert(const wchar_t * expr, const wchar_t * filename, unsigned int lineno) Line 314 - TheDarkMod.exe!idDynamicBlockAlloc<idDrawVert,1048576,1024>::FreeInternal(idDynamicBlock<idDrawVert> * block) Line 815 - TheDarkMod.exe!idDynamicBlockAlloc<idDrawVert,1048576,1024>::Free(idDrawVert * ptr) Line 646 - TheDarkMod.exe!R_ReallyFreeStaticTriSurf(srfTriangles_s * tri) Line 381 - TheDarkMod.exe!R_FreeDeferredTriSurfs(frameData_t * frame) Line 468 - TheDarkMod.exe!R_ToggleSmpFrame() Line 181 - TheDarkMod.exe!idRenderSystemLocal::EndFrame(int * frontEndMsec, int * backEndMsec) Line 743 If there's a double deletion, the problem probably happens much earlier in the frame. | ||||
Tags | No tags attached. | ||||
The problem is in CStaticMulti::UpdateRenderModel. CStaticMulti is the class for seed-combined entities. I haven't followed the path all the way through to find out exactly how the heap corruption comes about, but the problem arises because of the re-use of a render model pointer for a newly-constructed combined model, which was probably done to avoid an allocation. When the native game code changes a model, it always calls gameRenderWorld->FreeEntityDef, and uses a fresh pointer for a different model. There are parts of the engine code that *rely* on hModel pointers always pointing to the same model, for example idRenderWorldLocal::UpdateEntityDef which compares the old and the new hModel pointers for an entity when deciding whether it can leave decals in place. The renderer's model code does look like you *should* be able to construct a new model using an existing pointer in this way, because it provides an InitEmpty() method that clears the surfaces of the model. But in the native code only dynamic models use that method, not statics, and for dynamic models there's no concept of consistency from frame to frame. Changing the code to clear the entity def and use a newly allocated pointer for the new model stops the problem. That's also what the (non-buggy) LOD code does. |
|
At rev 6511 /trunk/game/StaticMulti.cpp /trunk/game/StaticMulti.h |
|
Nice catch. | |
Date Modified | Username | Field | Change |
---|---|---|---|
27.06.2015 15:10 | SteveL | New Issue | |
27.06.2015 15:10 | SteveL | Status | new => assigned |
27.06.2015 15:10 | SteveL | Assigned To | => SteveL |
27.06.2015 15:12 | SteveL | Additional Information Updated | |
27.06.2015 15:12 | SteveL | Description Updated | |
27.06.2015 22:45 | SteveL | Note Added: 0007604 | |
28.06.2015 20:54 | SteveL | Note Added: 0007605 | |
28.06.2015 20:54 | SteveL | Status | assigned => resolved |
28.06.2015 20:54 | SteveL | Fixed in Version | => TDM 2.04 |
28.06.2015 20:54 | SteveL | Resolution | open => fixed |
28.06.2015 20:58 | SteveL | Relationship added | related to 0004169 |
29.06.2015 04:09 | grayman | Note Added: 0007607 |