[Debian-science-sagemath] GAP: issue related to compressed manual.six: PATCHES: reproducing issue

Ximin Luo infinity0 at debian.org
Sun Dec 11 21:49:00 UTC 2016


Bill Allombert:
> On Sun, Dec 11, 2016 at 07:37:00PM +0000, Ximin Luo wrote:
>> But the "corrupt" file is not "/usr/share/gap/doc/tut/manual.six.gz", the "read" call gave back exactly what was expected. In fact the actual "corrupted" files are the manual files from alnuth and autogrp. if you run: 
>>
>> $ sudo gunzip /usr/share/gap/pkg/AutPGrp/doc/manual.six.gz
>> $ sudo gunzip /usr/share/gap/pkg/Alnuth/doc/manual.six.gz
> 
> GAP itself handles the compressed old-style .six files correctly. They
> are not corrupted.
> 

OK, thanks for the explanation and sorry for the false alarm. However, I am still quite certain the bug is not caused by the Python pipes issue.

I have traced it down to how the gap_reset_workspace() function works in Sage's code, and actually you can reproduce it with only GAP (it segfaults!), without Sage, if you download this file:

https://people.debian.org/~infinity0/res/sagetest.py.gap.xz

Unzip it, make sure gap-alnuth is installed, then run:

| $ echo '?FieldByMatricesNC' | gap -q -L ./sagetest.py.gap 
| #W  corrupted 'manual.six': ##W (in stream: InputTextFile(/usr/share/gap/doc/t\
| ut/manual.six))
| #W  corrupted 'manual.six': ##W (in stream: InputTextFile(/usr/share/gap/doc/c\
| hanges/manual.six))
| #W  corrupted 'manual.six':  intro.tex 1. Introduction
| #W (in stream: InputTextFile(/usr/share/gap/pkg/Alnuth/doc/manual.six))
| Error, no method found! For debugging hints type ?Recovery from NoMethodFound
| Error, no 1st choice method found for `+' on 2 arguments called from
| pos - 1 at /usr/share/gap/lib/helpdef.gi:168 called from
| HELP_BOOK_HANDLER.(handler).ReadSix( stream 
|  ) at /usr/share/gap/lib/helpbase.gi:679 called from
| [..]
| quite a lot of output
| [..]
| res := SHELL( context, mayReturnVoid, mayReturnObj, 1, false, prompt, false, 
|    "*errin*", "*errout*", false )
|  ; at /usr/share/gap/lib/error.g:235 called from
| ...  at line 1 of *errin*
| you can 'return;' after assigning a value
| brk_14> Segmentation fault
| # exit code 139

It is an issue with gap_reset_workspace() because if you explicitly avoid it, then Sage+GAP can read this file just fine.

| $ ./sage -c "print(gap.help('SymmetricGroup', pager=False)[:100])"
| [ gives the error ]
| 
| $ ./sage -c "gap=Gap(use_workspace_cache=False); print(gap.help('SymmetricGroup', pager=False)[:100])"
| [ doesn't give the error ]

To demonstrate this in slightly more detail, I have attached two files:

- sagetest.g  - this is directly from Sage, for Bill's reference

- sagetest.py - this is my attempt to come up with a "minimal test example". I failed, it's not minimal and still requires Sage, however it demonstrates that the problem is to do with Sage's method of "resetting" the gap workspace.

Hopefully Jerome can confirm the following, by running in sagemath.git/sage:

| sagemath.git/sage$ python sagetest.py 0 # don't use a workspace file
| Creation of number fields ______________________ Methods for number fields
| 
| We   provide  functions  to  create  number  fields  defined  by  rational
| matrices or by rational polynomials.
| 
| [..]
| 
| Creates  a field defined by <polynomial>. The polynomial <polynomial> must
| be  an  irreducible  rational  polynomial.  In  the  faster NC version, no
| checks on the input are performed.
|
| sagemath.git/sage$ python sagetest.py 1 # i.e. do use a (new) workspace file; it gets "reset" first by Sage
| *** Error loading Gap package sonata. You may want to install the gap_packages and/or database_gap SPKGs.
| *** Error loading Gap package guava. You may want to install the gap_packages and/or database_gap SPKGs.
| *** Error loading Gap package factint. You may want to install the gap_packages and/or database_gap SPKGs.
| *** Error loading Gap package grape. You may want to install the gap_packages and/or database_gap SPKGs.
| *** Error loading Gap package design. You may want to install the gap_packages and/or database_gap SPKGs.
| *** Error loading Gap package toric. You may want to install the gap_packages and/or database_gap SPKGs.
| *** Error loading Gap package laguna. You may want to install the gap_packages and/or database_gap SPKGs.
| *** Error loading Gap package braid. You may want to install the gap_packages and/or database_gap SPKGs.
| Traceback (most recent call last):
|   File "sagetest.py", line 409, in <module>
|     print(gap.help('FieldByMatricesNC'))
|   File "sagetest.py", line 367, in help
|     line = Expect.eval(self, "? %s"%s)
|   File "/home/infinity0/var/lib/sage/sagemath/debian/build/usr/lib/python2.7/dist-packages/sage/interfaces/expect.py", line 1299, in eval
|     for L in code.split('\n') if L != ''])
|   File "sagetest.py", line 330, in _eval_line
|     raise RuntimeError(message)
| RuntimeError: Gap produced error output
| Error, no method found! For debugging hints type ?Recovery from NoMethodFound
| Error, no 1st choice method found for `+' on 2 arguments
| 
|    executing ? FieldByMatricesNC
| # exit code 1

