Bug in OCC 6.9.1 and 7.0.0 using VS 2015 compiler.

Hi. We tried to use OCC (versions 6.9.1 and 7.0.0) with VS 2015 compiler (Update 2). We succeeded with 32bit compilation, but when we tried to run our application or OCC examples, OCC generated message with error depicted in attached picture. Bug occurs during initialization of OCC static global variables. We did two distinct 32bit compilations of versions 6.9.1 and 7.0.0 using two distinct machines and this bug appeared in all cases. Our previous compilation with VS 2013 worked well. Are we missing something? Or is there any workaround?

Thanks in advance

Honza

Attachments: 
Forum supervisor's picture

Dear Jan,

This is known problem, reported in Mantis and fixed in current master: see commit marked by ID 27385 in OCCT Git repository.
The cause of the crash is careless calls to methods of cerr from method Reset() of OSD_Error, which in turn is called from the constructor.
The effect of this depends on initialization order of globals defined in TKernel.
The wrong code existed from early versions of OCCT, but until recent experience with VS 2015 it has never exhibited a problem.

You can try the fix and report result.

Best regards,

FSR

Fabian Gerold's picture

The same problem occurs in my OCC project with VS 2015.

When I change Project Settings->Linker->System->SubSystem to "/SubSystem:Console", the problem goes away, probably because the console gets initialized and cerr redirected to the console before initializing static variables.

But that is only a temporary workaround. Has anyone a solution for this?

Julien Finet's picture

I also have the problem running (a recent version of )​OCE built with MSVC 14.0.

To reproduce inside the OCE solution, you can change the macro add_oce_test with the line:

add_executable(${test_name} ${SOURCE_FILES})

with

add_executable(${test_name} WIN32 ${SOURCE_FILES})

And then add in boolean_ops.cpp:

#include <windows.h>
#include <stdio.h>
#include <shellapi.h>
#include <locale>
#include <codecvt>
#include <string>

int __stdcall WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nShowCmd)
{

    // CommandLineToArgvW has no narrow-character version, so we get the arguments in wide strings
    // and then convert to regular string.
    int argc;
    LPWSTR* argvStringW = CommandLineToArgvW(GetCommandLineW(), &argc);

    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converter;

    std::vector< const char* > argv(argc); // usual const char** array used in main() functions
    std::vector< std::string > argvString(argc); // this stores the strings that the argv pointers point to
    for (int i = 0; i < argc; i++)
    {
        argvString[i] = converter.to_bytes(argvStringW[i]);
        argv[i] = argvString[i].c_str();
    }

    LocalFree(argvStringW);
    testing::InitGoogleTest(&argc, const_cast< char** >(&argv[0]));
    return RUN_ALL_TESTS();
}

Finally, you can simply compile the boolean_ops_test project and run it. The same error will be generated as run time:

Debug Assertion Failed!

Program: ...vs2015-64-qt56-debug\OCE-build\bin\Debug\boolean_ops_test.exe
File: minkernel\crts\ucrt\src\appcrt\lowio\lseek.cpp
Line: 74

Expression: ("Invalid file descriptor",0)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

Julien Finet's picture

I spoke too fast. The problem is indeed solved in OCCT. It is just NOT solved on OCE.

Thanks,
Julien Finet.