Archived issue #0033834
Configuration - Access violations when unloading DLL after STEP-/IGES-import
Description
Fix to metadata:
* OCCT Version is 7.8.1
We use OCCT within a shared library (32 bit DLL) which is dynamically loaded and unloaded with LoadLibrary/FreeLibrary functions.
Our DLL uses OCCT as shared libraries. (But these errors occur even when using static OCC libs).
After Importing an STEP or IGES file, access violation exceptions are raised when unloading the DLL (FreeLibrary).
Sometimes these errors are dropped by the OS (so they are observed only when the debugger is attaced) but sometimes they crash the whole application.
The situation gets much worse if some of the OCCT-Dll's are not unloaded because they are used in other parts of the program. (E.g. we always use some modeling algorithms but the Import/Export is only loaded when needed).
As far as I analyzed the issue it has to deal with the lots of static maps that register types and instances. So I suppose a relation to #0033719
* OCCT Version is 7.8.1
We use OCCT within a shared library (32 bit DLL) which is dynamically loaded and unloaded with LoadLibrary/FreeLibrary functions.
Our DLL uses OCCT as shared libraries. (But these errors occur even when using static OCC libs).
After Importing an STEP or IGES file, access violation exceptions are raised when unloading the DLL (FreeLibrary).
Sometimes these errors are dropped by the OS (so they are observed only when the debugger is attaced) but sometimes they crash the whole application.
The situation gets much worse if some of the OCCT-Dll's are not unloaded because they are used in other parts of the program. (E.g. we always use some modeling algorithms but the Import/Export is only loaded when needed).
As far as I analyzed the issue it has to deal with the lots of static maps that register types and instances. So I suppose a relation to #0033719
Steps to reproduce
Build a shared library with:
#include "IGESControl_Reader.hxx"
#include "STEPControl_Reader.hxx"
#include <iostream>
#include <windows.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C"
{
void __declspec(dllexport) _cdecl RunImport(char const* szName)
{
std::cerr << "Running Import of " << szName << "\n";
STEPControl_Reader r;
IGESControl_Reader ir;
}
}
and a console application with
#include <iostream>
#include <windows.h>
DWORD ExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS* ep)
{
auto addr = ep->ExceptionRecord->ExceptionAddress;
std::cerr << "ErrorCode = 0x" << std::hex << code << " Address= 0x" << addr << "\n" << std::flush;
return EXCEPTION_EXECUTE_HANDLER;
}
int main()
{
auto hXS = LoadLibrary(L"TKernel.dll");
std::cout << std::hex << "Address of TKernel.dll: 0x" << hXS << "\n";
while (true)
{
__try
{
auto h = LoadLibrary(L"TestDll");
std::cout << "Address of TestDll: 0x" << h << "\n";
typedef void(*RunImportFunc)(char const*);
RunImportFunc pRunImport = (RunImportFunc)GetProcAddress(h, "RunImport");
std::cout << "Address of RunImport: 0x" << pRunImport << "\n";
if (pRunImport)
{
pRunImport("C:\\Testfile.step");
}
std::cout << "Unload TestDll\n" << std::flush;
bool bUnloaded = FreeLibrary(h);
std::cout << "Unloading result " << std::boolalpha << bUnloaded << "\n" << std::flush;
}
__except(ExceptionFilter(GetExceptionCode(), GetExceptionInformation()))
{
std::cerr << "ERROR\n" << std::flush;
break;
}
}
}
Let the application run for some seconds an afterusually less than 10 iterations of the while loop an access violation error is thrown.
#include "IGESControl_Reader.hxx"
#include "STEPControl_Reader.hxx"
#include <iostream>
#include <windows.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C"
{
void __declspec(dllexport) _cdecl RunImport(char const* szName)
{
std::cerr << "Running Import of " << szName << "\n";
STEPControl_Reader r;
IGESControl_Reader ir;
}
}
and a console application with
#include <iostream>
#include <windows.h>
DWORD ExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS* ep)
{
auto addr = ep->ExceptionRecord->ExceptionAddress;
std::cerr << "ErrorCode = 0x" << std::hex << code << " Address= 0x" << addr << "\n" << std::flush;
return EXCEPTION_EXECUTE_HANDLER;
}
int main()
{
auto hXS = LoadLibrary(L"TKernel.dll");
std::cout << std::hex << "Address of TKernel.dll: 0x" << hXS << "\n";
while (true)
{
__try
{
auto h = LoadLibrary(L"TestDll");
std::cout << "Address of TestDll: 0x" << h << "\n";
typedef void(*RunImportFunc)(char const*);
RunImportFunc pRunImport = (RunImportFunc)GetProcAddress(h, "RunImport");
std::cout << "Address of RunImport: 0x" << pRunImport << "\n";
if (pRunImport)
{
pRunImport("C:\\Testfile.step");
}
std::cout << "Unload TestDll\n" << std::flush;
bool bUnloaded = FreeLibrary(h);
std::cout << "Unloading result " << std::boolalpha << bUnloaded << "\n" << std::flush;
}
__except(ExceptionFilter(GetExceptionCode(), GetExceptionInformation()))
{
std::cerr << "ERROR\n" << std::flush;
break;
}
}
}
Let the application run for some seconds an afterusually less than 10 iterations of the while loop an access violation error is thrown.
Public activity
3 archived notes
Participants are labeled by their role within this record.
Commenter 2 unloading is not accepted for OCCT components for now.
The crash is expected. We have some plans to accept unloading, but now it is not supported.
The crash is expected. We have some plans to accept unloading, but now it is not supported.
The issue related with XSBase logic.
We plan to rework it. Unfortunately, it will be later then 7.9
We plan to rework it. Unfortunately, it will be later then 7.9
Commenter 3 Thank you for the information.
So I will change our application to never unload these DLL's and observe the progress concerning these issues.
So I will change our application to never unload these DLL's and observe the progress concerning these issues.
Related records