nix/tests/functional/lang/eval-fail-duplicate-traces.err.exp
Rebecca Turner 7434caca05
Fix segfault on infinite recursion in some cases
This fixes a segfault on infinite function call recursion (rather than
infinite thunk recursion) by tracking the function call depth in
`EvalState`.

Additionally, to avoid printing extremely long stack traces, stack
frames are now deduplicated, with a `(19997 duplicate traces omitted)`
message. This should only really be triggered in infinite recursion
scenarios.

Before:

    $ nix-instantiate --eval --expr '(x: x x) (x: x x)'
    Segmentation fault: 11

After:

    $ nix-instantiate --eval --expr '(x: x x) (x: x x)'
    error: stack overflow

           at «string»:1:14:
                1| (x: x x) (x: x x)
                 |              ^

    $ nix-instantiate --eval --expr '(x: x x) (x: x x)' --show-trace
    error:
           … from call site
             at «string»:1:1:
                1| (x: x x) (x: x x)
                 | ^

           … while calling anonymous lambda
             at «string»:1:2:
                1| (x: x x) (x: x x)
                 |  ^

           … from call site
             at «string»:1:5:
                1| (x: x x) (x: x x)
                 |     ^

           … while calling anonymous lambda
             at «string»:1:11:
                1| (x: x x) (x: x x)
                 |           ^

           … from call site
             at «string»:1:14:
                1| (x: x x) (x: x x)
                 |              ^

           (19997 duplicate traces omitted)

           error: stack overflow
           at «string»:1:14:
                1| (x: x x) (x: x x)
                 |              ^
2023-12-29 22:16:44 -08:00

45 lines
1.2 KiB
Plaintext

error:
… from call site
at /pwd/lang/eval-fail-duplicate-traces.nix:9:3:
8| in
9| throwAfter 2
| ^
10|
… while calling 'throwAfter'
at /pwd/lang/eval-fail-duplicate-traces.nix:4:16:
3| let
4| throwAfter = n:
| ^
5| if n > 0
… from call site
at /pwd/lang/eval-fail-duplicate-traces.nix:6:10:
5| if n > 0
6| then throwAfter (n - 1)
| ^
7| else throw "Uh oh!";
… while calling 'throwAfter'
at /pwd/lang/eval-fail-duplicate-traces.nix:4:16:
3| let
4| throwAfter = n:
| ^
5| if n > 0
… from call site
at /pwd/lang/eval-fail-duplicate-traces.nix:6:10:
5| if n > 0
6| then throwAfter (n - 1)
| ^
7| else throw "Uh oh!";
… while calling 'throwAfter'
at /pwd/lang/eval-fail-duplicate-traces.nix:4:16:
3| let
4| throwAfter = n:
| ^
5| if n > 0
error: Uh oh!