Page 1 of 1

MatlabDemo batch crashes

Posted: 21 May 2013, 07:26
by krutanen
Hi,

The MatlabDemo_SignalProcessing.bat "crashes" with us. You get the usual windows, but then the log says that an access violation happened in the MatlabFilter. This happens both with the prebuilt version, and our own build. We have Windows 7, Matlab 2011b (both 32-bit and 64-bit), and Matlab 2012b (32-bit). However, these have only a small number of toolboxes installed. Does BCI2000 use any specific toolboxes? Any ideas?

Kalle

Re: MatlabDemo batch crashes

Posted: 21 May 2013, 08:04
by krutanen
An update. We uninstalled all Matlab versions, rebooted, and then installed Matlab 2012 32-bit will all the toolboxes. The same error persists.

Re: MatlabDemo batch crashes

Posted: 21 May 2013, 09:17
by mellinger
Hi,

an access violation always indicates some kind of bug. Unfortunately, I'm still lacking first-hand experience about the behavior of the LoadLibrary() and GetProcAddress() with regard to all possible 32-vs-64-bit combinations of OS, client application, DLL loaded, and COM objects instantiated by the DLL. For some of these combinations, it may be possible that LoadLibrary() succeeds in loading a DLL of the wrong architecture, and that the client application then crashes as soon as it tries to call one of the imported functions.

Normally, a 64 bit Windows system takes care of avoiding architecture mismatch, but this does not apply when dynamically loading the Matlab engine DLL.

In that case, multiple features of recent Windows versions are working together in order to create a terrible mess which is quite difficult to debug:
* User Account Control and Registry Virtualization when registering COM components under different kinds of user accounts,
* Folder Redirection and Registry Virtualization when running 32-bit executables on a 64-bit Windows,
* DLL search path modification (which was introduced to fix a security flaw related to DLL loading).

As a result, the DLLs and executables involved in your problem may be visible or hidden, may be loaded or not loaded depending on whether UAC is enabled or not, which user account you are running a process from, whether you are running the 32 bit version of com.exe when executing a process from there, and the history of all of the above with regard to COM component registration.

So what you might try is the following:
* Deinstall all versions of Matlab from your machine.
* Install a 32-bit version of Matlab.
* Open a command Window, and run
runas /user:administrator matlab /regserver
even if you might be logged in from a so-called "administrator" account.
* Make sure you are running a purely 32-bit version of BCI2000 (there might be bugs regarding interoperability of 32- and 64-bit BCI2000 executables).
* Copy the 32-bit libeng.dll from your Matlab installation to BCI2000/prog.

There might still be a problem if a wrong libeng.dll is lying around somewhere on your PATH (as it is seen by 32-bit processes), or in Windows/SysWOW64.

HTH,
Juergen

Re: MatlabDemo batch crashes

Posted: 21 May 2013, 10:50
by krutanen
We have two computers A and B. The (Matlab-demo of the) same build of BCI2000 works in computer A, but does not work in computer B (the crash above). It seems that this has something to do with dynamic linking. We can find only one libeng.dll on the whole harddisk, and that is in the Matlab installation directory. Both the computer A, and the computer B now have only Matlab 2011b 32-bit installed. We are running things from an administrator account. Using the runas command did not make a difference. We are running the 32-bit version of BCI2000.

I had a look at the dll-dependencies of MatlabFilter.exe (using a software called Dependency Walker), and saw that it didn't mention any Matlab dlls. Therefore it seems to me that the linking with Matlab is done in a "plug-in" style using LoadLibrary etc. Would you know why this style is used over the more traditional linking methods (say, load-time dynamic libraries)? I've also been wondering why the src/extlib/matlab directory contains local copies of matlab lib and header-files? The MatlabFilter source code is dependent on at least the header files there. Can that be a good thing? Isn't there a problem with matching these files against whatever Matlab version is present in the computer?

Kalle

Re: MatlabDemo batch crashes

Posted: 21 May 2013, 12:39
by krutanen
We can locate the crash into MatlabFilter.cpp at line 66, to the function call MatlabEngine::Open(), which is located at MatlabWrapper.cpp line 176. Here, ::LoadLibrary (trying to find libeng) returns dllHandle = 0, so the library-loading fails. Subsequently, the control goes to printing out an error message as follows:

Code: Select all

  
bcierr << "Could not load library " << inName << ":\n"
        << OSError().Message() << endl;
It is the OSError().Message() function which causes the actual crash. Two interesting questions arise:

1) Whether there is a bug in this error-reporting code?
2) Why the ::LoadLibrary fails with libeng?

Kalle

Re: MatlabDemo batch crashes

Posted: 21 May 2013, 13:00
by krutanen
We managed to solve this problem. First of all, the crash occurs because of a bug in the OSError class (OSError.cpp). My guess is that this has to do with you using a global variable for the default error message.

After this error-reporting is fixed, it becomes clear that ::LoadLibrary can not find libeng.dll. The reason for this is that libeng.dll is not in the path. And this is in turn is because the Matlab installation does not place the needed bin/win32 in the path variable of the operating system.

Kalle

Re: MatlabDemo batch crashes

Posted: 22 May 2013, 10:50
by mellinger
I had a look at the dll-dependencies of MatlabFilter.exe (using a software called Dependency Walker), and saw that it didn't mention any Matlab dlls. Therefore it seems to me that the linking with Matlab is done in a "plug-in" style using LoadLibrary etc. Would you know why this style is used over the more traditional linking methods (say, load-time dynamic libraries)?
  • It allows us to provide a reasonable error message to users in case the DLL is not found (at least if there is no crash in the function that reports the error, thanks for the hint).
  • It allows us to support multiple compilers and architectures without having to maintain a separate .lib file for each.
I've also been wondering why the src/extlib/matlab directory contains local copies of matlab lib and header-files? The MatlabFilter source code is dependent on at least the header files there. Can that be a good thing?
The .lib files remained from previous versions which did not use dynamic linking yet, so they could be removed by now.
Regarding the header files, I don't see a problem. Obviously, any code making use of a library will depend on the library's header files, there is no way around that. Having copies of those header files allows to build the MatlabFilter module on machines without Matlab installed.
Isn't there a problem with matching these files against whatever Matlab version is present in the computer?
Reasonable library vendors will not make breaking changes to their library interfaces, to allow existing binaries to run with newer versions of a library without being recompiled. Thus, compiling with an old version of a library's header file will typically pose no problem.

For libraries exporting class instances, such as Qt, the case is different because such a library will not be compatible across compilers, and different versions of the same compiler anyway. As a result, there is also not much sense in dynamically linking against such libraries in the first place, which is why BCI2000 comes with its own copy of Qt libraries, to which it is linked statically.
My guess is that this has to do with you using a global variable for the default error message.
Please note that it's a _static_ rather than a _global_ variable, which makes a big difference ;-)
But of course relying on a static variable to be initialized before being used at global init time is a bad programming error, yes :-(

Regards,
Juergen