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

Dotnet apps fail to start when run in a directory containing a backslash #75387

Closed
Penguinwizzard opened this issue Sep 10, 2022 · 10 comments
Closed
Milestone

Comments

@Penguinwizzard
Copy link

Description

If a dotnet self-contained app starts up from a path where a component contains a backslash (e.g. /home/cooluser/fancy\folder/app_binary, where one of the folders in the path is named fancy\folder, with a backslash in the folder name), the runtime startup will fail, and the cryptic error message Failed to create CoreCLR, HRESULT: 0x80004005 will be displayed.

Reproduction Steps

mkdir test_console_app
cd test_console_app
dotnet new console
dotnet publish --self-contained -p:PublishSingleFile=true test_console_app.csproj --runtime linux-x64 --self-contained true --configuration Release --framework net6.0
mkdir s\\test
cp bin/Release/net6.0/linux-x64/publish/test_console_app s\\test/
s\\test/test_console_app

Expected behavior

The app should run. Failing that, an error message that provides relevant information should be displayed.

Actual behavior

The app crashes with the message

Failed to create CoreCLR, HRESULT: 0x80004005

Regression?

Unknown.

Known Workarounds

Run from only paths without backslashes in folder names.

Configuration

  • Reproduced in dotnet 6.0.400
  • Any OS supporting backslashes in folder names (reproduced on multiple Linux distros and OSX)
  • Any architecture tested
  • Most likely specific to self-contained apps
  • Before any user code (Blazor/non-Blazor irrelevant)

Other information

If you run the app with COREHOST_TRACE=3, you still don't get anything terribly useful; it continues exactly as per normal until it prints Failed to create CoreCLR, HRESULT: 0x80004005 to the log and immediately exits.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Sep 10, 2022
@ghost
Copy link

ghost commented Sep 10, 2022

Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

If a dotnet self-contained app starts up from a path where a component contains a backslash (e.g. /home/cooluser/fancy\folder/app_binary, where one of the folders in the path is named fancy\folder, with a backslash in the folder name), the runtime startup will fail, and the cryptic error message Failed to create CoreCLR, HRESULT: 0x80004005 will be displayed.

Reproduction Steps

mkdir test_console_app
cd test_console_app
dotnet new console
dotnet publish --self-contained -p:PublishSingleFile=true test_console_app.csproj --runtime linux-x64 --self-contained true --configuration Release --framework net6.0
mkdir s\\test
cp bin/Release/net6.0/linux-x64/publish/test_console_app s\\test/
s\\test/test_console_app

Expected behavior

The app should run. Failing that, an error message that provides relevant information should be displayed.

Actual behavior

The app crashes with the message

Failed to create CoreCLR, HRESULT: 0x80004005

Regression?

Unknown.

Known Workarounds

Run from only paths without backslashes in folder names.

Configuration

  • Reproduced in dotnet 6.0.400
  • Any OS supporting backslashes in folder names (reproduced on multiple Linux distros and OSX)
  • Any architecture tested
  • Most likely specific to self-contained apps
  • Before any user code (Blazor/non-Blazor irrelevant)

Other information

If you run the app with COREHOST_TRACE=3, you still don't get anything terribly useful; it continues exactly as per normal until it prints Failed to create CoreCLR, HRESULT: 0x80004005 to the log and immediately exits.

Author: Penguinwizzard
Assignees: -
Labels:

area-Host, untriaged

Milestone: -

@vitek-karas
Copy link
Member

#75097 should be able to tell us more.
@janvorli maybe you can try the repro of this as a test for your change?

@janvorli
Copy link
Member

I have debugged it too. With my change #75097, which besides adding logging for E_FAIL also stopped reporting all failures in the EE initialization that resulted in an exception as E_FAIL we now get 0x80070002 instead, which is "not found" error. I've stepped through the code and the culprit is in FILEDosToUnixPathA called from CreateFileW, see the call stack below.
The problem is that this method converts all backslashes in filenames to forward ones. Which for any valid path containing backslash on Unix is obviously wrong.

