I have an app crashing some times because the MS _purecall is being called but the data I see on the crash dump is not what I expected.
I have CSocket derived from CConnection, the latter has a pure virtual function named DoRead and the app crashes when an instance of CSocket calls this function in a worker thread.
Following the register values and how Microsoft implements C++ virtual tables and calls, I see RCX has the correct this value, the first quad-word points to the v-table and the v-table is correct so the call to _purecall should not happen.
But after seeing how the constructor is implemented, I see CConnection constructor sets up the pointer to the v-table which includes the call to _purecall and then, CSocket's constructor overwrites this value with the correct/derived v-table.
This is what I suspect is happening:
- A thread calls to
new CSocket. - Before
CSocketconstructor is called and the v-table modified, the worker thread reads some memory near the pointer (probably because it is processing an operation of otherCSocketinstance) and that memory page is "cached" by the processor. - The thread creating
CSocketcontinues its execution finishingCSocketconstruction. - When the worker thread accesses the v-table, reads the value from the "cached" page instead of the real memory containing the correct v-table.
At first glance there is no memory barrier inserted by the compiler to avoid this.
Am I correct in my assumption? Is it possible to happen or the compiler/processor has a mechanism to avoid this?