Error when canonicalizing path on RAM drive

b21e6a3
Opened by swDM8 at 2023-08-23 00:57:41
R:\rust-test>rustc --version --verbose
warning: could not canonicalize path: 'R:\rust-test'
warning: could not canonicalize path: 'R:\rust-test'
warning: could not canonicalize path: 'R:\'
rustc 1.24.0 (4d90ac38c 2018-02-12)
binary: rustc
commit-hash: 4d90ac38c0b61bb69470b61ea2cccea0df48d9e5
commit-date: 2018-02-12
host: x86_64-pc-windows-msvc
release: 1.24.0
LLVM version: 4.0

I created a new project using 'cargo new rust-test --bin' Imported project to Intellij and clicked run. (without Intellij fails as well, just less text)

Console:

C:/Users/<username>/.cargo/bin/cargo.exe run --package rust-test --bin rust-test
warning: could not canonicalize path: 'R:\rust-test'
warning: could not canonicalize path: 'R:\rust-test'
warning: could not canonicalize path: 'R:\'
   Compiling rust-test v0.1.0 (file:///R:/rust-test)
error: incremental compilation: error canonicalizing path `R:\rust-test\target\debug\incremental\rust_test-1apbc64jn2fjp`: Niepoprawna funkcja. (os error 1)

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.24.0 (4d90ac38c 2018-02-12) running on x86_64-pc-windows-msvc

note: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'src\librustc\session\mod.rs:665: Trying to get session directory from IncrCompSession `NotInitialized`', src\librustc\session\mod.rs:1141:26
stack backtrace:
   0: <std::sync::condvar::WaitTimeoutResult as core::fmt::Debug>::fmt
   1: <std::time::SystemTimeError as core::fmt::Display>::fmt
   2: std::panicking::Location::column
   3: std::panicking::Location::column
   4: std::panicking::rust_panic_with_hook
   5: <alloc::vec::Vec<(alloc::string::String, u64)> as rustc::session::config::dep_tracking::DepTrackingHash>::hash
   6: rustc::ty::context::tls::span_debug
   7: rustc::session::bug_fmt
   8: rustc::session::bug_fmt
   9: rustc::session::Session::incr_comp_session_dir
  10: rustc_incremental::persist::load::load_dep_graph
  11: rustc_driver::driver::compile_input
  12: rustc_driver::run_compiler
  13: rustc_driver::profile::dump
  14: _rust_maybe_catch_panic
  15: <rustc_driver::pretty::UserIdentifiedItem as core::fmt::Debug>::fmt
  16: <std::sync::condvar::Condvar as core::default::Default>::default
  17: std::sys::windows::thread::Thread::new
  18: BaseThreadInitThunk

error: Could not compile `rust-test`.

To learn more, run the command again with --verbose.

Process finished with exit code 101

'Niepoprawna funkcja.' means 'invalid function'

R is an in-memory drive created using ImDisk program. cargo new ... cargo run works fine on external ssd drive. So in-memory drive is probably the cause. Reporting because console output says you will appreciate it.

  1. I wonder whether we actually need canonicalization here. It's very likely that normalization would be enough and not cause this issue by virtue of not hitting the filesystem.

    Peter Atashian at 2018-02-16 04:10:08

  2. cc @rust-lang/compiler Is there any reason we need to do canonicalization, specifically the symbolic link resolution aspect? Turning relative paths into absolute paths can be done without canonicalization so if we don't actually need canonicalization...

    Peter Atashian at 2018-02-20 20:40:06

  3. IIRC, canonicalization was the most robust way of getting Windows to transform paths into the \\?\ form. There might have been other reasons. It has not caused a problem so far but if it does not support in-memory drives, we'll have to take another look.

    Michael Woerister at 2018-02-21 10:26:52

  4. I just got same error.

    r:\cargo new hello-world-cargo --bin
    

    and got this errors:

    warning: could not canonicalize path: 'r:\rust_test\hello-world-cargo'
    warning: could not canonicalize path: 'r:\rust_test\hello-world-cargo'
    warning: could not canonicalize path: 'r:\rust_test'
    warning: could not canonicalize path: 'r:\'
       Compiling hello-world-cargo v0.1.0 (R:\rust_test\hello-world-cargo)
    error: incremental compilation: error canonicalizing path `r:\rust_test\hello-world-cargo\target\debug\incremental\hello_world_cargo-35pjmbew4invf`: Incorrect function. (os error 1)
    
    thread 'rustc' panicked at 'trying to get session directory from `IncrCompSession`: NotInitialized', src\librustc_session\session.rs:736:52
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
    
    error: internal compiler error: unexpected panic
    
    note: the compiler unexpectedly panicked. this is a bug.
    
    note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
    
    note: rustc 1.41.0 (5e1a79984 2020-01-27) running on i686-pc-windows-msvc
    
    note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin
    
    note: some of the compiler flags provided by cargo are hidden
    
    error: aborting due to previous error
    
    error: could not compile `hello-world-cargo`.
    
    To learn more, run the command again with --verbose.
    

    Also, R is an in-memory drive created using ImDisk program. Copying solution to regular C:\ and build works. Also, cargo on subst drives also works without issues.

    Dražen Šoronda at 2020-02-09 12:15:28

  5. I saw this issue linked from #79449

    The issue is basically that GetFinalPathNameByHandleW fails if the drive was not mounted using the Windows Mount Manager. Some mounting tools will use it, while others will not. (Notably, Dokan has a flag that specifies if we're using the mounting manger or not.)

    But you can use QueryDosDeviceW to get the NT path given a drive letter.

    The procedure basically becomes to first call GetFinalPathNameByHandleW and request a DOS path. If you get a dos path, great, you're done. Otherwise, you need to request an NT path. Then you call QueryDosDeviceW on each of the 26 drive letters, and match the path prefix. If you find a match, you've canonicalized the path for a drive letter which was not mounted using the Mount Manager.

    Dan Weiss at 2023-08-22 18:27:04

  6. But you can use QueryDosDeviceW to get the NT path given a drive letter.

    This can still fail if the drive was mounted to a directory and not a drive letter.

    Chris Denton at 2023-08-22 18:33:27

  7. Absolutely true too, if the path isn't mounted as a drive letter, it won't be found using QueryDosDeviceW. But chances are good that people will probably be using mounting tools with a drive letter. If they really need to mount in a subdirectory, they can use a different mounting program that makes use of the mount manager.

    Eventually you could just give up and return a path like \\?\GLOBALROOT\Device\HarddiskVolume4\Path\To\File. This kind of path will not work in the Windows Explorer shell or standard File dialogs. But it will work everywhere else. fopen will open it. Notepad will open that kind of path if you specify it from the command line. 7-Zip File Manager will even let you browse the directories and subdirectories of a path like that.

    But I'm sure nobody would ever expect a "Canonicalize" function to return a path beginning with \\?\GLOBALROOT\.

    Dan Weiss at 2023-08-22 23:30:22

  8. Eventually you could just give up and return a path like \\?\GLOBALROOT\Device\HarddiskVolume4\Path\To\File.

    Yes this has been considered before. It stalled on the "weirdness" factor though. If someone wants to push for again, I'd be minded to support them.

    I would ask though, why Dokan defaults to not integrating with the mount manager? Should that not be the default? Tbh, I'm confused why that's even an option.

    Chris Denton at 2023-08-22 23:53:46

  9. Using the mount manager causes Windows to immediately generate a Recycle Bin and System Volume Information folder.

    Dan Weiss at 2023-08-23 00:57:41