Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is QtCreator/MSVC linking 64 bit system DLLs to my 32 bit application?

UPDATE: This is all essentially bogus. It turns out the version of Depends.exe on the machine where the application runs was the 32 bit version. Upon fixing that, both machines show the system DLLs as 64bit, so that is not the source of the problem. Not sure why depends shows them that way in a 32 bit exe.


FURTHER UPDATE: Ultimately the problem was one 64 bit DLL. This was easier to find after using the correct version of Dependency Walker. Selecting the 32 vs 64 bit version is not based on the platform you're running on. From the FAQ:

Dependency Walker will work with any 32-bit or 64-bit Windows module. There are 32-bit and 64-bit versions Dependency Walker. All versions are capable or opening 32-bit and 64-bit modules. However, there are major advantages to using the 32-bit Dependency Walker to process 32-bit modules and the 64-bit Dependency Walker to process 64-bit modules. This is especially true when running on a 64-bit version of Windows, which allows execution of both 32-bit and 64-bit programs. The 32-bit subsystem on 64-bit Windows (known as "WOW64") has its own private registry, "AppPaths", "KnownDlls", system folders, and manifest processing. Only the 32-bit version of Dependency Walker can access this 32-bit environment, which is needed to accurately process a 32-bit module. Likewise, only the 64-bit version of Dependency Walker can fully access the 64-bit environment, so it should always be used for processing 64-bit modules.


I have an application that builds correctly on one machine and incorrectly on another one. Both are MacBook Pros running Windows 7 via BootCamp. They are being built via QtCreator with VS2010 as the compile/link tool.

On Machine A it compiles and links without any reported errors. However, when run it fails with a 0xc000007b error (STATUS_INVALID_IMAGE_FORMAT). Depends.exe confirms that the exe is a 32-bit exe but that all of the Windows DLLs (advapi32.dll etc.) are linked as 64 bit DLLs. It seems as though this would be a link time error but apparently not.

On Machine B, everything compiles and runs correctly. Depends.exe confirms that the exe and all linked DLLs are 32-bit.

My Qt project is configured as follows:

qmake: qmake.exe PROJECT.pro -r -spec win32-msvc2010 "CONFIG+=declarative_debug"

I believe the -spec win32-msvc2010 part is sufficient to specify a 32 bit build.

The project file explicitly links to the Windows import lib files located in: C:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/Lib I have confirmed these are 32 bit import libs. An explicit LIB+= line in the project file calls out this path. If this line is removed from the project file, the link succeeds anyway. So I am not sure how the location of the Windows system import libs is specified in that case.

I verified with dumpbin that import .libs are tagged as either 32 or 64 bit. We are specifiying locations with 32 import libs.

Because one machine works and another doesn't, I believe the problem is one of machine configuration. Therefore, I removed and re-installed the MS tools from Machine A:

  • Uninstalled VS2010, Windows 8 SDK, .NET Framework 4.5, QT Libraries and QtCreator.
  • Reinstalled all of the above, in this order:

    1. VS2010
    2. VS2010 SP1
    3. .NET Framework 4.5
    4. Windows 8 SDK
    5. Qt Libraries 4.8.4
    6. QtCreator 2.7.1

I still get a 32 bit exe linked to 64 bit DLLs.

What could be causing the strange linking? And/or how can I determine more precisely why it thinks it should link to 64 bit DLLs?

like image 647
Steve Fallows Avatar asked Nov 12 '22 03:11

Steve Fallows


1 Answers

It is not.

Answer from question text:

This is all essentially bogus. It turns out the version of Depends.exe on the machine where the application runs was the 32 bit version. Upon fixing that, both machines show the system DLLs as 64bit, so that is not the source of the problem.

Ultimately the problem was one 64 bit DLL. This was easier to find after using the correct version of Dependency Walker. Selecting the 32 vs 64 bit version is not based on the platform you're running on. From the FAQ:

Dependency Walker will work with any 32-bit or 64-bit Windows module. There are 32-bit and 64-bit versions Dependency Walker. All versions are capable or opening 32-bit and 64-bit modules. However, there are major advantages to using the 32-bit Dependency Walker to process 32-bit modules and the 64-bit Dependency Walker to process 64-bit modules. This is especially true when running on a 64-bit version of Windows, which allows execution of both 32-bit and 64-bit programs. The 32-bit subsystem on 64-bit Windows (known as "WOW64") has its own private registry, "AppPaths", "KnownDlls", system folders, and manifest processing. Only the 32-bit version of Dependency Walker can access this 32-bit environment, which is needed to accurately process a 32-bit module. Likewise, only the 64-bit version of Dependency Walker can fully access the 64-bit environment, so it should always be used for processing 64-bit modules.

like image 52
Martin Ba Avatar answered Nov 15 '22 07:11

Martin Ba