Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolving mimalloc-redirect.dll seems to be initialized after ucrtbase.dll #668

Open
jeremyong opened this issue Dec 15, 2022 · 8 comments

Comments

@jeremyong
Copy link

At application start, I am seeing the following output:

mimalloc-redirect: error: mimalloc-redirect.dll seems to be initialized after ucrtbase.dll   
  (hint: try to link with 'mimalloc-override.lib' earlier on the command line?)
mimalloc-redirect: error: mimalloc-redirect.dll seems to be initialized after ucrtbased.dll  
  (hint: try to link with 'mimalloc-override.lib' earlier on the command line?)
mimalloc-redirect: warning: standard malloc is _not_ redirected! -- using regular malloc/free

The executable spawning these messages is linking mimalloc.lib (this is the mimalloc.dll import lib) as well as mimalloc-redirect.lib (the import lib for mimalloc-redirect.dll). Both of the DLLs are in the executable directory (of course, or nothing would run at all). Care was taken to ensure these libs appear first in the linker input list.

I have even tried declaring a static variable like so:

static int mv = mi_version();

in an attempt to force the mimalloc DLLs to load early, albeit to no avail. Running the exe under WinDbg, I'm finding the ModLoad of mimalloc.dll and the associated mimalloc-redirect.dll far too late, after other DLLs and ucrtbased.dll is loaded. After playing around with this a bit, I'm convinced that changing the ordering of the linker inputs appears to do little to influence the actual DLL loading order (latest MSVC at the time of this writing, Windows 10).

I did confirm that allocations are properly being redirected to mimalloc's allocation and deallocation routines however, immediately after entry into main (mimalloc's DllMain runs first, resulting in the messages above).

Do you have any suggestions on how to properly use the redirect DLL? Thanks!

@daanx
Copy link
Collaborator

daanx commented Dec 20, 2022

The easiest way is to use the minject program in the bin directory. Run minject -h to see how to use it. It will output a rewritten exe that ensures the mimalloc-redirect dll comes first in the import table. For example:

> minject --list myprogram.exe

lists the current import table, and

> minject --force --inplace myprogram.exe

rewrites myprogram.exe in place to have mimalloc-redirect first in the import table.
Let me know if this works for you.

@jeremyong
Copy link
Author

Thanks @daanx that did seem to do the trick and I see that mimalloc-redirect is being loaded much earlier now (just after the necessities: ntdll.dll, KERNEL32.DLL, KERNELBASE.dll, and SHELL32.dll). Do you know if there's a way to get the MSVC linker to inject a dll directly into the import table, so we don't need to do this post-build step?

@daanx
Copy link
Collaborator

daanx commented Dec 23, 2022

ah great to hear it works for you. I do not know of a reliable way to do this at link time :-( but it does help if the mimalloc-redirect.lib is the first one on the linker command line; try to see if that is actually the case as often other "default" libs are put before it by msvc

@thehans
Copy link
Contributor

thehans commented Dec 24, 2022

This is the same thing I was seeing in my issue #542. Although, it was mixed in with a number of other issues I was dealing with at the time. I think the other ones basically got sorted out, but I never found any workaround for having to run minject.

I also find it slightly disturbing that a bin directory exist at all in the github repo. Is there a reason they cannot be built from source like the rest of the nominally "open source" project? Then maybe a version of minject could be built that would run natively on our cross-compiling Linux based build servers.

@jeremyong
Copy link
Author

I ended up taking an evening to quickly whip up this tool which does a quick-and-dirty import data directory reordering in-place in a PE file. For getting things to work with mimalloc, I found you only need to reorder the mimalloc-debug.dll or mimalloc.dll entry, since the redirect loads as a secondary dependency in time. This avoids the headache of needing to futz with fixing up raw file offsets for trailing sections in the PE. It's very alpha but I'm using it in my own projects without any issues for now.

@machish
Copy link

machish commented Dec 14, 2023

I found that the message was accurate, but I did need it to be the very first item in AdditionalDependencies. And because Microsoft.Cpp.targets touches AdditionalDependencies, I had to make the .vcxproj change in a different place in the file.

  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <!-- Force mimalloc to be the first library. It needs to come first so that mimalloc-redirect.dll can do its magic.
       This also needs to be done after Microsoft.Cpp.targets, since %(AdditionalDependencies) gets modified more than once. -->
  <ItemDefinitionGroup>
    <Link>
      <AdditionalDependencies>
        $(MiMallocLib);
        %(AdditionalDependencies)</AdditionalDependencies>
   </Link>
  </ItemDefinitionGroup>

(And $(MiMallocLib) is something I defined so that I could use the debug version in debug builds.)

@tlanyan
Copy link

tlanyan commented Feb 26, 2024

@daanx Hello, I tried minject.exe, but it didn't work when executed in cmd and PowerShell.

I linked my exe with mimalloc-override.dll, it worked as expected in VS and git bash. But when i executed the program in cmd and PowerShell, i got the error "mimalloc-redirect.dll seems to be initialized after ucrtbase.dll"

I tried to use minject.exe and it showed mimalloc-redirect.dll is definitely in first place:

0: mimalloc-redirect.dll
1: mimalloc-override.dll
xxxx

But the modifed exe still got the same error when executed in cmd and PowerShell.

So what happened in cmd or PowerShell? And any idea to resolve this error?

@tlanyan
Copy link

tlanyan commented Feb 26, 2024

If I use the Developer PowerShell in Visual Studio(in "Tools" -> "Command Line"), it works, but it don't in Developer Command Prompt and normal PowerShell. The more interesting thing is, if i open a terminal in VS(in "View" -> "Terminal"), both the Developer Command Prompt and Developer PowerShell terminal work.

IMO, some environment variables or options had an effect on how the ucrtbase.dll loads, but I don't know which they are and how to set them correctly.

Can anyone tell what's the difference between a normal PowerShell and a VS Developer PowerShell?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants