- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I've run into a weird problem while using some software using IPP and openCV.
My software only uses ippi (from ipp) and openCV libraries. All is linked against the dynamic version of ippi, ippcore & cxcore.
When it loads, it starts by loading dependency dlls : ippi, ippcore and cxcore. As you must know, openCV is programmed to automatically load ipp if present. It does this by using the LoadLibrary function. What happens is that the LoadLibrary will fail to load any ipp module except the ones dynamically linked by the software.
You can reproduce this behaviour using cxcore and cxcoretest projects from openCV.
I just modified cxcoretest_main.cpp from cxcoretest as follow
[cpp]#include "PATH_TO_IPP_6.0_IA32includeipp.h" #pragma comment(lib, "PATH_TO_IPP_6.0_IA32\stublib\ippcore.lib") #pragma comment(lib, "PATH_TO_IPP_6.0_IA32\stublib\ippi.lib") int main( int argc, char** argv ) { const IppLibraryVersion* ippVersion = ippiGetLibVersion(); printf("%s", ippVersion->Name); return test_system.run( argc, argv ); }[/cpp]
The worst about it is that when failing to load ipp 6.0 modules, openCV would try to load 5.3 module which are also installed on my computer resulting in libguide40 and libiomp5md to conflict....
I made the same test with ipp 5.3 version (by removing 6.0 module from cxswitcher.cpp and using 5.3 in cxcoretest_main.cpp) and it worked just fine (all modules are loaded)
What seems to happen is the following : ippMalloc function in ippcore doesn't seem to be properly initialized (it makes a call to some unitialized function pointer) when LoadLibrary function is called.
Is this a known regression ?
Will there be a new release shortly ?
Regards
Matthieu
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The issue here is not OpenCV related. I just used OpenCV to illustrate that issue because I discovered this problem using OpenCV and anyone can reproduce this behaviour using it.
As I understand, my previous post wasn't clear enough. I tried to make a simple test case not OpenCV related to illustrate this behaviour and it became weirder.
So let me explain it again :
On one hand, I've got a dynamic module which does some stuff and uses ipp modules when found (like OpenCV does). It does this with the help of the LoadLibrary function. The LoadLibrary function is called when the module is loaded (DllMain / C++ class initializer). We'll call it "foo.dll".
On the other hand, I've got an executable which uses functions from ippi module and foo module. It links with the ippi stublib and the foo stublib.
When I start the executable, foo.dll loads and will fail to load any ipp module except ippi
I could reproduce this behaviour with the following code.
main.cpp :
[cpp]#include#include #include "ipp-6.0-ia32includeipp.h" #pragma comment(lib, "foo.lib") #pragma comment(lib, "ipp-6.0-ia32stublibippi.lib") __declspec(dllimport) const char* __cdecl GetIppsVersionName(void); int main(int argc, char* argv[]) { const IppLibraryVersion* ippVersion; ippVersion = ippiGetLibVersion(); printf("%sn", ippVersion->Name); printf("%sn", GetIppsVersionName()); getc(stdin); return 0; }[/cpp]
foo.cpp:
[cpp]#include#include #include "ipp-6.0-ia32includeipp.h" HMODULE ippModule; BOOL APIENTRY DllMain( HMODULE hModule, DWORD fdwReason, LPVOID lpReserved ) { switch( fdwReason ) { case DLL_PROCESS_ATTACH: ippModule = LoadLibraryA("ipps-6.0.dll"); break; default: break; } return TRUE; } typedef const IppLibraryVersion* (__stdcall * version_fn)(void); __declspec(dllexport) const char* __cdecl DummyGetIppsVersionName(void) { static const char error[] = "Couldn't load ipps-6.0.dll module"; if (ippModule == NULL) return error; version_fn GetVersion = (version_fn)GetProcAddress(ippModule, "ippsGetLibVersion"); return GetVersion()->Name; }[/cpp]
Here is the printed output :
ippiv8-6.0.dll
Couldn't load ipps-6.0.dll module
The strangest thing occured when I swapped two lines in main.cpp
if you try using this
[cpp]#pragma comment(lib, "ipp-6.0-ia32stublibippi.lib") #pragma comment(lib, "foo.lib")[/cpp]
then the output will be
ippiv8-6.0.dll
ippsv8-6.0.dll
In the first case, ippcore-6.0.dll and ippi-6.0.dll appears in the debugger as loaded whereas in the second case ippiv8-6.0.dll is also loaded. Curiously the same behaviour apply for 5.3 in my test case but not in OpenCV (weird again...)
What went wrong at which point ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The issue here is not OpenCV related. I just used OpenCV to illustrate that issue because I discovered this problem using OpenCV and anyone can reproduce this behaviour using it.
As I understand, my previous post wasn't clear enough. I tried to make a simple test case not OpenCV related to illustrate this behaviour and it became weirder.
So let me explain it again :
On one hand, I've got a dynamic module which does some stuff and uses ipp modules when found (like OpenCV does). It does this with the help of the LoadLibrary function. The LoadLibrary function is called when the module is loaded (DllMain / C++ class initializer). We'll call it "foo.dll".
On the other hand, I've got an executable which uses functions from ippi module and foo module. It links with the ippi stublib and the foo stublib.
When I start the executable, foo.dll loads and will fail to load any ipp module except ippi
I could reproduce this behaviour with the following code.
main.cpp :
#include
foo.cpp:
#include
Here is the printed output :
ippiv8-6.0.dll
Couldn't load ipps-6.0.dll module
The strangest thing occured when I swapped two lines in main.cpp
if you try using this
#pragma comment(lib, "ipp-6.0-ia32\stublib\ippi.lib") #pragma comment(lib, "foo.lib")then the output will be
ippiv8-6.0.dll
ippsv8-6.0.dll
In the first case, ippcore-6.0.dll and ippi-6.0.dll appears in the debugger as loaded whereas in the second case ippiv8-6.0.dll is also loaded. Curiously the same behaviour apply for 5.3 in my test case but not in OpenCV (weird again...)
What went wrong at which point ?
Hi,
I believe you are not allowed to call LoadLibrary from dllmain (see MSDN documentation)
Emmanuel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir
Hi,
Thanks for your input. I've just looked at MSDN documentation to see what are the limitations.
So, in my previous example, it appears that ippcore-6.0.dll is assumed to be loaded when trying to load ipps-6.0.dll. But initialization code (DllMain) from ippcore-6.0.dll had not been called yet.
So in my case, I'll just do it otherwise. As for OpenCV, it doesn't follow recommendations in MSDN and that's what causing such a mess...
Regards,
Matthieu
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vladimir
Hi Vladimir,
This is indeed a tricky subject. Here is what the documentation says under DllMain (I do believe the restriction was not as clearly stated in the past but I didn't install an older MSDN library to check ;) )
The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, the entry-point function must not call the FreeLibrary function (or a function that calls FreeLibrary) during process termination, because this can result in a DLL being used after the system has executed its termination code.
Also in the MSFT "Dll best practice document":
You should never perform the following tasks from within DllMain:
Call LoadLibrary or LoadLibraryEx (either directly or indirectly). This can cause a deadlock or a crash.
...
Of course if you want to load your own dll and you know you don't introduce any loop then there is no technical limitation.
Emmanuel
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page