oscar-system / GAP.jl

GAP packages for Julia integration
https://oscar-system.github.io/GAP.jl/
GNU Lesser General Public License v3.0
57 stars 19 forks source link

Segmentation fault when coding a syntax tree obtained from evaluating a Julia string #814

Open zickgraf opened 2 years ago

zickgraf commented 2 years ago

The input

$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.7.2 (2022-02-06)
 _/ |\__'_|_|_|\__'_|  |  
|__/                   |

julia> using GAP
 ┌───────┐   GAP 4.12dev-1062-g401c797-dirty built on 2022-03-01 09:32:09+0000
 │  GAP  │   https://www.gap-system.org
 └───────┘   Architecture: x86_64-pc-linux-gnu-julia64-kv8
 Configuration:  gmp 6.2.1, Julia GC, Julia 1.7.2, readline
 Loading the library and packages ...
 Packages:   GAPDoc 1.dev, IO 4.7.1, JuliaInterface 0.7.7, PrimGrp 3.4.1, SmallGrp 1.4.2, TransGrp 3.3
 Try '??help' for help. See also '?copyright', '?cite' and '?authors'

julia> GAP.Globals.SYNTAX_TREE_CODE(GAP.Globals.SYNTAX_TREE(GAP.Globals.EvalString(GapObj("x -> x"))));

leads to a segmentation fault:

signal (11): Segmentation fault
in expression starting at REPL[2]:1
GetInputFilenameID at /workspace/srcdir/gap/src/io.c:256
unknown function (ip: (nil))
unknown function (ip: 0x7f2ada08c81f)
Allocations: 2019021 (Pool: 2005180; Big: 13841); GC: 5
zsh: segmentation fault (core dumped)  julia

The segmentation fault does not occur in a GAP prompt:

julia> GAP.prompt();
gap> SYNTAX_TREE_CODE(SYNTAX_TREE(EvalString("x -> x")));
function( x ) ... end

cc @mohamed-barakat

fingolfin commented 2 years ago

Thanks, I'll have a look. BTW, it seems to me your are using an older version of GAP.jl (and hence an older GAP). Not that it makes a difference!

fingolfin commented 2 years ago

The syntax tree code unfortunately is a bit of a hack in parts. In particular, it calls parts of the AST coder despite not really being run in the right context, and usually "gets away" with that. But not here: SyntaxTreeCodeFunc_Internal just calls CodeFuncExprBegin and expects it to work. But that then does this:

    SET_GAPNAMEID_BODY(body, GetInputFilenameID(GetCurrentInput()));

But at the time this is executed there is no active GAP input stream. So GetCurrentInput() returns NULL and we get a crash.

One can verify this with the following snippet:

julia> GAP.Globals.INPUT_FILENAME()
GAP: "*defin*"

This value is only returned by FuncINPUT_FILENAME if the "current input" is set to NULL.

A proper fix requires adjusting the GAP kernel code. E.g. perhaps CodeFuncExprBegin should not set the if startLine is set to 0. Or perhaps GetInputFilenameID should be modified to deal with a NULL argument, and return a placeholder (so essentially move part FuncINPUT_FILENAME into GetInputFilenameID). Gotta think a bit about it.

As a workaround, you could try to ensure there is an active GAP input stream during your call. E.g. by using EvalString, or rather GAP.evalstr:

julia> to_syntax_tree_and_back(f::String) = GAP.evalstr("SYNTAX_TREE_CODE(SYNTAX_TREE($f))");

julia> to_syntax_tree_and_back("x -> x")
GAP: function( x ) ... end
zickgraf commented 2 years ago

Thanks a lot for the fast reply and analysis of the problem! Based on your suggestion I have added a workaround to CompilerForCAP where we originally encountered this issue: https://github.com/homalg-project/CAP_project/pull/919. Since we never call SYNTAX_TREE_CODE directly, this fixes the problem for us.

And I have updated my GAP.jl, I still have to get used to the Julia workflow :D

fingolfin commented 2 years ago

Oops, this was closed automatically; but really, while the fix is in the GAP repo, it's not yet in GAP.jl. I'll leave this open until it is.