emacs-tree-sitter / elisp-tree-sitter

Emacs Lisp bindings for tree-sitter
https://emacs-tree-sitter.github.io
MIT License
816 stars 73 forks source link

emacs-tree-sitter causes emacs to SIGABRT on Ubuntu 20.10 #125

Closed josteink closed 3 years ago

josteink commented 3 years ago

Using latest Emacs built from git-master (a9a4af6ff18487938f4859418e8e27ffb174af7c) and latest tree-sitter package(s) from MELPA, activating tree-sitter (for csharp-tree-sitter-mode) causes Emacs to SIGABRT.

Please note: I was forced to wipe my ~/.emacs.d/elpa folder after dist-upgrading, and then re-building Emacs from latest sources, and thus most likely pulled in the latest version of tree-sitter too at the same time. This could in theory be a general regression.

The following is the backtrace when Emacs is invoked through gdb:

jostein@thinkpad-t480s:~$ gdb emacs
GNU gdb (Ubuntu 9.2-0ubuntu2) 9.2
Copyright (C) 2020 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://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 emacs...
(gdb) c
The program is not being run.
(gdb) r
Starting program: /home/jostein/bin/emacs 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff1e8b640 (LWP 48264)]
[New Thread 0x7ffff151f640 (LWP 48265)]
[New Thread 0x7ffff0ab9640 (LWP 48266)]
[Detaching after vfork from child process 48267]
[Detaching after vfork from child process 48268]
[Detaching after vfork from child process 48269]
[Detaching after vfork from child process 48270]
[Detaching after vfork from child process 48272]
[Detaching after vfork from child process 48274]
[Detaching after vfork from child process 48275]
[Detaching after vfork from child process 48304]
[Detaching after vfork from child process 48305]
[Detaching after vfork from child process 48306]
[Detaching after vfork from child process 48307]
[Detaching after vfork from child process 48308]
[Detaching after vfork from child process 48309]
[Detaching after vfork from child process 48311]
[Detaching after vfork from child process 48313]
[Detaching after vfork from child process 48314]
[Detaching after vfork from child process 48343]
[Detaching after vfork from child process 48344]
[Detaching after vfork from child process 48345]
[Detaching after vfork from child process 48346]
[Detaching after vfork from child process 48347]
[Detaching after vfork from child process 48349]
[Detaching after vfork from child process 48351]
[Detaching after vfork from child process 48352]
[Detaching after vfork from child process 48353]
emacs: src/./query.c:1236: ts_query__analyze_patterns: Assertion `exists' failed.

Thread 1 "emacs" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
49  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49
#1  0x00007ffff60ea864 in __GI_abort () at abort.c:79
#2  0x00007ffff60ea749 in __assert_fail_base
    (fmt=0x7ffff6276458 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x7fffe3229423 "exists", file=0x7fffe32292ec "src/./query.c", line=1236, function=<optimized out>) at assert.c:92
#3  0x00007ffff60fca96 in __GI___assert_fail (assertion=0x7fffe3229423 "exists", file=0x7fffe32292ec "src/./query.c", line=1236, function=0x7fffe322a480 <__PRETTY_FUNCTION__.6261> "ts_query__analyze_patterns")
    at assert.c:101
#4  0x00007fffe31cc794 in ts_query_new () at /home/jostein/.emacs.d/elpa/tsc-20210315.238/tsc-dyn.so
#5  0x00007fffe3187400 in tree_sitter::Query::new () at /home/jostein/.emacs.d/elpa/tsc-20210315.238/tsc-dyn.so
#6  0x00007fffe319b35d in tsc_dyn::query::__emr_O__make_query () at /home/jostein/.emacs.d/elpa/tsc-20210315.238/tsc-dyn.so
#7  0x00007fffe31b341a in std::panicking::try () at /home/jostein/.emacs.d/elpa/tsc-20210315.238/tsc-dyn.so
#8  0x00007fffe319c02d in tsc_dyn::query::__emrs_E__make_query::extern_lambda () at /home/jostein/.emacs.d/elpa/tsc-20210315.238/tsc-dyn.so
#9  0x0000555555741d4a in funcall_module (function=<optimized out>, nargs=3, arglist=0x7fffffff5bc8) at emacs-module.c:1186
#10 0x000055555570fd87 in Ffuncall (nargs=4, args=args@entry=0x7fffffff5bc0) at eval.c:2928
#11 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#12 0x000055555570fd87 in Ffuncall (nargs=4, args=args@entry=0x7fffffff5e98) at eval.c:2928
#13 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#14 0x000055555570fd87 in Ffuncall (nargs=1, args=args@entry=0x7fffffff61a8) at eval.c:2928
#15 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#16 0x000055555570fd87 in Ffuncall (nargs=1, args=0x7fffffff6578) at eval.c:2928
#17 0x00005555557120b1 in Fapply (nargs=2, args=0x7fffffff6578) at eval.c:2497
#18 0x000055555570fe4b in Ffuncall (nargs=3, args=args@entry=0x7fffffff6570) at lisp.h:2081
#19 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#20 0x000055555570fd87 in Ffuncall (nargs=1, args=args@entry=0x7fffffff6850) at eval.c:2928
#21 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#22 0x0000555555713577 in apply_lambda (fun=<optimized out>, args=<optimized out>, count=<optimized out>) at eval.c:3061
#23 0x0000555555712586 in eval_sub (form=<optimized out>) at eval.c:2466
#24 0x0000555555713bcd in Fprogn (body=0x0) at eval.c:462
#25 Flet (args=<optimized out>) at eval.c:1048
#26 0x0000555555712702 in eval_sub (form=<optimized out>) at lisp.h:2081
#27 0x0000555555712b2d in Fprogn (body=0x0) at eval.c:462
#28 0x0000555555712702 in eval_sub (form=<optimized out>) at lisp.h:2081
#29 0x0000555555713375 in Fprogn (body=0x555557e24f53) at eval.c:462
#30 funcall_lambda (fun=0x555557e2f1f3, nargs=0, arg_vector=0x7fffffff6f60) at eval.c:3184
#31 0x000055555570fd87 in Ffuncall (nargs=1, args=args@entry=0x7fffffff6f58) at eval.c:2928
#32 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#33 0x000055555570fd87 in Ffuncall (nargs=3, args=args@entry=0x7fffffff7270) at eval.c:2928
#34 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#35 0x000055555570fd87 in Ffuncall (nargs=1, args=args@entry=0x7fffffff7730) at eval.c:2928
#36 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#37 0x000055555570fd87 in Ffuncall (nargs=2, args=args@entry=0x7fffffff7a70) at eval.c:2928
#38 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#39 0x000055555570fd87 in Ffuncall (nargs=6, args=args@entry=0x7fffffff7e98) at eval.c:2928
#40 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#41 0x000055555570fd87 in Ffuncall (nargs=3, args=args@entry=0x7fffffff8250) at eval.c:2928
#42 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#43 0x000055555570fd87 in Ffuncall (nargs=1, args=args@entry=0x7fffffff8528) at eval.c:2928
#44 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#45 0x000055555570fd87 in Ffuncall (nargs=2, args=args@entry=0x7fffffff8820) at eval.c:2928
#46 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#47 0x000055555570fd87 in Ffuncall (nargs=3, args=args@entry=0x7fffffff8b70) at eval.c:2928
#48 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#49 0x000055555570fd87 in Ffuncall (nargs=1, args=args@entry=0x7fffffff8e98) at eval.c:2928
#50 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#51 0x000055555570fd87 in Ffuncall (nargs=1, args=0x7fffffff91b0) at eval.c:2928
#52 0x000055555570fe6d in funcall_nil (nargs=<optimized out>, args=<optimized out>) at eval.c:2555
#53 0x000055555570f47d in run_hook_with_args (nargs=1, args=0x7fffffff91b0, funcall=0x55555570fe60 <funcall_nil>) at eval.c:2732
#54 0x000055555570f5fc in Frun_hook_with_args (args=0x7fffffff91b0, nargs=1) at eval.c:2745
#55 run_hook (hook=<optimized out>) at eval.c:2745
#56 Frun_hooks (nargs=2, args=0x7fffffff9268) at eval.c:2579
#57 0x000055555570fe4b in Ffuncall (nargs=3, args=args@entry=0x7fffffff9260) at lisp.h:2081
#58 0x000055555574d964 in exec_byte_code (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=<optimized out>, nargs=<optimized out>, args=<optimized out>) at bytecode.c:632
#59 0x000055555570fd87 in Ffuncall (nargs=2, args=args@entry=0x7fffffff95a0) at eval.c:2928

Checking tsc-dyn.so using ldd gives the following output, which looks OK to me:

jostein@thinkpad-t480s:~$ ldd /home/jostein/.emacs.d/elpa/tsc-20210315.238/tsc-dyn.so
    linux-vdso.so.1 (0x00007fffd8f9f000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f92432d4000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f92432b9000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f92432ae000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f924328c000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f92430a2000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f92436f9000)

I'm honestly not sure if this bug is related to Ubuntu 20.10, or something else.

theHamsta commented 3 years ago

This is already fixed on tree-sitter runtime 0.19.3. The bug is present in tree-sitter runtime version 0.19.[0-2].Therw is probably one problematic query that triggers the crash. So you can bisect if you don't want to do a manual build of the newer tree-sitter version.

The problem: https://github.com/tree-sitter/tree-sitter/issues/968#issuecomment-792314281 The fix: https://github.com/tree-sitter/tree-sitter/pull/971

josteink commented 3 years ago

Oh I see. That's certainly helpful.

That said, if this is already fixes in 0.19.3, how come I still get the error when trying to rebuild tsc-dyn.so in place using cargo build ?

0.19.3 already seems to re referenced by Cargo.toml:

[package]
name = "emacs-tree-sitter"
version = "0.15.0"
authors = ["Tuấn-Anh Nguyễn <ubolonton@gmail.com>"]
edition = "2018"
publish = false

[lib]
path = "src/lib.rs"
name = "tsc_dyn"
crate-type = ["cdylib"]

[dependencies]
emacs = "0.17"
libloading = "0.7.0"
tree-sitter = "0.19.3"
once_cell = "1.7.2"

I guess if I can't find a way to bypass this bug, I will be forced to bisect the grammar, yes.

josteink commented 3 years ago

It also seems like 0.19.3 is the latest tree-sitter rust-crate too.

Could I be having some stale caches somewhere?

josteink commented 3 years ago

I encountered this issue originally in csharp-mode which provides its own grammar through ELISP. If I understand it correctly, it should not be possible for elisp-based grammer to have unbalanced parenthesis... So in that case this error probably had a different root cause?

For reference, I did a bisect and managed to isolate the offending rules as seen in this commit: https://github.com/emacs-csharp/csharp-mode/commit/65669643834b8bda7d950185688754cc10bc15a5

Any ideas on why those would make tree-sitter crash? Should this be reported further upstream?

ubolonton commented 3 years ago

This is already fixed on tree-sitter runtime 0.19.3. The bug is present in tree-sitter runtime version 0.19.[0-2].Therw is probably one problematic query that triggers the crash. So you can bisect if you don't want to do a manual build of the newer tree-sitter version.

The problem: tree-sitter/tree-sitter#968 (comment) The fix: tree-sitter/tree-sitter#971

That is a related but probably different issue.

This issue is caused by this assertion. Tree-sitter 0.19.4 still has it:

echo '(prefix_unary_expression (identifier)* @variable)' | tree-sitter query /dev/stdin /tmp/empty.cs
Assertion failed: (exists), function ts_query__analyze_patterns, file src/./query.c, line 1236.
[1]    3970 done       echo '(prefix_unary_expression (identifier)* @variable)' |
       3971 abort      tree-sitter query /dev/stdin /tmp/empty.cs
josteink commented 3 years ago

Ooh great. Will give it a try 😃

josteink commented 3 years ago

Confirmed no longer crashing my emacs, even with (somehow) invalid queries. Great job!

Thanks for the quick fix. Even quicker than the tree-sitter crate getting published :astonished: