diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-05-16 13:45:36 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-05-16 13:45:36 -0500 |
| commit | 62fd9437c7d750cde9c0ae91c4eb9ed4d69ecf35 (patch) | |
| tree | 0e5612688ba8f8f5965012f9060a0f683f6ee094 /libs/plugin_python/tests/runner/test_game.cpp | |
| parent | 48a00723e4d309018309f4fb40870c8f0403f812 (diff) | |
vfs: invalidate full subtree from node_cache on mutation (fixes #210)
invalidateNodeCache's docstring promised "Clear all node_cache entries
whose path starts with the given prefix" but the implementation only
cleared the exact path's entry and its parent. removeFromTree on a
directory destroys every descendant VfsNode via cascading unique_ptr
destruction; every descendant inode still cached in node_cache became
a dangling pointer.
Next time Wine called getattr on a cached descendant ino,
resolveByInode returned the dangling pointer and snapshotFromNode
read freed memory — depending on what reused the allocation, this
manifested as either std::bad_alloc (corrupted string length in
real_path triggers a huge allocation request) or outright SIGSEGV.
ENOMEM bubbled up to Wine's NT loader as ERROR_MOD_NOT_FOUND (0x7E),
which is exactly the F4SE "couldn't load plugin (0000007E)" pattern
reported in #210 after mod-state transitions.
Rewrite invalidateNodeCache to actually walk node_cache and erase
every entry whose path is the target or a descendant under target/.
Lock order is tree_mutex (exclusive, caller) → inode_mutex (shared)
→ node_cache_mutex (exclusive), consistent with existing sites.
Top-level mutations also invalidate root (inode 1) since its
children map changed.
Also enrich the FUSE wrap_* exception macro to log the inode being
processed alongside the exception text. Future "[VFS] getattr(ino=N):
caught exception: ..." entries point straight at the path that
triggered cache/tree corruption.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'libs/plugin_python/tests/runner/test_game.cpp')
0 files changed, 0 insertions, 0 deletions
