Stack overflow when builtins.toXML is given a derivation
#397
Opened by qyliss at
builtins.toXML { drv = derivation { name = "test"; builder = "/bin/sh"; system = builtins.currentSystem; }; }
cppnix:
<?xml version='1.0' encoding='utf-8'?> <expr> <attrs> <attr name="drv"> <derivation drvPath="/nix/store/vbmz3fr4imxm4r227b0jxz3izav4cdm0-test.drv" outPath="/nix/store/a3b6sypggf9c6qama5j182zsm6vcb2s5-test"> <attr name="all"> <list> <derivation drvPath="/nix/store/vbmz3fr4imxm4r227b0jxz3izav4cdm0-test.drv" outPath="/nix/store/a3b6sypggf9c6qama5j182zsm6vcb2s5-test"> <repeated /> </derivation> </list> </attr> <attr name="builder"> <string value="/bin/sh" /> </attr> <attr name="drvAttrs"> <attrs> <attr name="builder"> <string value="/bin/sh" /> </attr> <attr name="name"> <string value="test" /> </attr> <attr name="system"> <string value="aarch64-linux" /> </attr> </attrs> </attr> <attr name="drvPath"> <string value="/nix/store/vbmz3fr4imxm4r227b0jxz3izav4cdm0-test.drv" /> </attr> <attr name="name"> <string value="test" /> </attr> <attr name="out"> <derivation drvPath="/nix/store/vbmz3fr4imxm4r227b0jxz3izav4cdm0-test.drv" outPath="/nix/store/a3b6sypggf9c6qama5j182zsm6vcb2s5-test"> <repeated /> </derivation> </attr> <attr name="outPath"> <string value="/nix/store/a3b6sypggf9c6qama5j182zsm6vcb2s5-test" /> </attr> <attr name="outputName"> <string value="out" /> </attr> <attr name="system"> <string value="aarch64-linux" /> </attr> <attr name="type"> <string value="derivation" /> </attr> </derivation> </attr> </attrs> </expr>
tvix:
thread 'main' has overflowed its stack fatal runtime error: stack overflow
Nix must have some special support for derivations here, because they seem to have cycles, which our
toXML
implementation does not recognize (though the repl does). A large-but-terminating expression like this does still lead to a stack overflow though:let fix = f: let x = f x; in x; in builtins.toXML (fix (f: i: if i >10000 then {} else { "${toString i}" = f (i + 1); }) 0)
It does not seem to do so in nix-repl (though if you increase the loop breaker constant any more, you risk blowing out all your memory …)
profpatsch at 2024-05-20T20·49+00
With my changes in https://cl.tvl.fyi/c/depot/+/11698, the following expression:
let fix = f: let x = f x; in x; in builtins.substring 0 100 (builtins.toXML (fix (f: i: if i >20000 then {} else { "${toString i}" = f (i + 1); }) 0))
takes ~10s in
nix repl
and ~20s intvix repl
.profpatsch at 2024-05-20T21·04+00