Using NimRtl, on Windows, basic path string operations causes SIGSEGV.
Nim Version
Nim Compiler Version 2.3.1 [Windows: amd64]
Compiled at 2025-03-21
Copyright (c) 2006-2025 by Andreas Rumpf
git hash: ab14e0b550119ab6a56623276d57afdf6e5a7e40
active boot switches: -d:release
Description
This minimized example gives SIGSEGV when compiled with -d:useNimRtl on Windows. I've tried both Cpp and C modes.
import os
proc searchFoo(dir:string) =
var path:string = dir
while not isRootDir(path):
echo path / "foo"
path = path.parentDir()
searchFoo("c:\\123\\abc\\def")
The same code runs well with NimRtl on arm64 macos.
Current Output
output log:
Hint: mm: arc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
51793 lines; 1.429s; 73.793MiB peakmem; proj: C:\prj\Nim\lib\testrtl.nim; out: C:\prj\Nim\lib\testrtl.exe [SuccessX]
Hint: C:\prj\Nim\lib\testrtl.exe [Exec]
c:\123\abc\def\foo
c:\123\abc\foo
foo23\foo
Traceback (most recent call last)
C:\prj\Nim\lib\testrtl.nim(9) testrtl
C:\prj\Nim\lib\testrtl.nim(7) searchFoo
c:\prj\Nim\lib\std\private\ospaths2.nim(423) parentDir
c:\prj\Nim\lib\pure\pathnorm.nim(122) normalizePath
c:\prj\Nim\lib\pure\pathnorm.nim(66) addNormalizePath
c:\prj\Nim\lib\system.nim(1696) splitDrive
c:\prj\Nim\lib\system\alloc.nim(1148) alloc
c:\prj\Nim\lib\system\alloc.nim(932) rawAlloc
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Known Workarounds
No response
Additional Information
I'm working on a framework based on DLL modules. There were similar memory corruptions when using some string format procs along with nimRtl. It was a bit too difficult to extract an example.
Tried NimRtl built with -d:useMalloc, it just crashed without giving any stacktrace.
C:\prj\Nim\lib>nim cpp -r -d:debug -d:useNimRtl testrtl
Hint: used config file 'c:\prj\Nim\config\nim.cfg' [Conf]
Hint: used config file 'c:\prj\Nim\config\config.nims' [Conf]
Hint: used config file 'testrtl.nim.cfg' [Conf]
Hint: mm: arc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
10548 lines; 0.019s; 10.566MiB peakmem; proj: testrtl; out: C:\prj\Nim\lib\testrtl.exe [SuccessX]
Hint: C:\prj\Nim\lib\testrtl.exe [Exec]
C:\prj\Nim\lib\foo
Error: execution of an external program failed: 'C:\prj\Nim\lib\testrtl.exe'
FYI, I noticed that expanded Arc codes are different when toggling useNimRtl.
using NimRtl (-d:useNimRtl)
var path
try:
`=copy`(path, dir)
block :tmp:
while not isRootDir(path):
var :tmpD
try:
echo [
:tmpD = path / "foo"
:tmpD]
`=sink`(path, parentDir(path))
finally:
`=destroy`(:tmpD)
finally:
`=destroy`(path)
-- end of expandArc ------------------------
without NimRtl (-u:useNimRtl)
var path
try:
`=copy`(path, dir)
block :tmp:
var :tmpD
while not isRootDir do:
:tmpD = `=dup`(path)
:tmpD:
var :tmpD_1
try:
echo [
:tmpD_1 = path / "foo"
:tmpD_1]
`=sink`(path, parentDir(path))
finally:
`=destroy`(:tmpD_1)
finally:
`=destroy`(path)
-- end of expandArc ------------------------
Weird problem. Different ARC expansions cross platforms. Workaround for now: adds a sink type to isRootDir. I guess there is something suspicious with sink inference for different platforms
I see, in inclrtl sinkInference is always on
{.push sinkInference: on.}
Commenting it makes the arc expansion the same, though the bug remains for nimrtl
SinkInference should be turned off and sink annotations need to be done explicitly.