Inverse Heisenbug - Unit test fails only when debugger is attached

后端 未结 4 2084
不知归路
不知归路 2021-01-19 21:39

I recently fixed a defect in our product, the symptom of which was an access violation caused by accessing a dangling pointer.

For good practice I added a unit test

相关标签:
4条回答
  • 2021-01-19 21:54

    I have isolated the cause of this problem - see this question for details.

    When running my test harness under the debugger, the memory consumed by the debugging environment meant that subsequent allocations/deallocations of the same object were always allocated in different parts of memory. This meant that when my test harness tried to access a dangling pointer, it crashed the test (technically this is undefined behaviour but this is test code and it seems to do what I need it to do).

    When running my test harness from the command line, subsequent allocations/deallocations of the same object always re-used the same block of memory. This coincedental behaviour meant that when I accessed what was in actuality a dangling pointer in my test case, it happened that the dangling pointer still pointed to a valid object. That's why I didn't see a crash.

    0 讨论(0)
  • 2021-01-19 22:08

    I ran into this years ago in reverse: The problem was only occurring when the debugger was not attached.

    It turned out the code was corrupting the stack-frame of the previous method activation and using the debugger introduced an intermediate stack-frame.

    You possibly have a similar situation.

    0 讨论(0)
  • 2021-01-19 22:14

    Generally, the VC++ debugger will fill heap-allocated memory with some known value when you delete the pointer to that memory. It's been quite a while since I've used Visual Studio, but it seems reasonable to me that 0xcdcdcdcd could be such a value. It seems most likely to me that the application is crashing properly when running in the debugger. When running in Release mode the runtime doesn't waste time overwriting deallocated memory, so some of the time you get "lucky" and the data stored in that memory is still valid.

    You can modify your build setting to turn on the option for filling deallocated memory with a known value in Release mode (don't forget to turn it off again when you're done). I'd guess if you did this your application would crash in Release mode.

    I appreciate that the value isn't always 0xcdcdcdcd, which may mean I'm wrong or may mean you have more than one path to a dangling pointer.

    0 讨论(0)
  • 2021-01-19 22:15

    I don't know if this will help you any, but I once ran into a bug which would manifest differently if the program was run under the Visual Studio debugger, or program was run externally, then had debugger attached.

    0 讨论(0)
提交回复
热议问题