Static qT compilation and mingwm10.dll (MinGW) confusion.


After some reading, on the web, about MinGW compiler It comes to my attention that using static qT build without mingwm10.dll could cause memory leeks. That’s due to specific job that mingwm10 perform, with is catch dying threads and clean up data after them and handle exception in code. This is probably the reason, why by default, MinGW links that library in the first place.
Brief introduction:
So what the exception are? Well to put it simply something like this:
[cc lang=”cpp-qt” escaped=”true” width=”90%” height=”100%”]void MainWindow::exceptionTest( int x )
{
if( x == 0 ) throw “x is equal to 0”;
qDebug() << x;
}
void MainWindow::on_pushButton_clicked()
{
try{
exceptionTest( 2 );
exceptionTest( 0 );
}catch( const char* e){
qDebug() << e;
}
}[/cc]
In nutshell code test if particular peace of code do the job right and if not, what kind of error there was. In release mode you don’t really want that inside your application. Reason is simple, normal user, seeing something like that (i.e. in console output, assuming application is CLI), would be only confused. To prevent that from happening, while configuring qT, you pass something like this:

configure -static -release -no-exceptions

that way ( -no-exceptions ) exceptions are not supported. That rise an error, if code use exceptions, at compilation time like this one:

error: exception handling disabled, use -fexceptions to enable

on build with exception support, output (given by above code) would be like this:

2
x is equal to 0

I personally comment out any debug information on release build, so that’s not a problem. Alternatively You could use “ifdef” like so:

[cc lang=”cpp-qt” escaped=”true” width=”90%” height=”100%”]#ifdef QT_DEBUG
qDebug() << “Application compiled in debug mode”;
//do Debug stuff here
#endif

#ifdef QT_NO_DEBUG
qDebug() << “Application compiled in release mode”;
//do release stuff here
#endif[/cc]

How about cleaning after threads?
In src [1], mthr_init.c, is a short explanation that absent of mingwm10.dll would cause for each throw/catch in each thread memory leek of size (24 * sizeof (void*)). That would only happens, when You allow exception on build without mingwm10.dll linked.
That said there is no way to not link mingwm10.dll without -no-exceptions. (at least if You don’t hack configure files to actually allow that)
So bottom line here is that if You don’t want any additional MinGW dll’s You need to pass -no-exceptions in configure.

As stated before, although mingwm10.dll is allways linked, code inside that library is not always executed. Two condition must be met:

gcc uses -mthreads flag
and Your code uses exceptions in threads

so as long as that’s not true You are safe.

To test if that’s actually true I wrote small application to see for myself. First of all, how to know if code uses mingwm10.dll? There is a nice  bin utility called objdump.exe located in /bin directory of MinGW. Using this application You can find out what dll’s your application uses.

Firstly I use this application on stat_test_dyn.exe (qT dynamic, release mode):

objdump.exe -j .idata -p stat_test_dyn.exe | sed -ne ‘/mingwm10/,/^$/{p;}’
DLL Name: mingwm10.dll
vma:  Hint/Ord Member-Name Bound-To

then I did the same for stat_test_static.exe (qT static, release mode):

objdump.exe -j .idata -p stat_test_static.exe | sed -ne ‘/mingwm10/,/^$/{p;}’
no output

As you can see, there is no mingwm10.dll in static build with -no-exceptions. Also I performed some test, to be absolutely sure that there is nothing suspicious going on. My test application rune 1000 threads, one after another, on button click. I performed ten tests (simply pressed ten times button after each job finished) and measured memory usage. Result are as follows:

Dynamic build, release mode, before ten test

Dynamic build, release mode, before ten test

Dynamic build, release mode, after ten test

Dynamic build, release mode, after ten test

Memory increase in this mode was 168KB. After that I did same test for static build:

Static build, release mode, before ten test

Static build, release mode, before ten test

Static build, release mode, after ten test

Static build, release mode, after ten test

In this mode, memory increase was 120KB.

Memory increase is probably due to internal communication between application and dll’s, or the way thread’s are handled by qT itself (I’m not shure about that thought).
The source code, that I used for this test, can be downloaded here: source code test application.
Test performed on Windows XP SP3 32bit with Process Explorer v 11.33.

Reference material:
[1] http://www.devdaily.com/scw/c/cygwin/src/winsup/mingw/mthr_init.c.shtml
[2] http://wiki.forum.nokia.com/index.php/POSIX_TLS#Creating_a_key
[3] http://old.nabble.com/mingwm10.dll-ts8920679.html

, , , , ,

Comments are closed.