Menu

#3714 SDCC 4.4.0 on Windows: Sdar tool crashes because of missing DLLs

open
nobody
None
other
7
2026-02-27
2024-03-02
No

SDCC 4.4.0 don't works on Windows. Sdar tool just crashes !!
It appears you forgot to include two libraries that need to be in the same folder:
-zlib1.dll
-libgcc_s_dw2-1.dll

Related

Bugs: #3752
Bugs: #3796
Wiki: SDCC 4.5.0 Release
Wiki: SDCC 4.6.0 Release

Discussion

  • Benedikt Freisen

    • summary: SDCC 4.4.0 don't works on Windows. Sdar tool just crashes !! --> SDCC 4.4.0 on Windows: Sdar tool crashes because of missing DLLs
    • Priority: 1 --> 7
     
  • Benedikt Freisen

    This appears to be the same problem as recently described in Discussion/Help and [bugs:#3686] might also be related.
    Thanks for figuring out why it crashes. Adding files to a setup script should be doable even without access to a Windows machine.

    P.S.: I have adjusted the priority to match that of [bugs:#3686]. Priority 1 would be the lowest.

     

    Related

    Bugs: #3686

  • Philipp Klaus Krause

     
  • Philipp Klaus Krause

    Thanks for looking into this.
    Unfortunately, there is now good solution dor missing DLLs that we can implement.

    • There are tools, such as ntldd to find out which DLLs an executable depends on. It will sometimes also output their paths, if they happen to be installed in wine. Better than nothing, but not good enough.¹
    • When we build software with mingw, there will be the required DLLs somewhere on the host that was used to build it.
    • Some people have come up with programs to find those DLLs, but they don't work for all corner cases. Sometimes they might not find the DLL. Wprse, sometimes they might find a different DLL of the same name, but with different semantics, or different dependencies.
    • The mingw used to do the cross-build should know where the DLLs are, but there is apparently no way to get that information from mingw.

    ¹ Example output with wine installed:

    sdcc-builder@notebook6:~$ ntldd "./.wine/drive_c/Program Files/SDCC/bin/sdar.exe"
    0094:err:winediag:nodrv_CreateWindow Application tried to create a window, but no driver could be loaded.
    0094:err:winediag:nodrv_CreateWindow L"The explorer process failed to start."
    0094:err:systray:initialize_systray Could not create tray window
            KERNEL32.dll => not found
            msvcrt.dll => not found
            USER32.dll => not found
            zlib1.dll => not found
    

    So we see that this executable depends on 4 DLLs that are not found by ntldd. For the first three that is because they are part of Windows/wine, for the last one it is because it is really missing. Let's go on:

    root@notebook6:~# find /home/sdcc-builder -name zlib1.dll
    /home/sdcc-builder/.wine/drive_c/windows/system32/zlib1.dll
    /home/sdcc-builder/.wine/drive_c/windows/syswow64/zlib1.dll
    root@notebook6:~# find /usr -name zlib1.dll
    /usr/lib/x86_64-linux-gnu/wine/zlib1.dll
    /usr/lib/x86_64-linux-gnu/wine/i386-windows/zlib1.dll
    /usr/lib/x86_64-linux-gnu/wine/x86_64-windows/zlib1.dll
    /usr/lib/i386-linux-gnu/wine/zlib1.dll
    /usr/lib/i386-linux-gnu/wine/i386-windows/zlib1.dll
    /usr/lib/i386-linux-gnu/wine/x86_64-windows/zlib1.dll
    /usr/i686-w64-mingw32/lib/zlib1.dll
    /usr/x86_64-w64-mingw32/lib/zlib1.dll
    

    So, we need one of these. Don't really know which one (AFAIR this sdar.exe was built using the nativecrosstools branch, so I guess the first two are out).

    Anyway, on to libgcc_s_dw2-1.dll.

    root@notebook6:~# find /usr -name libgcc_s_dw2-1.dll 
    /usr/lib/gcc/i686-w64-mingw32/13-win32/libgcc_s_dw2-1.dll
    /usr/lib/gcc/i686-w64-mingw32/13-posix/libgcc_s_dw2-1.dll
    

    So, here we have only one target variant (i686-w64-mingw32). But this time there are different threading semantics (which AFAIK need to match among DLLs, so which one to choose here depends what which options were used to compile the other DLLs we depend on).

    I just don't see an easy way to find the DLLs we need to include in the installer. I want to write a compiler, not write a DLL finding tool. And I'm not a Windows expert. Maybe we need to drop Windows as a supported release platform until a Windows expert happens to join the SDCC team.

    P.S.: One option could be to figure this out manually, and hardcode the paths in our installer-creations scrips, which AFAIK was done before. That solution breaks when a part of the cross-build toolchain gets updated, which I think is what happened here, resulting in this bug report.

    P.P.S: The copydeps tool (https://github.com/suve/copydeps - AFAIK not included in GNU/Linux distributions) apparently knows which DLLs do come with Windows, but isn't perfect either:

    sdcc-builder@notebook6:~$ /tmp/copydeps/build/copydeps --dry-run "./.wine/drive_c/Program Files/SDCC/bin/sdar.exe"
    "KERNEL32.dll": (ignored)
    "USER32.dll": (ignored)
    "msvcrt.dll": (ignored)
    "zlib1.dll": (failed to resolve)
    
     
    😕
    1

    Last edit: Philipp Klaus Krause 2024-03-12
    • Janko Stamenović

      If there's somewhere a recipe one can follow to start with an "empty" OS, whichever is used for that build, and then if one follow the recipe exactly, until the resulting binary is created, then I could try to both diagnose and find something that would "work" as at least as long as the platform doesn't change. If I remember correctly, it could be even a good way to stop using dw2 convention which was almost accidentally accepted in these older platforms:

      https://sourceforge.net/p/mingw-w64/wiki2/Exception%20Handling/

      It was selected long long ago by somebody "because faster" but it was a wrong decision in practice because it's impossible to make sure that every DLL ever loaded by the program will follow that "unnatural" (from the perspective of all other DLLs) convention, so it's good that mingw64, which should be used for 32-bit builds because older mingw is now for decades stale and surely slower for 32-bits too, doesn't support DW2:

      "In win32 mode, the exception unwind handler cannot propagate through non-dw2 aware code, this means that any exception going through any non-dw2 aware "foreign frames" code will fail, including Windows system DLLs and DLLs built with Visual Studio."

       
      • Philipp Klaus Krause

        The snapshots that we use for releases are built this way: https://sourceforge.net/p/sdcc/wiki/HOWTO%20Make%20Snapshot%20Builds%20on%20the%20Developer%20Machine/

        Get the native snapshots to build first, then add the cross-build to the build configuration (libraries for both are built using the native build).

         
        • Janko Stamenović

          I don't see there any info about the versions involved, including which versions of needed dependencies produced correct binary releases before, and which new versions of the dependencies currently used introduced the problem discussed. All the configuration decisions in all steps of the process are needed to be able to reproduce the same result and to diagnose where and when what exactly fails, compared to the some previous also fully known state. Without all that, there could be only some less precise suggestions like in that my parallel, more recent answer here.

           
    • Janko Stamenović

      Re: "So, we need one of these. Don't really know which one"

      Unfortunately it depends on what is configured on the machine which cross-compiled the binaries.

      If you're actually using i686-w64-mingw32-gcc compiler to build 32-bit Windows binaries on Linux, try from the command line:

      update-alternatives --display i686-w64-mingw32-gcc

      to see which one is default. I think it depends even on the order in which the alternatives were installed on the machine.

      Moreover, some script can directly invoke i686-w64-mingw32-gcc-win32 or i686-w64-mingw32-gcc-posix and you'd eventually need only the matching libgcc_s_dw2-1.dll

      (Yes, dw2, I see that's default on the Ubuntu on which I've installed these cross compiling tools (I was clearly not up-to-date) -- it seems that for another convention one would have to get the cross compiler tools differently than from default apt repos, maybe even building yourself, but you surely don't want it, as it seems not too much binaries depend on these, and your sources seem to not depend on exceptions).

      These libgcc_s_dw2-1.dlls exist in both posix and win32 subdirs, and you need the one matching the compiler with which the binaries needing them are produced (and built with the same compiler version, of course).

      If the libgcc_s_dw2-1.dll is for posix then you'd also need

      libwinpthread-1.dll

      In short, when building for Windows 32-bit using gcc cross compilers on Linux, and the same when compiling native using gcc, one has many possible combinations:

      "mingw32" vs "w64-mingw32" -- generations of tools
      "dw2" vs "sjlj" -- exception generation and handling conventions
      "posix" vs "win32" -- threading models

      According to what you showed in your message, if that matches the building machine, it's only about the threading model, probably.

      Anyway if you have built 32-bit Windows version using i686-w64-mingw32 then you'd need this one dll for zlib:

      /usr/i686-w64-mingw32/lib/zlib1.dll

      All zlib1.dlls in the paths containing wine or linux are surely not what you'd want.

      Once you have the binaries, an ultimate "truth" if they could run correctly is installing the binaries in the windows virtual machine which doesn't contain any of the these libraries reachable through PATH or from windows directory, to avoid chance that some other is loaded.

      There are also ways to force an executable or a dll to not use any dlls reachable from somewhere else, but only from the specifically declared directory, but that's an additional story.

      But as an alternative approach to have the sdar on 4.4.0 seemingly working:

      I can report that I was able to install 32-bit 4.4.0 #14620 (MINGW32) observe sdar failing to start, but then download PortableGit-2.44.0-32-bit.7z.exe and unpack from it only:

       libwinpthread-1.dll
       libgcc_s_dw2-1.dll
       zlib1.dll
      

      From the \mingw32\bin of it, then put these three in the sdcc bin directory where sdar.exe is, and then sdar showed help etc.

      GNU ar (sdbinutils derived from GNU Binutils) 2.38

       
      • Janko Stamenović

        Here an example of building on Ubuntu 22.04.4 LTS, starting on the machine without any mingw and without Wine, and then what can be easily obvious regarding the problems described in https://sourceforge.net/p/sdcc/bugs/3714/#e483 ( 2024-03-12 )

        Installed only posixversion of w64 g++, which installs the dependencies: matching gcc etc:

        sudo apt install g++-mingw-w64-x86-64-posix
        

        With this kind of installation (being precise with that -posixsuffix) there are no alternatives so it will be easier to see what the matching dlls are.

        Then installed libz-mingw-w64-dev

        sudo apt install libz-mingw-w64-dev
        

        So, the correct dlls to take for a distribution are:

        /usr/lib/gcc/x86_64-w64-mingw32/10-posix/libstdc++-6.dll
        /usr/lib/gcc/x86_64-w64-mingw32/10-posix/libgcc_s_seh-1.dll
        /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll
        /usr/x86_64-w64-mingw32/lib/zlib1.dll
        

        Matching my previous explanation, libstdc++-6.dll and libgcc_s_seh-1.dll are in posixsubdir of the /usr/lib/gcc/x86_64-w64-mingw32/ path. These two must match the kind of threading used during the compilation.

        The two other dlls aren't dependent on that and are in the different path.

        So in the case of described problems with:

        root@notebook6:~# find /home/sdcc-builder -name zlib1.dll
        /home/sdcc-builder/.wine/drive_c/windows/system32/zlib1.dll
        /home/sdcc-builder/.wine/drive_c/windows/syswow64/zlib1.dll
        root@notebook6:~# find /usr -name zlib1.dll
        /usr/lib/x86_64-linux-gnu/wine/zlib1.dll
        /usr/lib/x86_64-linux-gnu/wine/i386-windows/zlib1.dll
        /usr/lib/x86_64-linux-gnu/wine/x86_64-windows/zlib1.dll
        /usr/lib/i386-linux-gnu/wine/zlib1.dll
        /usr/lib/i386-linux-gnu/wine/i386-windows/zlib1.dll
        /usr/lib/i386-linux-gnu/wine/x86_64-windows/zlib1.dll
        /usr/i686-w64-mingw32/lib/zlib1.dll
        /usr/x86_64-w64-mingw32/lib/zlib1.dll
        

        It's clear: all the paths with "wine" could be ignored. That leaves to decide between

        /usr/i686-w64-mingw32/lib/zlib1.dll
        /usr/x86_64-w64-mingw32/lib/zlib1.dll
        

        and it's obvious which one is for 32-bit: the first, containing i686: Both names contain "w64-mingw32" but it's important to know that that part should be ignored when deciding 32-bit or 64-bit (it's "just" the name of the kit, and w64 means "the second version", the first version was just called "mingw32", and the newer (since more than a decade) was then named "w64 -mingw32" apparently to be compatible with some older scripts, anyway that newer kit, the only one which is reasonable to use today, allows both 32-bit and 64-bit targets and that's what we should now select: ), so one just decides between i686 and x86_64 in these names: 32-bit build: the name with i686.

        OK. Now regarding this:

        root@notebook6:~# find /usr -name libgcc_s_dw2-1.dll 
        /usr/lib/gcc/i686-w64-mingw32/13-win32/libgcc_s_dw2-1.dll
        /usr/lib/gcc/i686-w64-mingw32/13-posix/libgcc_s_dw2-1.dll
        

        To make a correct decision for that one, one has to know which compiler was actually used during the build process of the binaries, which is what I've already mentioned before: if one has cross compilers with both (win32 and posix) threading targets installed, only the DLLs matching the compiler actually used to compile the binaries should be distributed. I was sure that I installed only one, and then also before the configure step set:

        export HOST=x86_64-w64-mingw32
        export CXX=x86_64-w64-mingw32-g++-posix
        export CC=x86_64-w64-mingw32-gcc-posix
        

        Which was an explicit selection of "posix threading" and not "win32 threading" alternative. In your case, even if you always wrote just i686-w64-mingw32 you should be able to do the following:

        update-alternatives --display i686-w64-mingw32-gcc
        

        to discover which one of the two is actually "active". BTW That mechanism works by maintaining the symbolic links, then using i686-w64-mingw32-gcc will be redirected either to i686-w64-mingw32-gcc-posix or to i686-w64-mingw32-win32 . And again, the "w64-mingw32" part should be ignored, the i686 means 32-bit, and the suffix -posix or -win32says correspond to the threading model built in in the cross compiler used during the compilation of the sources, and the dynamic libraries which are by design dependent on that just have to match that.

         
  • Ragozini Arturo

    Ragozini Arturo - 2024-03-13

    Sorry to hear this, sadly I'm not able to contribute... I do not know windows that well

     
  • Philipp Klaus Krause

    For reference, if anyone wants to look into this: I think the missing DLLs needs to be added in at least these two places:

    sdcc-build/lib/bootstrap.mk (to make it into the release .zip archive)
    sdcc/support/scripts/sdcc.nsi (to make it into the release installer)

    P.S.: Also, when building stuff the "normal" (i.e not using the nativecrosstools branch) way, DLLs might come from the packages installed via sdcc-cf/packages. Don't know which one that zlib DLL might come from.

     
    👍
    1

    Last edit: Philipp Klaus Krause 2024-09-19
    • Janko Stamenović

      Now trying to understand and reading https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc-cf/packages/build.mingw-w64/Makefile#l5

      MINGW_W64_VERSION=1.0
      MINGW_W64_BUILD_DATE=20120227
      BINUTILS_VERSION=2.28
      GCC_VERSION=4.9.4
      

      If these files reflect the actual state, does that mean that the "cf" (compile farm?) configuration uses 12 years old versions? Or is the script only for some initialization which is later updated?

       
      • Philipp Klaus Krause

        I'm not sure, I don't run the machines that do the windows builds, @epetrich does, but according to https://sourceforge.net/p/sdcc/wiki/Snapshot%20Builds/ they use something newer: GCC 10.3.0 for the 64-bit Windows build, GCC 6.3.0 for the 32-bit Windows build.
        For the nativecrosstools branch, I used GCC 13 locally.

         

        Last edit: Philipp Klaus Krause 2024-11-07
  • Philipp Klaus Krause

    The problem is still present in current snapshots 32-bit installers.

     
  • Philipp Klaus Krause

     
  • Philipp Klaus Krause

    In [r15083], this should be fixed in the nativecrosstools branch. Not sure how to port the fix to trunk yet.

     

    Related

    Commit: [r15083]

    • Janko Stamenović

      What is the purpose of the nativecrosstools branch? I've tried to find that in some description, but I wasn't able.

       
      • Philipp Klaus Krause

        I think normally (i.e. what is in trunk), to build SDCC snapshots, one will want to use known-good versions of tools. So the infrastructure in sdcc-cf provides for that. The stuff in sdcc-cf/packages should be such known-good versions; it is partly optional (i.e. only needed if the host doesn't provide anything), but for the cross-build of snapshots it seems that is the only easy way.
        But I wanted to try to just build snapshots with whatever cross tools happen to be installed on the host system, using nothing or very little of the sdcc-cf/packages stuff. So I created the nativecrosstools branch to do so.

        P.S.: Some time, I experimented with fixes for Windows-specific issues in the nativecrosstools branch, and once they looked good enough, ported them to trunk.

        Currently, there are only very few differences between trunk and the nativecrosstools branch:

        • sdcc/support/scripts/sdcc.nsi: nativecrosstools branch includes zlib1.dll, trunk doesn't.
        • sdcc-build/lib/fetch.mk, sdcc-build-bootstrap.sh: nativecrosstools branch fetches stuff from nativecrosstools branch instead of trunk.
        • lib/bootstrap.mk: DLLs are taken from cross-tools on host instead of locally (via sdcc-cf/packages) installed ones (except for readline5.dll, which isn't part of cross-tools on Debian host).
         

        Last edit: Philipp Klaus Krause 2024-11-08
  • Philipp Klaus Krause

    Looks like current wine has a dependency on zlib (libz-mingw-w64 on Debian), which comes with a zlib1.dll, so sdar.exe will always just work under wine, despite the SDCC installer not including zlib1.dll.

     
  • Janko Stamenović

    The procedure described in [r16282] allows cross building "no DLLs needed" Windows 32-bit executables on a newer version of the OS with the newer version of the tools. The example worked on ubuntu-24.04

     

    Related

    Commit: [r16282]


Log in to post a comment.

MongoDB Logo MongoDB