When is a divide by zero not a divide by zero? A puzzle in the debugger (static variable issues)

岁酱吖の 提交于 2019-11-28 11:58:22

Since the code is part of a member function, and you're calling this function from multiple threads, the static variables are not thread-safe if using a compiler that does not conform to C++ 11 standards. Thus you may get data races when initializing those two static variables.

For a C++ 11 standard conforming compiler, static variables are now guaranteed to be initialized by the first thread, while subsequent threads wait until the static is initialized.

For Visual Studio 2010 and below, static local variables are not guaranteed to be thread safe, since these compilers conform to the C++ 03 and C++ 98 standard.

For Visual Studio 2013, I am not sure of the level of C++ 11 support in terms of static local initialization. Therefore, for Visual Studio 2013, you may have to use proper synchronization to ensure that static local variables are initialized correctly.

For Visual Studio 2015, this item has been addressed and proper static local initialization is fully implemented, so the code you currently have should work correctly for VS 2015 and above.


Edit: For Visual Studio 2013, static local thread-safe initialization is not implemented ("Magic Statics"), as described here.

Therefore, we can cautiously verify that the reason for the original problem is the static-local initialization issue and threading. So the solution (if you want to stick with VS 2013) is to use proper synchronization, or redesign your application so that static variables are no longer needed.

The problem may be related to multithreading.

  1. A thread enters the function
  2. Checks the hidden "is_initialized" static variable to see if initialization has already been performed
  3. The var is 0, so it sets the variable to 1 and proceeds reading the registry
  4. At this point another thread enters the function
  5. The second thread sees the variables as already initialized and skips the initialization code
  6. The division is performed when the denominator is still 0 (the first thread is still reading the registry)
  7. The program crashes, but in the meanwhile the first thread completes execution, setting the variables that you see in the dump.
  8. You lose sleep thinking how the impossible happened
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!