Changeset 1111 for trunk/src


Ignore:
Timestamp:
Feb 28, 2013, 11:47:15 PM (12 years ago)
Author:
Dmitry A. Kuminov
Message:

corelib: Make sure QLibrary::load() doesn't change FPU control word.

This is known to happen on OS/2 when loading some DLLs and it causes
applications to unexpectedly crash with SIGFPE when doing some FPU
arithmetics (like division by zero).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/corelib/plugin/qlibrary_os2.cpp

    r877 r1111  
    4848#include "qfileinfo.h"
    4949#include "qdir.h"
     50
     51#include <float.h>
    5052
    5153#ifndef QT_NO_LIBRARY
     
    100102    QByteArray attempt = QFile::encodeName(QDir::toNativeSeparators(fileName));
    101103
     104    // It is known that the OS/2 DLL loader (or the init routine of some DLLs)
     105    // sometimes resets the FPU CW to a value that causes operations like
     106    // division by zero to throw SIGFPE instead of being handled by the FPU.
     107    // This is unexpected in many apps since they rely on the default C runtime
     108    // setting which is to handle them. The solution is to force the required
     109    // CW value and then restore it after loading the DLL.
     110
     111    _clear87();
     112    unsigned int oldbits = _control87(0, 0);
     113    _control87(MCW_EM, MCW_EM);
     114
    102115    APIRET rc;
    103116    char errModule[CCHMAXPATH] = { '\0' };
     
    108121        rc = DosLoadModule(errModule, sizeof(errModule), attempt, &pHnd);
    109122    }
     123
     124    _clear87();
     125    _control87(oldbits, 0xFFFFF);
    110126
    111127    if (rc != NO_ERROR) {
Note: See TracChangeset for help on using the changeset viewer.