4

After upgrading from Visual Studio 2012 to Visual Studio 2015 my project gets heap corruption and access violation errors before even reaching the main function. There is simply no code that I can debug. I checked for static variables and anything that can possibly be created on a stack but I do not seem to have any. I tried to launch the program with empty main function:

int main(){return 0;};

but I still get access violation error. The program is a GUI form with mixed C++/CLI code. I made sure I have rebuilt third party libraries (curl) from source with VS2015 and use correct DLLs. Have no clue where do these errors come from - everything worked fine before. How can I fix/debug it? I googled a lot and tried even running gflags but the debugger does not stop on any human readable code. The error reads:

Exception thrown at 0x5A4C7988 (verifier.dll) in MyProgramName.exe: 0xC0000005: Access violation reading location 0xA46FEC13.

EDIT 1: verifier.dll has nothing to do with the error. It turns out this library is loaded when I added image file to gflags.exe in attempt to debug the program. After discarding these changes I got back to the original error message which is heap corruption raised by ntdll.dll.

EDIT 2: I stripped down the code to the bare minimum by deleting all .h files and .cpp files till the error got away. This is very inefficient way to debug, yet since I did not know any better I did it anyway.

#include "MyGUI.h"
#include <boost/date_time/posix_time/posix_time.hpp>

[STAThread]
void main(array<String^>^ args) {
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Application::Run(gcnew MyProject::MyGUI);
}

If I then remove the line

#include <boost/date_time/posix_time/posix_time.hpp>

then the problem goes away and the gui starts with no errors.

The reason why I got access violation error is because posix_time library silently links a .lib file. When I migrated from VS2012 to VS2015 I have rebuilt all the boost libraries in multiple variants and the additional library directories have been specified correctly in the project and contained the right variants of the libraries. I used posix_time library in other projects without problems however other projects were targeting x64 bit but the one I had a problem with is a x32 bit. I was linking x32 bit project against lib32 directory of my boost build, which is correct. It turns out that the reason why my application crashed was a bug in 32bit version of the posix_time library. Even linking my 32bit application to x64 folder resolves the problem. However, since I did not use microseconds,

BOOST_DATE_TIME_NO_LIB

compiler directive was sufficient. According to boost documentation,

The nano-second resolution option uses 96 bits of underlying storage for each ptime while the micro-second resolution uses 64 bits per ptime.

The latter quote and the fact that x64 bit library works fine makes me think that 32bit implementation of the library is faulty.

For those who might find it helpful - this was the reason. As for my original question how to debug such a crash when the heap corrupts even before the entry point is reached (and therefore no any source code or debug information is available) without wasting 7 hours to strip down the project till there is only one line left - I leave the question open.

If someone can point out a better approach to find such kind of errors - this will be very instructive.

EDIT 3: Apparently this is not the end. After fixing boost libraries and reverting to the full code I got the error again. Problem is caused by use of a static variable in a GUI windows form method callback:

System::Void comboBoxStart_SelectionChangeCommitted(System::Object^  sender,
                                                    System::EventArgs^  e) {

    static wstring LastChoice; //This line is enough to reproduce the crash

}

Can anyone explain why this leads to access violation reading location? Similar symptoms are described in this post.

Community
  • 1
  • 1
OGCJN
  • 393
  • 3
  • 9

2 Answers2

2

Before loading your main, the executable will load dependent libraries and execute their own "main". It's a bit more complicated than that, but the important thing to understand is that code gets executed in those libraries first. If there are errors there, it will crash.

Your error message mentions that verifier.dll is the source of the problem. You should investigate that DLL first. Did you build it yourself? Does it have all required dependencies to run?

Eric
  • 19,525
  • 19
  • 84
  • 147
  • No, I do not know what is verifier.dll library. The only dependent library I have is CURL which I rebuilt from source. I have a feeling that the error happens after the managed code is "initialized" and the application passes over to unmanaged code? That's my best guess from what I googled on the problem so far... – OGCJN Mar 09 '17 at 06:14
  • Have you tried dropping curl for testing purposes? Does it run when curl does not load? – Eric Mar 09 '17 at 06:17
  • If there was an error in the code I would have debugged it quickly. The point is that it is some other library and I have no clue where it comes from since it does not even reach main nor is it linked by me. – OGCJN Mar 09 '17 at 06:18
  • I don't remember the exact ramifications, but I do recall that getting pure C libraries to work with C# is a pain. Have you considered using a C# port of libcurl ? http://stackoverflow.com/questions/24567344/use-libcurl-net-to-download-a-file – Eric Mar 09 '17 at 06:21
  • Also there are project settings to in c# to debug native code, have you enabled that? – Eric Mar 09 '17 at 06:24
  • have just tried what you proposed - no, unlinking the curl library and removing all curl related code did not help. Same error. – OGCJN Mar 09 '17 at 06:25
  • It is C++, though yes I know that native and managed code together is somewhat a mess...however in VS2012 everything worked as a charm. I have quite a lot of native code. GUI has over 400 controls and native code is more than 10000 lines all together. – OGCJN Mar 09 '17 at 06:28
  • In the output window, you should see libraries loading. Can you pinpoint the last one before the crash? – Eric Mar 09 '17 at 06:30
  • ...ole32.dll, uxtheme.dll, oleaut32.dll, msvcp_win.dll with msvcp_win.dll being the last one, yet exception is thrown at 0x59D17988 (verifier.dll). Verifier is not even loaded - I think it is a consequence of me trying to use gflags to debug. Before I tried that the error was thrown by ntdll.dll. – OGCJN Mar 09 '17 at 06:37
1

Access violation was caused by using static variables in managed code. I used a static variable of wstring type (native C++ type!) inside a windows form GUI callback (managed code). My guess is that the program tried to initialize the variable before the managed code initialization was over, causing the error before even reaching the program entry point.

After removing all static variables from managed code the problem disappeared.

OGCJN
  • 393
  • 3
  • 9