godotengine / godotengine/godot
SIGSEGV at startup when file logger cannot open its log file (RotatedFileLogger::rotate_file() null deref)
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Godot version
4.7.1.stable.official (a13da4feb) - macOS 26.6.1 arm64 (code path is platform-independent, see cause below)
### System information
macOS 26.6.1 (arm64), official editor binary
### Issue description
The engine crashes with SIGSEGV during startup whenever the file logger's target file cannot be opened. Game mode enables file logging by default on desktop (`debug/file_logging/enable_file_logging.pc` = true), so any game-mode run with an unwritable `user://` (read-only HOME, sandboxed shell, disk full, blocked container dir, ...) dies with signal 11 before the main loop starts.
Editor / project-manager / script / import modes never create the file logger, which is why only game-mode runs are affected.
### Steps to reproduce
Any of:
1. Run a project in game mode with an unwritable `--log-file` target:
```
godot --headless --log-file /nonexistent-dir/foo.log --quit-after 5
```
2. Make `user://` unwritable and run in game mode, e.g. on Linux:
```
chmod 555 ~/.local/share/godot/app_userdata/
godot --headless --quit-after 5
```
(equivalent to a sandboxed/read-only HOME on macOS)
Expected: an error is logged ("Cannot open log file...") and the engine continues without file logging.
Actual: SIGSEGV at startup. Sample backtrace (macOS):
```
Program crashed with signal 11
[1] _sigtramp + 56
[2] ZSTD_decompressStream_simpleArgs + 2307560 (unsymbolized region - nearest-export attribution only)
[3] ZSTD_decompressStream_simpleArgs + 2307560
[4] ZSTD_decompressStream_simpleArgs + 2307812
[5] main + 32784
[6] mvk::SPIRVToMSLConverter::convert(...) + 1981664
[7] main (in Godot) + 944
```
Crash report details: EXC_BAD_ACCESS (KERN_INVALID_ADDRESS) at address 0x158 - consistent with a virtual/field access on a null object (`this + 0x158`). The MoltenVK/ZSTD symbols in the console backtrace are misleading: the crashing code is Godot's own logger (verified by disassembling the crash site and matching it to the logger sources).
### Root cause
`core/io/logger.cpp`, `RotatedFileLogger::rotate_file()`:
```cpp
file = FileAccess::open(base_path, FileAccess::WRITE);
file->detach_from_objectdb(); // Note: This FileAccess instance will exist longer than ObjectDB, therefore can't be registered in ObjectDB.
```
`FileAccess::open()` returns `nullptr` when the file cannot be created (missing directory, permission denied, ENOSPC). The `Ref` member is then null and `file->detach_from_objectdb()` calls into `Object` with a null `this`, dereferencing a field at offset 0x158 - SIGSEGV. The file-logger constructor (`RotatedFileLogger::RotatedFileLogger`) is created early in `Main::setup()`'s file-logging block (`main.cpp`), so the crash happens before any error message from the logger itself.
### Suggested fix
Guard the open result, e.g.:
```cpp
file = FileAccess::open(base_path, FileAccess::WRITE);
if (file.is_null()) {
// Fall back to the std logger with an error instead of crashing.
return;
}
file->detach_from_objectdb();
```
(and similarly handle the failure in `logv()` gracefully).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in core/io/logger.cpp at RotatedFileLogger::rotate_file(), then inspect the related failure path in logv(). Use the headless --log-file reproduction or make user:// unwritable to verify the failure. Done means an unavailable log file reports an error and the engine continues without a SIGSEGV.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- observability
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100