* thread #1, name = 'test_console_ap', stop reason = step over
  * frame #0: 0x00007ffff77bf4aa libcoreclr.so`::FILEDosToUnixPathA(lpPath="/home/janvorli/test/test_console_app/s\\test/System.Private.CoreLib.dll") at path.cpp:465:14
    frame #1: 0x00007ffff77c0a73 libcoreclr.so`FILEDosToUnixPathA(lpPath=0x00007fffffffc398) at path.cpp:481:5
    frame #2: 0x00007ffff77ae3ac libcoreclr.so`CorUnix::InternalCreateFile(pThread=0x0000555555591780, lpFileName="/home/janvorli/test/test_console_app/s\\test/System.Private.CoreLib.dll", dwDesiredAccess=2147483648, dwShareMode=5, lpSecurityAttributes=0x0000000000000000, dwCreationDisposition=3, dwFlagsAndAttributes=128, hTemplateFile=0x0000000000000000, phFile=0x00007fffffffc508) at file.cpp:464:5
    frame #3: 0x00007ffff77afbfb libcoreclr.so`::CreateFileW(lpFileName=u"/home/janvorli/test/test_console_app/s\\test/System.Private.CoreLib.dll", dwDesiredAccess=2147483648, dwShareMode=5, lpSecurityAttributes=0x0000000000000000, dwCreationDisposition=3, dwFlagsAndAttributes=128, hTemplateFile=0x0000000000000000) at file.cpp:883:16
    frame #4: 0x00007ffff754d8df libcoreclr.so`CreateFileWrapper(lpFileName=u"/home/janvorli/test/test_console_app/s\\test/System.Private.CoreLib.dll", dwDesiredAccess=2147483648, dwShareMode=5, lpSecurityAttributes=0x0000000000000000, dwCreationDisposition=3, dwFlagsAndAttributes=128, hTemplateFile=0x0000000000000000) at longfilepathwrappers.cpp:111:19
    frame #5: 0x00007ffff70aa747 libcoreclr.so`PEImage::TryOpenFile(this=0x00005555555ab310, takeLock=false) at peimage.cpp:902:13
    frame #6: 0x00007ffff71c0b4d libcoreclr.so`::BinderAcquirePEImage(wszAssemblyPath=u"/home/janvorli/test/test_console_app/s\\test/System.Private.CoreLib.dll", ppPEImage=0x00007fffffffca70, bundleFileLocation=(Size = 0, Offset = 0, UncompresedSize = 0)) at coreassemblyspec.cpp:108:20
    frame #7: 0x00007ffff75d44b9 libcoreclr.so`BINDER_SPACE::AssemblyBinderCommon::GetAssembly(assemblyPath=0x00007fffffffd118, fIsInTPA=YES, ppAssembly=0x00007fffffffcc08, bundleFileLocation=(Size = 0, Offset = 0, UncompresedSize = 0)) at assemblybindercommon.cpp:1016:18
    frame #8: 0x00007ffff75d3d30 libcoreclr.so`BINDER_SPACE::AssemblyBinderCommon::BindToSystem(systemDirectory=0x00007fffffffd710, ppSystemAssembly=0x00007fffffffd6a8) at assemblybindercommon.cpp:283:14
    frame #9: 0x00007ffff75e0332 libcoreclr.so`DefaultAssemblyBinder::BindToSystem(this=0x0000555555624770, ppSystemAssembly=0x00007fffffffd9b8) at defaultassemblybinder.cpp:199:14
    frame #10: 0x00007ffff70a6032 libcoreclr.so`PEAssembly::DoOpenSystem() at peassembly.cpp:838:53
    frame #11: 0x00007ffff70a5a22 libcoreclr.so`PEAssembly::OpenSystem() at peassembly.cpp:810:18
    frame #12: 0x00007ffff6ef0d86 libcoreclr.so`SystemDomain::LoadBaseSystemClasses(this=0x00007ffff791ed80) at appdomain.cpp:1265:27
    frame #13: 0x00007ffff6ef0c88 libcoreclr.so`SystemDomain::Init(this=0x00007ffff791ed80) at appdomain.cpp:1144:5
    frame #14: 0x00007ffff7777adc libcoreclr.so`EEStartupHelper() at ceemain.cpp:924:33
    frame #15: 0x00007ffff7778ec4 libcoreclr.so`EEStartup(this=0x00007fffffffdfe8, p=0x0000000000000000)::$_1::operator()(void*) const at ceemain.cpp:1071:9
    frame #16: 0x00007ffff77767fb libcoreclr.so`EEStartup() at ceemain.cpp:1073:5
    frame #17: 0x00007ffff77765f1 libcoreclr.so`EnsureEEStarted() at ceemain.cpp:308:17
    frame #18: 0x00007ffff6f94132 libcoreclr.so`CorHost2::Start(this=0x0000555555593dd0) at corhost.cpp:100:14
    frame #19: 0x00007ffff6eec2a8 libcoreclr.so`::coreclr_initialize(exePath="/home/janvorli/test/test_console_app/s\\test/test_console_app", appDomainFriendlyName="clrhost", propertyCount=9, propertyKeys=0x00005555555c1d40, propertyValues=0x00005555555c1e70, hostHandle=0x00007fffffffe338, domainId=0x00007fffffffe334) at exports.cpp:279:16
    frame #20: 0x00007ffff798b1ef libhostpolicy.so`___lldb_unnamed_symbol218 + 783
    frame #21: 0x00007ffff799ad21 libhostpolicy.so`___lldb_unnamed_symbol310 + 385
    frame #22: 0x00007ffff799a5da libhostpolicy.so`corehost_main + 154
    frame #23: 0x00007ffff79f3be4 libhostfxr.so`___lldb_unnamed_symbol239 + 1812
    frame #24: 0x00007ffff79f2309 libhostfxr.so`___lldb_unnamed_symbol237 + 665
    frame #25: 0x00007ffff79ed6db libhostfxr.so`hostfxr_main_startupinfo + 171
    frame #26: 0x000055555556c4b5 test_console_app`___lldb_unnamed_symbol638 + 1045
    frame #27: 0x000055555556c990 test_console_app`___lldb_unnamed_symbol639 + 144
    frame #28: 0x00007ffff7a61d90 libc.so.6`__libc_start_call_main(main=(test_console_app`___lldb_unnamed_symbol639), argc=1, argv=0x00007fffffffe908) at libc_start_call_main.h:58:16
    frame #29: 0x00007ffff7a61e40 libc.so.6`__libc_start_main_impl(main=(test_console_app`___lldb_unnamed_symbol639), argc=1, argv=0x00007fffffffe908, init=0x00007ffff7ffd040, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffe8f8) at libc-start.c:392:3
    frame #30: 0x0000555555560029 test_console_app`_start + 41

