The current order affects macFUSE 5.2.0+ which switched to ObjC MFMount.framework in libfuse. Using fork after touching some ObjC objects and then touching them again in the child after fork is not supported on macOS and triggers its own fork guard that terminates the sshfs process:
Thread 3 Crashed:
0 libsystem_kernel.dylib 0x180efeb10 __abort_with_payload + 8
1 libsystem_kernel.dylib 0x180f260e8 abort_with_payload_wrapper_internal + 104
2 libsystem_kernel.dylib 0x180f26080 abort_with_reason + 32
3 libobjc.A.dylib 0x180b105ec _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 128
4 libobjc.A.dylib 0x180b1056c _objc_fatal(char const*, ...) + 44
5 libobjc.A.dylib 0x180af4b10 performForkChildInitialize(objc_class*, objc_class*) + 396
6 libobjc.A.dylib 0x180ada7d0 initializeNonMetaClass + 620
7 libobjc.A.dylib 0x180af6258 initializeAndMaybeRelock(objc_class*, objc_object*, locker_mixin<lockdebug::lock_mixin<objc_lock_base_t>>&, bool) + 176
8 libobjc.A.dylib 0x180ad9f8c lookUpImpOrForward + 288
9 libobjc.A.dylib 0x180ad9b84 _objc_msgSend_uncached + 68
10 MFMount 0x1035d2f0c specialized static Bridge.log(level:function:_:) + 564
11 MFMount 0x1035dfa9c closure #1 in MFChannelCopyNextMessage(_:) + 232
12 MFMount 0x1035df984 MFChannelCopyNextMessage + 32
13 libfuse3.4.dylib 0x102718880 0x102700000 + 100480
14 libfuse3.4.dylib 0x1027140b4 0x102700000 + 82100
15 libsystem_pthread.dylib 0x180f35c58 _pthread_start + 136
16 libsystem_pthread.dylib 0x180f30c1c thread_start + 8
…
Thread 3 crashed with ARM Thread State (64-bit):
x0: 0x0000000000000008 x1: 0x0000000000000001 x2: 0x0000000000000000 x3: 0x0000000000000000
x4: 0x00000001039423b0 x5: 0x0000000000000080 x6: 0xffffffffbfc007ff x7: 0xfffff0003ffff800
x8: 0x0000000000000020 x9: 0x0000000000001c03 x10: 0x0000000103942130 x11: 0x0000000103942080
x12: 0x0000000000000004 x13: 0x0000000000001359 x14: 0x0000000004000000 x15: 0x000000000000002b
x16: 0x0000000000000209 x17: 0x00000001ee77b190 x18: 0x0000000000000000 x19: 0x0000000000000080
x20: 0x00000001039423b0 x21: 0x0000000000000000 x22: 0x0000000000000000 x23: 0x0000000000000001
x24: 0x0000000000000008 x25: 0x000000016de370e0 x26: 0x00000001ea670000 x27: 0x00000001ed13648c
x28: 0x000000016de370e0 fp: 0x000000016de36b10 lr: 0x0000000180f260e8
sp: 0x000000016de36ad0 pc: 0x0000000180efeb10 cpsr: 0x40001000
far: 0x0000000000000000 esr: 0x56000080 (Syscall)
Binary Images:
0x1021f4000 - 0x102203fff sshfs (*) <44561020-c195-3898-b4ff-5acf36d45ef8> /Volumes/VOLUME/*/sshfs
0x102700000 - 0x10272ffff libfuse3.4.dylib (*) <cd74eae7-b278-377d-86fd-664f04628378> /usr/local/lib/libfuse3.4.dylib
0x102364000 - 0x10245ffff libglib-2.0.0.dylib (*) <31e21c05-0fe3-3331-a56f-9e819e39cc0c> /opt/homebrew/*/libglib-2.0.0.dylib
0x1035d0000 - 0x103713fff io.macfuse.frameworks.mount (2.1) <49484faa-8015-3f8a-83a5-aa4134c4c744> /Library/Filesystems/macfuse.fs/Contents/Frameworks/MFMount.framework/Versions/A/MFMount
0x10224c000 - 0x102273fff libintl.8.dylib (*) <9ef58f71-571d-352e-bb98-6e9754d6b30b> /opt/homebrew/*/libintl.8.dylib
0x1024b4000 - 0x10252bfff libpcre2-8.0.dylib (*) <ac59ae27-0884-3df1-baf1-38015aa7768b> /opt/homebrew/*/libpcre2-8.0.dylib
0x180ef1000 - 0x180f2e2af libsystem_kernel.dylib (*) <fca53b98-3d6a-38b2-a0ec-df0f7e05f171> /usr/lib/system/libsystem_kernel.dylib
0x180d79000 - 0x180dc023f libdispatch.dylib (*) <f071efe4-299f-3089-acc4-0025b8ffb52a> /usr/lib/system/libdispatch.dylib
0x180b58000 - 0x180bfe217 dyld (*) <f924bdd3-4365-3466-9580-8b1b3fa8f857> /usr/lib/dyld
0x0 - 0xffffffffffffffff ??? (*) <00000000-0000-0000-0000-000000000000> ???
0x180f3c000 - 0x180f44963 libsystem_platform.dylib (*) <160fd864-8d15-36fc-9e97-9725388cfafe> /usr/lib/system/libsystem_platform.dylib
0x180ad0000 - 0x180b22b4b libobjc.A.dylib (*) <ff1d8ae4-abef-35f1-a30a-1183b9cb414f> /usr/lib/libobjc.A.dylib
0x180f2f000 - 0x180f3bb3b libsystem_pthread.dylib (*) <4f33683c-18c8-39a1-800b-2e3bd43bcc13> /usr/lib/system/libsystem_pthread.dylib
macFUSE 5.3.3 went further and now always forces sshfs to run in foreground (as if -f was given) to protect from this crash which is inconvenient (at least).
See also #371 (comment) for some more details.
The fix seems to be trivial - just move fuse_daemonize before fuse_mount. I tested it locally and daemonization works well again, as well as the mounted filesystem, no visible issues after a VS Code stress test on a large project. While reordering can be only made macOS-specific, I don't think it's necessary. Calling fuse_daemonize right after fuse_new and before anything else (e.g. before fuse_mount) seems to be the right way on any platform.
The current order affects macFUSE 5.2.0+ which switched to ObjC
MFMount.frameworkinlibfuse. Usingforkafter touching some ObjC objects and then touching them again in the child afterforkis not supported on macOS and triggers its ownforkguard that terminates thesshfsprocess:macFUSE 5.3.3 went further and now always forces
sshfsto run in foreground (as if-fwas given) to protect from this crash which is inconvenient (at least).See also #371 (comment) for some more details.
The fix seems to be trivial - just move
fuse_daemonizebeforefuse_mount. I tested it locally and daemonization works well again, as well as the mounted filesystem, no visible issues after a VS Code stress test on a large project. While reordering can be only made macOS-specific, I don't think it's necessary. Callingfuse_daemonizeright afterfuse_newand before anything else (e.g. beforefuse_mount) seems to be the right way on any platform.