ziglint icon indicating copy to clipboard operation
ziglint copied to clipboard

Recursion in unused.zig causes infinite loop

Open F3real opened this issue 2 years ago • 5 comments

Test example bad\unused_decl.zig causes stack overflow due to recursion having infinite loop.

It goes to:

checkNamespace( container_decl_two ...)
→ checkNamespaceItem (fn_decl...)
→ checkNamespaceItem (fn_proto...)
→ searchForNameInNamespace
→ checkValueForName(simple_var_decl...)

where for init node we have container_decl_two which calls checkNamespace and it repeats.

Can be fixed by just removing:

         .container_decl, .container_decl_trailing => {
             const x = ast.containerDecl(node);
             if (try checkValuesForName(ast, search_name, x.ast.members, writer, file_name, node)) return true;
-            try checkNamespace(ast, node, writer, file_name);
             return false;
         },

But probably larger refactor would be needed to make it more performant/safer.

F3real avatar Nov 26 '23 11:11 F3real

can u post the zig file that tripped this issue as well? I'm happy to look into this

nektro avatar Nov 26 '23 21:11 nektro

 C:\Users\user\ziglint>zig build -Dmode=Debug -j1
 C:\Users\user\ziglint> .\zig-out\bin\ziglint.exe
./bad\dupe_import.zig:5:11: found duplicate import of "std"
./bad\file_as_struct.zig:1:1: found top level fields, file name should be capitalized
./bad\todo.zig:6:1: TODO: maybe the return type should be !void
./bad\todo.zig:8:5: TODO: switch to something that also prints in release mode
./bad\unused_decl.zig:12:11: unused local declaration 'bar'
Stack Overflow

It can be reproduced just by running ziglint on ./bad\unused_decl.zig example.

F3real avatar Nov 26 '23 21:11 F3real

~~oh hmmm. seems that's only propagating on windows. on linux with~~

[meghan@nixos:/run/media/meghan/dev/ziglint]$ zig build run
./bad/file_as_struct.zig:1:1: found top level fields, file name should be capitalized
./bad/unused_function.zig:9:4: unused local function 'foo'
./bad/todo.zig:6:1: TODO: maybe the return type should be !void
./bad/todo.zig:8:5: TODO: switch to something that also prints in release mode
./bad/unused_decl.zig:12:11: unused local declaration 'bar'
./bad/unused_decl.zig:16:8: unused local function 'baz'
./bad/unused_decl.zig:3:7: unused local declaration 'root'
./bad/dupe_import.zig:5:11: found duplicate import of "std"
./src/main.zig:93:5: TODO: eventually do .gitignore parsing
[meghan@nixos:/run/media/meghan/dev/ziglint]$ ./zig-out/bin/ziglint 
./bad/file_as_struct.zig:1:1: found top level fields, file name should be capitalized
./bad/unused_function.zig:9:4: unused local function 'foo'
./bad/todo.zig:6:1: TODO: maybe the return type should be !void
./bad/todo.zig:8:5: TODO: switch to something that also prints in release mode
./bad/unused_decl.zig:12:11: unused local declaration 'bar'
Segmentation fault (core dumped)

this behavior is much weirder than i expected. digging...

nektro avatar Nov 26 '23 21:11 nektro

[meghan@nixos:/run/media/meghan/dev/ziglint]$ gdb ./zig-out/bin/ziglint 
GNU gdb (GDB) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./zig-out/bin/ziglint...
(gdb) r
Starting program: /run/media/meghan/dev/ziglint/zig-out/bin/ziglint 
./bad/file_as_struct.zig:1:1: found top level fields, file name should be capitalized
./bad/unused_function.zig:9:4: unused local function 'foo'
./bad/todo.zig:6:1: TODO: maybe the return type should be !void
./bad/todo.zig:8:5: TODO: switch to something that also prints in release mode
./bad/unused_decl.zig:12:11: unused local declaration 'bar'

Program received signal SIGSEGV, Segmentation fault.
0x000000000032467c in __zig_probe_stack () at /home/meghan/.local/share/zig/lib/compiler_rt/stack_probe.zig:53
53                  asm volatile (
(gdb) bt
#0  0x000000000032467c in __zig_probe_stack () at /home/meghan/.local/share/zig/lib/compiler_rt/stack_probe.zig:53
Backtrace stopped: Cannot access memory at address 0x7ffffeffe970
(gdb) 

nektro avatar Nov 26 '23 21:11 nektro

bottom of strace stack is

write(1, "bar", 3)                      = 3
write(1, "'\n", 2)                      = 2
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x7ffc42883d90} ---
--- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=NULL} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)

nektro avatar Nov 26 '23 21:11 nektro