node-tree-sitter icon indicating copy to clipboard operation
node-tree-sitter copied to clipboard

Segfault with tree-sitter-java for multi-pattern multi-predicate query

Open dmfay opened this issue 4 years ago • 2 comments

This query:
((
  (expression_statement
    (method_invocation
      arguments: (argument_list (string_literal) @first_str))
    (#match? @first_str "one fish"))
)(expression_statement
  (method_invocation
    name: (identifier) @mname
    arguments: (argument_list (string_literal) @next_str))
  (#match? @mname "append")
)*)
This Java code:
package com.dot.dot.stuff;

public class Aaa {
	private Stuff stuff;

	public Aaa() {
	}

	public StringBuilder test() {
		StringBuilder sb = new StringBuilder();
		sb.append("one fish");
		sb.append("two fish");
		sb.append("red fish");
		sb.append("blue fish");

		return sb;
	}
}

Works in the tree-sitter playground, segfaults in node-tree-sitter v0.19.0 with tree-sitter-java 0.19.1.

   3:   ~Parser.parse+0(this=0x233e1d901479 <Parser map = 0x1cb716404881>, 0x233e1d901581 <String[283]: "package com.dot.dot.stuff;\n\npublic class Aaa {\n\x09private Stuff stuff;\n\n\x09public Aaa() {\n\x09}\n\n\x09public StringBuilder test() {\n\x09\x09StringBuilder sb = new StringBuilder();\n\x09\x09sb.append("one fish");\n\x09\x09sb.append("two fish");\n\x09\x09sb.append("red fish");\n\x09\x09sb.append("blue fish");\n\n\x09\x09return sb;\n\x09}\n}\n">, 0x1d1865b01599 <undefined>, 0x1d1865b01599 <undefined>) {
   4:    ~input+0(this=0x38cb43581119 <JSGlobal Object>, 0, 0x1cb492e6d3e1 <Object map = 0x1cb716422149>) {
   4:    } -> 0x233e1d901581 <String[283]: "package com.dot.dot.stuff;\n\npublic class Aaa {\n\x09private Stuff stuff;\n\n\x09public Aaa() {\n\x09}\n\n\x09public StringBuilder test() {\n\x09\x09StringBuilder sb = new StringBuilder();\n\x09\x09sb.append("one fish");\n\x09\x09sb.append("two fish");\n\x09\x09sb.append("red fish");\n\x09\x09sb.append("blue fish");\n\n\x09\x09return sb;\n\x09}\n}\n">
   4:    ~input+0(this=0x38cb43581119 <JSGlobal Object>, 283, 0x1cb492e6d491 <Object map = 0x1cb716422149>) {
   4:    } -> 0x1d1865b017b1 <String[0]: #>
   4:    ~Parser.getLanguage+0(this=0x233e1d901479 <Parser map = 0x1cb716404881>, 0x1d1865b01599 <undefined>) {
   4:    } -> 0x33f636ba7911 <Language map = 0x1cb716421de9>
   3:   } -> 0x1cb492e6d4e9 <Tree map = 0x1cb716422269>
   3:   ~Parser.getLanguage+0(this=0x233e1d901479 <Parser map = 0x1cb716404881>, 0x1d1865b01599 <undefined>) {
   3:   } -> 0x33f636ba7911 <Language map = 0x1cb716421de9>
   3:   ~getQuery+0(this=0x1d1865b01599 <undefined>, 0x299339ddc509 <String[4]: #java>) {
   3:   } -> 0x0ecd6a4f1b01 <String[410]: #((\n        (expression_statement\n          (method_invocation\n            arguments: (argument_list (string_literal) @first_str))\n          (#match? @first_str "^.(one fish)"))\n      )(expression_statement\n
   (method_invocation\n          name: (identifier) @mname\n          arguments: (argument_list (string_literal) @next_str))\n        (#match? @mname "append")\n      )*)\n        >
   3:   ~Query._init+0(this=0x1cb492e6d781 <Query map = 0x212864fc94b9>) {
PID 23772 received SIGSEGV for address: 0x78
/path/to/node_modules/segfault-handler/build/Release/segfault-handler.node(+0x2e9b)[0x7feee9f5ee9b]
/usr/lib/libpthread.so.0(+0x13870)[0x7feee929e870]
/path/to/node_modules/tree-sitter/build/Release/tree_sitter_runtime_binding.node(ts_query_pattern_count+0x0)[0x7feee453ac10]
/path/to/node_modules/tree-sitter/build/Release/tree_sitter_runtime_binding.node(_ZN16node_tree_sitter5Query13GetPredicatesERKN3Nan20FunctionCallbackInfoIN2v85ValueEEE+0x56)[0x7feee4529ed6]
/path/to/node_modules/tree-sitter/build/Release/tree_sitter_runtime_binding.node(+0x18b28)[0x7feee4528b28]
node(_ZN2v88internal25FunctionCallbackArguments4CallENS0_15CallHandlerInfoE+0x108)[0x5571376c67e8]
node(+0x9194e0)[0x5571376c74e0]
node(+0x91999f)[0x5571376c799f]
node(_ZN2v88internal21Builtin_HandleApiCallEiPmPNS0_7IsolateE+0x16)[0x5571376c7bf6]
node(+0x1116439)[0x557137ec4439]
zsh: segmentation fault (core dumped)  node --trace ./index.js

This behaves a lot like @cellog's discovery in #72:

further context: the lines

        call receiver: (constant) @class
        (#eq? @class "I18n")
        method: (identifier) @method
        (#eq? @method "namespace")

are responsible. If I remove either

        method: (identifier) @method
        (#eq? @method "namespace")

or

        call receiver: (constant) @class
        (#eq? @class "I18n")

OR remove both predicates (the (#eq?

then the seg fault disappears.

It succeeds with one pattern or the other, or with both patterns sans predicates.

dmfay avatar Aug 24 '21 00:08 dmfay

I got same stacktrace on linux machine or docker, but it does not seem to occur on MacOS.

0x00007f8554ff4dd9 in ts_query_pattern_count (self=0x0) at ../vendor/tree-sitter/lib/src/./query.c:2013
2013	 return self->patterns.size;
(gdb) bt
#0  0x00007f8554ff4dd9 in ts_query_pattern_count (self=0x0) at ../vendor/tree-sitter/lib/src/./query.c:2013
#1  0x00007f8554fda7b4 in node_tree_sitter::Query::GetPredicates (info=...) at ../src/query.cc:149
#2  0x00007f8554fca167 in Nan::imp::FunctionCallbackWrapper (info=...) at ../../nan/nan_callbacks_12_inl.h:176
#3  0x0000000000d471cb in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) ()
#4  0x0000000000d4844a in v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) ()
#5  0x0000000000d48926 in v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) ()
#6  0x00000000015ce039 in Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit ()
#7  0x000000000156612b in Builtins_InterpreterEntryTrampoline ()
#8  0x000020e34c641599 in ?? ()

Based on the source code, I have changed my query to be a Buffer instead of the string and it seems to be working.

const query = new Query(Language, Buffer.from(`
  // my query here
`))

mochja avatar Aug 30 '21 16:08 mochja

It may be fixed in master. (I encountered segfault with tree-sitter-javascript and resolved in master) tree-sitter team members, please release new version 🚢

You can use "tree-sitter": "git://github.com/tree-sitter/node-tree-sitter.git#16302f904d698dfd619824fc9ed76f4edc8d7bfc" for workaround. If you use pnpm, because of https://github.com/pnpm/pnpm/issues/3801, you should use git submodule add ... to maintain it by yourself.

LumaKernel avatar Sep 28 '21 17:09 LumaKernel