10

I'm writing a project in C++ with SDL2 on 64-bit Windows 10 using Visual Studio 2015. I recently purchased a new Windows 10 laptop and cloned my project from github. My project compiles correctly, but I get the following error when I run it:

The application was unable to start correctly (0xc000007b). Click OK to close the application.

Based on my research so far, this error is usually caused by loading an incompatible DLL, e.g. a 64-bit version instead of 32-bit. Suggestions I've found so far include:

  • Checking that I'm using the 32-bit versions of the SDL2 DLLs
  • Installing/reinstalling the x86 version of the Visual C++ Redistributable for Visual Studio 2015
  • Using Dependency Walker to troubleshoot which DLL is failing

My project is set to build for Win32, and I've ensured that I'm using the 32-bit versions of all DLLs I'm explicitly linking (libfreetype-6, libpng16-16, SDL2, SDL2_image, SDL2_mixer, and SDL2_ttf). I have confirmed that the x86 VC++ Redistributable is installed on my machine.

Finally, I've attempted to use Dependency Walker to determine what DLL might be causing the problem (although I've read caveats that Dependency Walker has a lot of false positives). These were the results:

Dependency Walker static analysis Dependency Walker static analysis

Dependency Walker profiling results Dependency Walker profiling results

After that point, the profiler freezes and never continues. Note that the SDL components and the VC runtime are loading without error.

The program compiles and loads correctly on my two older machines, one running 32-bit Windows 7 and one running 64-bit Windows 10.

Now for the actual question. What other steps can I take to debug this crash? Or does anyone see from the information I've provided what I'm doing wrong?

Related questions:

Edit:

As rflobao suggested, I was using the 64-bit version of Dependency Walker on a 32-bit exe. Here is the new output of my profiling run:

New Dependency Walker Profile Output

At this point, as before, Dependency Walker freezes. I'm still totally lost and don't feel like I'm any closer to being able to determine what's causing the problem.

Community
  • 1
  • 1
Jonathan Sharman
  • 636
  • 6
  • 16
  • 1
    The Windows OS is responsible for [searching and finding the first DLL](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx) that has a matching name. What may be happening is that there is a 64-bit component that you may not be aware of that's situated in a directory in your system PATH, and Windows happens to find that DLL and attempts to load it. – PaulMcKenzie Jun 17 '16 at 04:00
  • That makes sense. Do you know of a systematic way for me to determine which it is? Dependency Walker seems to be too out-of-date to be useful, and there are of course many hundreds of DLLs that can be found in my path. – Jonathan Sharman Jun 19 '16 at 02:31
  • In the dependency walker, click on the C:\ icon - that will tell you where it is picking up the files from. Have you tried running it from a 64-bit cmd prompt (the one in windows/system32) and from a 32-bit cmd prompt (the one in windows/syswow64). – cup Jun 19 '16 at 16:43
  • Are you actually reaching the main function? Did you install the 2015 redists on that machine? – paulm Jul 06 '16 at 07:30
  • Actually your 64bit exe must be loading a 32bit dll, copy all of the dlls to the same directory as the exe and check if that works, also confirm each dll is actually 64bit – paulm Jul 06 '16 at 07:32

3 Answers3

5

Note that Dependency Walker has 32 and 64 bit version. If your application is 32-bit you should use the 32 bit version. Otherwise the Dependency Walker will see the libs to System32 and not SisWOW64. You image show 32bit and 64bit libs mixed, where 64 has error.

rflobao
  • 562
  • 2
  • 8
  • That was indeed one of my problems. I was using the 64-bit Dependency Walker on my 32-bit executable. Thank you! Updating my question with the new output. – Jonathan Sharman Jul 06 '16 at 07:06
  • Verify in Dependency Walker "without run", if exists some lib 64-bit yet. If all libs are 32-bit, is likely that libs64 are loaded dynamically in lazy mode. Make sure all the libs used by your project (libfreetype-6, libpng16-16, SDL2, SDL2_image, SDL2_mixer, and SDL2_ttf, ...) are 32-bit compiled. – rflobao Jul 06 '16 at 14:16
4

This is by no means completely reliable, but you can give it a try. It requires dumpbin.exe, which is included with Visual Studio.

First, get a list of dependent DLLs for your program, resolved against your path:

del dlls.txt
for /f %d in ('dumpbin /dependents Questless.exe ^| findstr /ic:".dll"') do @echo %~$PATH:d >> dlls.txt

Then get the bitness of each:

for /f "delims=" %d in (dlls.txt) do @echo %d & dumpbin /headers "%d" | findstr /c:"machine (x"

This will produce output like:

C:\Windows\System32\kernel32.dll
            8664 machine (x64)
C:\programs\ed23\bin\hydra.dll
             14C machine (x86)

Note that this is incorrectly using the kernel32.dll from System32, rather than the WOW6432 one, so it shows that as x64. That's because it just used the path, when the Windows loader will actually use the WOW6432 mapper, SxS, the application manifest, and only fall back on the path if none of those resolve the dependency. It also doesn't find dependents of dependents (you could script recursing through the dependents, but be sure to filter out duplicates), and of course doesn't know anything about run-time explicit dynamic loads.

Nevertheless, it's a quick way to get a short list to check, and might identify your problem.

  • This is really useful! This technique shows that Windows is finding the 64-bit versions of msvcp140d.dll, vcruntime140d.dll, ucrtbased.dll, and kernel32.dll, in System32. Is there some Visual Studio project setting I can change to make Windows look in SysWoW64 for the 32-bit versions instead? – Jonathan Sharman Jul 09 '16 at 19:00
2

I feel profoundly dumb, but I finally figured out the real problem. I'm using the SDL font library SDL2_ttf, and I simply hadn't copied zlib.dll from the SDL2_ttf lib directory into my build directory. I don't understand why the error message was so cryptic; in the past missing DLLs have given me a helpful "foo.dll is missing" error message.

Anyway, thank you all for your help. At least I've learned a useful lesson: always make sure all the required DLLs are present before suspecting a more complex problem.

Jonathan Sharman
  • 636
  • 6
  • 16
  • 1
    This was my issue too! This had been bugging me for over a month. Apparently I had another copy of 64-bit zlib1.dll somewhere else on my PATH, so the 64-bit build of my project worked fine. – Bernard Jul 02 '18 at 06:31