Since you guys know more about GAP than I do, perhaps you can take a look at gap_reset_workspace() in sagetest.py and see if anything looks suspicious? It's still unclear if this is a GAP or a Sage bug.

X

-- 
GPG: ed25519/56034877E1F87C35
GPG: rsa4096/1318EFAC5FBBDBCE
https://github.com/infinity0/pubkeys.git
-------------- next part --------------

#
# SAGE support utilities to read into the GAP session.
#
\$SAGE := rec();

\$SAGE.OldPager := Pager;


\$SAGE.NewPager :=
          function( data )
    local   str,  lines,  line, fn, start;
    str := OutputTextFile(\$SAGE.tempfile,false);
    start := 1;
    if IsRecord(data) then
        lines := data.lines;
        if IsBound(data.start) then
            start := data.start;
        fi;
    else
        lines := data;
    fi;
    if IsString(lines) then
        lines := SplitString(lines,"\n");
    fi;
    for line in lines do
        WriteLine(str, line);
    od;
    CloseStream(str);
    Print("Page from ",start,"\n");
end;

\$SAGE.StartInteract := function()
    MakeReadWriteGlobal("Pager");
    Pager := \$SAGE.OldPager;
    HELP_VIEWER_INFO.screen.show := \$SAGE.OldPager;
    MakeReadOnlyGlobal("Pager");
end;


\$SAGE.StopInteract := function()
    MakeReadWriteGlobal("Pager");
    Pager := \$SAGE.NewPager;
    HELP_VIEWER_INFO.screen.show := \$SAGE.NewPager;
    MakeReadOnlyGlobal("Pager");
end;


\$SAGE.StopInteract();

#\$SAGE.ErrorHandler := function(m,a,m2,mode)
#    PrintTo("*errout*", m);
#    if a <> fail then
#        PrintTo("*errout*",a);
#    fi;
#    SetErrorHandler(\$SAGE.ErrorHandler);
#    return true;
#end;

#SetErrorHandler(\$SAGE.ErrorHandler);

SetAllInfoLevels(0);

\$SAGE.OperationsAdmittingFirstArgument := function(obj)
    local   hits,  myflags,  i,  flagss,  flags;
    hits := [];
    myflags := FlagsType(TypeObj(obj));
    for i in [1,3..Length(OPERATIONS)-1] do
        flagss := OPERATIONS[i+1];
        for flags in flagss do
            if Length(flags) >= 1 and IS_SUBSET_FLAGS(myflags, flags[1]) then
                Add(hits, OPERATIONS[i]);
                break;
            fi;
        od;
    od;
    return hits;
end;


\$SAGE.CleanOperationName := function(name)
    local   lt,  ls;
    lt := Length("Tester(");
    if Length(name) > lt and name{[1..lt]} = "Tester(" then
        return Concatenation("Has",name{[lt+1..Length(name)-1]});
    fi;
    ls := Length("Setter(");
    if Length(name) > ls and name{[1..ls]} = "Setter(" then
        return Concatenation("Set",name{[lt+1..Length(name)-1]});
    fi;
    return name;
end;

\$SAGE.HasAtLeastOneMethodAsFirstArgument := function(op,obj)
    local   t,  f,  n,  meths,  i;
    t := TypeObj(obj);
    f := FlagsType(t);
    for n in [1..6] do
        meths := METHODS_OPERATION(op,n);
        for i in [1,n+5..LENGTH(meths)-n-3] do
            if IS_SUBSET_FLAGS(f,meths[i+1]) then
                return true;
            fi;
        od;
    od;
    return false;
end;


\$SAGE.PlausibleTabCompletionsForSage := function(o)
    local   ops,  opnames;
    ops := Filtered(\$SAGE.OperationsAdmittingFirstArgument(o), op ->
                   \$SAGE.HasAtLeastOneMethodAsFirstArgument(op,o));
    opnames := List(ops, op -> \$SAGE.CleanOperationName(NameFunction(op)));
    return Concatenation(opnames, GLOBAL_FUNCTION_NAMES);
end;

# The log below is for debuging only.
# CAREFUL -- do *not* activate this unless you know
# what you are doing.  E.g., if active and the user doesn't
# have write permission to /tmp (e.g., on OS X),
# then gap will completely fail to work for them.   -- WAS
#
LogTo("/tmp/gapsage.log");
#
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sagetest.py
Type: text/x-python
Size: 2754 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/debian-science-sagemath/attachments/20161211/38b5d6b9/attachment-0001.py>


More information about the Debian-science-sagemath mailing list