Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running gap with incorrect GAP_ROOT_PATHS results in awful error messages #37308

Open
tornaria opened this issue Feb 13, 2024 · 4 comments
Open

Comments

@tornaria
Copy link
Contributor

  • For gap expect interface:
$ GAP_ROOT_PATHS=/bad sage -c 'gap(1)'
** Gap crashed or quit executing 'SaveWorkspace("/home/tornaria/.sage/gap/tmp1xkouu8e");' **
Restarting Gap and trying again
** Gap crashed or quit executing '\$sage1:=1;;' **
Restarting Gap and trying again
** Gap crashed or quit executing 'SaveWorkspace("/home/tornaria/.sage/gap/tmpq435w0q8");' **
Restarting Gap and trying again
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/sage/interfaces/expect.py", line 545, in _start
    self._expect.expect(self._prompt)
  File "/usr/lib/python3.12/site-packages/pexpect/spawnbase.py", line 354, in expect
    return self.expect_list(compiled_pattern_list,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pexpect/spawnbase.py", line 383, in expect_list
    return exp.expect_loop(timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pexpect/expect.py", line 179, in expect_loop
    return self.eof(e)
           ^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pexpect/expect.py", line 122, in eof
    raise exc
pexpect.exceptions.EOF: End Of File (EOF). Exception style platform.
Gap with PID 7218 running /usr/bin/gap -A -l /bad -b -p -T -E -m 64m /usr/lib/python3.12/site-packages/sage/ext_data/gap/sage.g
command: /usr/bin/gap
args: ['/usr/bin/gap', '-A', '-l', '/bad', '-b', '-p', '-T', '-E', '-m', '64m', '/usr/lib/python3.12/site-packages/sage/ext_data/gap/sage.g']
buffer (last 100 chars): b''
before (last 100 chars): b"'-l <gaproot>'?@J@n If you ran the GAP binary directly, try running the 'gap.sh' or 'gap.bat' scr\\@J"
after: <class 'pexpect.exceptions.EOF'>
match: None
match_index: None
exitstatus: None
flag_eof: True
pid: 7218
child_fd: 8
closed: False
timeout: None
delimiter: <class 'pexpect.exceptions.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 4194304
ignorecase: False
searchwindowsize: None
delaybeforesend: None
delayafterclose: 0.1
delayafterterminate: 0.1
searcher: searcher_re:
    0: re.compile(b'gap> ')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/sage/interfaces/expect.py", line 1520, in __init__
    self._name = parent._create(value, name=name)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sage/interfaces/interface.py", line 517, in _create
    self.set(name, value)
  File "/usr/lib/python3.12/site-packages/sage/interfaces/gap.py", line 1353, in set
    self._eval_line(cmd, allow_use_file=True)
  File "/usr/lib/python3.12/site-packages/sage/interfaces/gap.py", line 728, in _eval_line
    self._start()
  File "/usr/lib/python3.12/site-packages/sage/interfaces/gap.py", line 1187, in _start
    gap_reset_workspace(verbose=False)
  File "/usr/lib/python3.12/site-packages/sage/interfaces/gap.py", line 1526, in gap_reset_workspace
    g.save_workspace()
  File "/usr/lib/python3.12/site-packages/sage/interfaces/gap.py", line 1283, in save_workspace
    self.eval('SaveWorkspace("%s");' % (f.name), allow_use_file=False)
  File "/usr/lib/python3.12/site-packages/sage/interfaces/gap.py", line 526, in eval
    result = Expect.eval(self, input_line, **kwds)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sage/interfaces/expect.py", line 1414, in eval
    return '\n'.join(self._eval_line(L, allow_use_file=allow_use_file, **kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sage/interfaces/expect.py", line 1414, in <genexpr>
    return '\n'.join(self._eval_line(L, allow_use_file=allow_use_file, **kwds)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sage/interfaces/gap.py", line 728, in _eval_line
    self._start()
  File "/usr/lib/python3.12/site-packages/sage/interfaces/gap.py", line 1192, in _start
    Expect._start(self, "Failed to start GAP.")
  File "/usr/lib/python3.12/site-packages/sage/interfaces/expect.py", line 549, in _start
    raise RuntimeError("unable to start %s: %s" % (self.name(), msg))
RuntimeError: unable to start gap: End Of File (EOF). Exception style platform.
Gap with PID 7218 running /usr/bin/gap -A -l /bad -b -p -T -E -m 64m /usr/lib/python3.12/site-packages/sage/ext_data/gap/sage.g
command: /usr/bin/gap
args: ['/usr/bin/gap', '-A', '-l', '/bad', '-b', '-p', '-T', '-E', '-m', '64m', '/usr/lib/python3.12/site-packages/sage/ext_data/gap/sage.g']
buffer (last 100 chars): b''
before (last 100 chars): b"'-l <gaproot>'?@J@n If you ran the GAP binary directly, try running the 'gap.sh' or 'gap.bat' scr\\@J"
after: <class 'pexpect.exceptions.EOF'>
match: None
match_index: None
exitstatus: None
flag_eof: True
pid: 7218
child_fd: 8
closed: False
timeout: None
delimiter: <class 'pexpect.exceptions.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 4194304
ignorecase: False
searchwindowsize: None
delaybeforesend: None
delayafterclose: 0.1
delayafterterminate: 0.1
searcher: searcher_re:
    0: re.compile(b'gap> ')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/sagemath/10.3.beta7/bin/sage-eval", line 10, in <module>
    eval(compile(s,'<cmdline>','exec'))
  File "<cmdline>", line 1, in <module>
  File "/usr/lib/python3.12/site-packages/sage/interfaces/interface.py", line 306, in __call__
    result = self._coerce_from_special_method(x)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sage/interfaces/interface.py", line 334, in _coerce_from_special_method
    return (x.__getattribute__(s))(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "sage/structure/sage_object.pyx", line 749, in sage.structure.sage_object.SageObject._gap_ (build/cythonized/sage/structure/sage_object.c:8742)
  File "sage/structure/sage_object.pyx", line 725, in sage.structure.sage_object.SageObject._interface_ (build/cythonized/sage/structure/sage_object.c:8165)
  File "/usr/lib/python3.12/site-packages/sage/interfaces/interface.py", line 299, in __call__
    return cls(self, x, name=name)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/sage/interfaces/expect.py", line 1525, in __init__
    raise TypeError(*x.args)
TypeError: unable to start gap: End Of File (EOF). Exception style platform.
Gap with PID 7218 running /usr/bin/gap -A -l /bad -b -p -T -E -m 64m /usr/lib/python3.12/site-packages/sage/ext_data/gap/sage.g
command: /usr/bin/gap
args: ['/usr/bin/gap', '-A', '-l', '/bad', '-b', '-p', '-T', '-E', '-m', '64m', '/usr/lib/python3.12/site-packages/sage/ext_data/gap/sage.g']
buffer (last 100 chars): b''
before (last 100 chars): b"'-l <gaproot>'?@J@n If you ran the GAP binary directly, try running the 'gap.sh' or 'gap.bat' scr\\@J"
after: <class 'pexpect.exceptions.EOF'>
match: None
match_index: None
exitstatus: None
flag_eof: True
pid: 7218
child_fd: 8
closed: False
timeout: None
delimiter: <class 'pexpect.exceptions.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 4194304
ignorecase: False
searchwindowsize: None
delaybeforesend: None
delayafterclose: 0.1
delayafterterminate: 0.1
searcher: searcher_re:
    0: re.compile(b'gap> ')
  • For libgap:
$ GAP_ROOT_PATHS=/bad sage -c 'libgap(1)'
gap: hmm, I cannot find 'lib/init.g' maybe use option '-l <gaproot>'?
------------------------------------------------------------------------
/usr/lib/python3.12/site-packages/cysignals/signals.so(+0x9820)[0x7f6abd4cf820]
/usr/lib/python3.12/site-packages/cysignals/signals.so(+0x98e6)[0x7f6abd4cf8e6]
/usr/lib/python3.12/site-packages/cysignals/signals.so(+0xc320)[0x7f6abd4d2320]
/usr/lib/libc.so.6(+0x3d910)[0x7f6abd63d910]
/usr/lib/libgap.so.8(DoOperation1Args+0x24)[0x7f6a2b6ce644]
/usr/lib/libgap.so.8(GAP_EvalString+0x5c)[0x7f6a2b69ab2c]
/usr/lib/python3.12/site-packages/sage/libs/gap/util.so(+0xcbf4)[0x7f6a2c675bf4]
/usr/lib/python3.12/site-packages/sage/libs/gap/libgap.so(+0x1839a)[0x7f6a2c60639a]
/usr/lib/python3.12/site-packages/sage/structure/coerce_maps.so(+0x1de70)[0x7f6ab7dcbe70]
/usr/lib/python3.12/site-packages/sage/structure/parent.so(+0x285ae)[0x7f6abc1795ae]
/usr/lib/python3.12/site-packages/sage/misc/lazy_import.so(+0x1673d)[0x7f6abc62873d]
/usr/lib/libpython3.12.so.1.0(_PyObject_MakeTpCall+0x6b)[0x7f6abdc006eb]
/usr/lib/libpython3.12.so.1.0(+0x1804ea)[0x7f6abdb804ea]
/usr/lib/libpython3.12.so.1.0(PyEval_EvalCode+0xb2)[0x7f6abdcbf752]
/usr/lib/libpython3.12.so.1.0(+0x17e364)[0x7f6abdb7e364]
/usr/lib/libpython3.12.so.1.0(+0x21f903)[0x7f6abdc1f903]
/usr/lib/libpython3.12.so.1.0(PyObject_Vectorcall+0x4f)[0x7f6abdc00c0f]
/usr/lib/libpython3.12.so.1.0(+0x1804ea)[0x7f6abdb804ea]
/usr/lib/libpython3.12.so.1.0(PyEval_EvalCode+0xb2)[0x7f6abdcbf752]
/usr/lib/libpython3.12.so.1.0(+0x2ddca7)[0x7f6abdcddca7]
/usr/lib/libpython3.12.so.1.0(+0x2ddc1b)[0x7f6abdcddc1b]
/usr/lib/libpython3.12.so.1.0(+0x2de302)[0x7f6abdcde302]
/usr/lib/libpython3.12.so.1.0(_PyRun_SimpleFileObject+0x1cf)[0x7f6abdcde08f]
/usr/lib/libpython3.12.so.1.0(_PyRun_AnyFileObject+0x44)[0x7f6abdcdddd4]
/usr/lib/libpython3.12.so.1.0(Py_RunMain+0x313)[0x7f6abdce66f3]
/usr/lib/libpython3.12.so.1.0(Py_BytesMain+0x37)[0x7f6abdce6287]
/usr/lib/libc.so.6(+0x27c4c)[0x7f6abd627c4c]
/usr/lib/libc.so.6(__libc_start_main+0x85)[0x7f6abd627d05]
/usr/bin/python3(_start+0x21)[0x5620698a0081]
------------------------------------------------------------------------
...
@tornaria
Copy link
Contributor Author

@orlitzky

Here's a situation where GAP_ROOT_PATHS will be incorrect: if one installs sagemath-standard in a venv using system gap the default value for SAGE_LOCAL will be sys.prefix which is the venv, so SAGE_LOCAL/share/gap will not be /usr/share/gap. Thus causing this issue.

So I see three issues related to this:

  1. make it so that an error initializing gap or libgap is actually detected and raise a reasonable error instead of keep going and fail in a confusing way.
  2. fix the default of GAP_ROOT_PATHS so it will be good when SAGE_LOCAL is different than the system prefix (/usr).
  3. do we actually need GAP_ROOT_PATHS? It seems to me that running gap without giving gap root paths should be more correct, at least for running gap / libgap.

@orlitzky
Copy link
Contributor

  1. do we actually need GAP_ROOT_PATHS? It seems to me that running gap without giving gap root paths should be more correct, at least for running gap / libgap.

It's "needed" so that people can install the gap_packages SPKG and use them from the system gap. The SAGE_LOCAL path is appended to the usual system one so that GAP will look there for packages, too.

If you're not using sage-the-distro, the easiest fix is just to set GAP_ROOT_PATHS to the correct value, i.e. the one system directory. But if you want to start a bunch of fights then yeah it would be cleaner to not support sage-the-distro GAP packages when using the system GAP. Naturally I think everyone should be using the system packages instead of the SPKGs.

@tornaria
Copy link
Contributor Author

  1. do we actually need GAP_ROOT_PATHS? It seems to me that running gap without giving gap root paths should be more correct, at least for running gap / libgap.

It's "needed" so that people can install the gap_packages SPKG and use them from the system gap. The SAGE_LOCAL path is appended to the usual system one so that GAP will look there for packages, too.

Ah, thanks, I missed this. Did you mean "the SAGE_LOCAL path is prepended to the usual system one"? (so that pkgs installed in sage can override system gap pkgs).

Let me see if I get this right: what we need is a configuration, let's tentatively call it SAGE_GAP_PKG which when set will be prepended to the system gap root paths. Is that correct?

This means:

a. for gap binary, we can run using -l "$SAGE_GAP_PKG;" where the empty last component means to prepend to system root paths:

$ gap -r -l "/SAGE/GAP/PATH;" -q -c 'Display(KERNEL_INFO().GAP_ROOT_PATHS);QUIT;'
[ "/SAGE/GAP/PATH/", "/usr/lib64/gap/", "/usr/share/gap/" ]

b. for libgap we can run using -l "$SAGE_GAP_PKG;<system-root-paths>":

$ ./libgap -r -l "/SAGE/GAP/PATH;/usr/lib64/gap/;/usr/share/gap/" -q -c 'Display(KERNEL_INFO().GAP_ROOT_PATHS);QUIT;'
[ "/SAGE/GAP/PATH/", "/usr/lib64/gap/", "/usr/share/gap/" ]

(here ./libgap is just a trivial shim to run gap-as-library)

c. the for libgap we can get from the gap binary:

$ gap -r --systemfile <(echo 'PRINT_TO("*stdout*",KERNEL_INFO().GAP_ROOT_PATHS,"\n");QuitGap();')
[ "/usr/lib64/gap/", "/usr/share/gap/" ]

(with the systemfile trick this is quick enough to do at runtime)

If this sounds right, I can try to adjust #37344.

If you're not using sage-the-distro, the easiest fix is just to set GAP_ROOT_PATHS to the correct value, i.e. the one system directory. But if you want to start a bunch of fights then yeah it would be cleaner to not support sage-the-distro GAP packages when using the system GAP. Naturally I think everyone should be using the system packages instead of the SPKGs.

I don't want to fight, and I don't want to improve sagemath-standard at the expense of sage-the-distro.

But I want sane defaults and avoid any unnecessary configuration. The less knobs we have, the easier it is to run in different situations. As a matter of fact, the problem I describe here first arised when I built sage-the-distro in editable mode. Because sage-conf editable mode is BROKEN so it won't load GAP_ROOT_PATHS.

A different situation is when running sagemath-standard in a venv since SAGE_LOCAL/share/gap is wrong (SAGE_LOCAL defaults to sys.prefix which is /usr when running non-isolated but path-to-venv when running in a venv).

@orlitzky
Copy link
Contributor

That sounds more or less right for now but the whole thing is a mess so I'm sure some use case will wind up broken. IMO what we really need is a sagelib build system ASAP so we don't need sage_conf handed to us by a deity before sagelib will work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants