The problems with apphelp.dll
Abstract
Several times I’ve seen cygwin/msys errors when their subsystem had failed to create child processes.
Example from cygwin’s ls
0 [main] us 0 init_cheap: VirtualAlloc pointer is null, Win32 error 487 AllocationBase 0x68520000, BaseAddress 0x68570000, RegionSize 0x218000, State 0x1000 C:\Program Files (x86)\Git\bin\ls.exe: *** Couldn't reserve space for cygwin's heap, Win32 error 487
Example from msys-git’s perl
C:\GIT\bin\perl.exe: *** unable to remap C:\GIT\bin\libsvn_wc-1-0.dll to same address as parent -- 0x2190000
1 [main] perl 8248 sync_with_child: child 5768(0xB60) died before initialization with status code 0x1
2 [main] perl 8248 sync_with_child: *** child state child loading dlls
C:\GIT\bin\perl.exe: *** unable to remap C:\GIT\lib\perl5\site_perl\5.8.8\msys\auto\SVN\_Delta\_Delta.dll to same address as parent -- 0x630000
3 [main] perl 8248 sync_with_child: child 6632(0xB90) died before initialization with status code 0x6802752F
3 [main] perl 8248 sync_with_child: *** child state child loading dlls
The problem
Digging the problem for some time I’ve found the reason of these errors on my PC (in perl’s case).
- Address, where perl wants to load its libraries was used by
C:\Windows\System32\uxtheme.dll
. - This
uxtheme.dll
was loaded as static linked library byC:\Windows\apppatch\AcGenral.dll
. - This
AcGenral.dll
was loaded (dynamically) byC:\Windows\System32\apphelp.dll
. - And this
apphelp.dll
was loaded in the parent process of theConEmu.exe
(that wasUSBSafelyRemove.exe
in my case). - Oops…
The check
The following examples shows msysgit x86
Almost all dll-s used by cygwin/msys must be loaded at high memory addresses (above 0x60000000).
For example, if you call
dumpbin /HEADERS C:\GIT\bin\libsvn_wc-1-0.dll
You will see
OPTIONAL HEADER VALUES
6F1C0000 image base (6F1C0000 to 6F2E7FFF)
So, you you see that one of the cygwin/msys libraries is loaded in low memory address (below 0x5FFF0000) you have a problem most probably… The easies way to check is using ProcessExplorer.
Press Ctrl+D
(Menu ->
View ->
Lower pane view ->
DLLs)
and look at ‘Base’ column in the lower pane.
If it is not visible just right-click on the DLLs list header,
choose ‘Select columns’ and turn on ‘Base address’ on the ‘DLL’ tab page.
And use ‘dumpbin’ to ensure that required ‘image base’ differs.
Scroll the DLLs list in the ProcessExplorer lower pane to find ‘Base+Size’ which covers desired address was shown by ‘dumpbin’. And who was loaded that dll? You may use DependencyWalker or ImpEx to check ‘Imports’ section of each dll loaded before. Yeah, that is not too simple but rather…
The solution
- You need to ‘rebase’ conflicting modules.
- Alternatively you need to run your shell in different way so process tree
will not include DLLs raised the conflict. In my case, when I run ConEmu from TaskBar icon,
there is no
apphelp.dll
in the result process tree (fromConEmu.exe
down toperl.exe
). But when I run ConEmu from ‘USB Safe Remove’ tool (automatically on connecting USB flash),apphelp.dll
appears in the process tree and perl is always failed…