@janvorli
Copy link
Member

janvorli commented Sep 12, 2022

If I patched the string at the FILEDosToUnixPathA to not do to any transformation, then it progressed further and as a next failure, it failed to load the JIT.

./test_console_app
Fatal error. Failed to load JIT compiler

Edit: I have forgotten to mention that I was debugging the non-single file version as it behaved the same as the single file and it is simpler to debug.

@janvorli
Copy link
Member

My mistake, I have forgotten to copy over the jit I've built. So there were no further issues:

./test_console_app
Hello, World!

@janvorli
Copy link
Member

Now as for the FILEDosToUnixPathA behavior. The point for it was that the CreateFile and other PAL emulated APIs working with file paths, can be called with Windows style paths from user apps that were ported from Windows. But clearly, its behavior is too big hammer in the scenario from this issue. I wonder though how to fix it without making a breaking change.

@jkotas
Copy link
Member

jkotas commented Sep 12, 2022

We should make the breaking change.

99+% of the cases that take paths go through libraries shims that do not have this adjustment. It is just the few remaining cases that still go through the Win32 PAL have this odd behavior.

@Penguinwizzard Penguinwizzard changed the title Dotnet self-contained apps fail to start when run in a directory containing a backslash Dotnet apps fail to start when run in a directory containing a backslash Sep 12, 2022
@mangod9 mangod9 removed the untriaged New issue has not been triaged by the area owner label Sep 13, 2022
@mangod9 mangod9 added this to the 8.0.0 milestone Sep 13, 2022
@vitek-karas
Copy link
Member

There seems to be a similar problem with forward slash in the path (although I have no idea how that is supposed to work if forward slash is also a directory separator).

From: #75882

Description

If a path to a dotnet application contains slashes / in any of parent folder names, the app will just return a Failed to create CoreCLR, HRESULT: 0x80070057
If the path contains a backslash \ in any parent folder names, the app fails with a System.IO.FileNotFoundException pointing to the built dll file of the app.

Reproduction Steps

  • have a Mac (tested on macmini, 2018 and M1) with dotnet setup
  • create a new folder testfolder
  • in the folder, run dotnet new console and dotnet build
  • run the generated executable, something like ./bin/Debug/net6.0/testfolder
  • change parent folder name to test/folder
  • re-run the generated executable and observe CoreCLR error
  • change parent folder name to test\folder
  • re-run the generated executable and observe the FileNotCoundException
  • change the parent folder back to the initial
  • re-run the generated executable and things work again

Copy link
Contributor

Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

@jkotas
Copy link
Member

jkotas commented Jul 4, 2024

Fixed by #78995. The original repro steps (with backward slashes) work as expected.

@jkotas jkotas closed this as completed Jul 4, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Aug 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Archived in project
Development

No branches or pull requests

5 participants