quiverteam / Engine

Modified Version of Source 2007
106 stars 29 forks source link

Random crash when you turn flashlight on #24

Closed Demez closed 4 years ago

Demez commented 5 years ago

The crash is in tslist.h at line 43 { return ThreadInterlockedAssignIf64( pDest, value, comperand ); }

This can occur at random whenever you turn the flashlight on, or even with other things.

JJL772 commented 5 years ago

What is the exception that the debugger reports?

Demez commented 5 years ago

Unhandled exception thrown: read access violation. this->m_Head.value.Next was 0x44BB8000.

JJL772 commented 5 years ago

That is most likely caused by a dangling pointer that had the memory it points to freed, so there is probably a problem with tlist.

JJL772 commented 5 years ago

Also, can you post the callstack the next time the crash happens?

Demez commented 5 years ago

Older screenshot 2019-04-26_23-39-22_quiver_HALF-LIFE_2

JJL772 commented 5 years ago

So I did some digging for this, basically this is how it goes: Valve's memory allocator treats memory as a linked list of blocks, as most allocators do. When freeing/deleting a block of memory, it simply pushes a pointer to that into freelist.

When allocating a new memory block, the allocator uses the pop function to pop the first element from freelist, which will give the first free block. It then traverses the list of freed blocks until it finds a block big enough to fit the new block. The variable Next simply points to the next free block of memory. That value gets referenced for whatever reason in tlist (I wont question it).

The exception references a read-access violation which generally means the region of memory where Next points to isn't mapped to any physical memory. One of two causes here:

It might be best if we used tcmalloc's memory management functions (or the operating systems!) instead of Valve's custom ones. (tcmalloc is apparently one of the fastest memory allocators anyways)

JJL772 commented 4 years ago

I would like to revise my previous comment. There is NO use of OS memory allocators (malloc, free, etc.) in valve's custom allocator, just calls to VirtualAlloc and VirtualFree (and now mmap and munmap on linux). The tslist (which is a lock-less list of allocated blocks) somehow maintained an invalid pointer in a page that was returned to the OS. This could be one of two things: a bug with the allocator or an issue introduced by our upgrade to SDK 2013 libs. It could also be something else but who the heck knows.

My solution is to torch Valve's memory allocator. Just use platform malloc/calloc/free/whatever.

Demez commented 4 years ago

was just caused by me using 2 different header files with the 2 different class definitions of the same name, fixed a while ago