Menu

#2895 Commandline parser: Illegal seek / Hang on syntax error

None
closed
nobody
None
5
2015-02-04
2015-01-24
No

Using == on the Maxima command line is not parsed correctly, and causes an glibc illegal seek on Linux and just hang on OSX. For example (in Sage using ECL 13.5.1):

--------snip on-----------
$ sage -maxima
;;; Loading #P"/home/vbraun/Code/sage.git/local/lib/ecl/sb-bsd-sockets.fas"
;;; Loading #P"/home/vbraun/Code/sage.git/local/lib/ecl/sockets.fas"
;;; Loading #P"/home/vbraun/Code/sage.git/local/lib/ecl/defsystem.fas"
;;; Loading #P"/home/vbraun/Code/sage.git/local/lib/ecl/cmp.fas"
Maxima 5.35.1 http://maxima.sourceforge.net
using Lisp ECL 13.5.1
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) 1 == 1;

Maxima encountered a Lisp error:

Read or write operation signaled an error
C library explanation: Illegal seek.

Automatically continuing.
To enable the Lisp debugger set debugger-hook to nil.
-------snip off-----------
On OSX there is no output, Maxima hangs but can be interrupted with Ctrl-C.

This worked in Maxima 5.34.1:
--------snip on-----------
$ ./sage -maxima
;;; Loading #P"/home/vbraun/Sage/git-temp/local/lib/ecl/cmp.fas"
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=0
;;;
;;; End of Pass 1.
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=0
;;;
;;; End of Pass 1.
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=0
;;;
;;; End of Pass 1.
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=0
;;;
;;; End of Pass 1.
;;; Loading #P"/home/vbraun/Sage/git-temp/local/lib/ecl/sb-bsd-sockets.fas"
;;; Loading #P"/home/vbraun/Sage/git-temp/local/lib/ecl/sockets.fas"
;;; Loading #P"/home/vbraun/Sage/git-temp/local/lib/ecl/defsystem.fas"
Maxima 5.34.1 http://maxima.sourceforge.net
using Lisp ECL 13.5.1
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) 1 == 1;
incorrect syntax: = is not a prefix operator
1 ==
^
-------snip off-----------

Discussion

  • Robert Dodier

    Robert Dodier - 2015-01-25

    This is a bug in ECL, reported as: https://sourceforge.net/p/ecls/bugs/298/
    The bug is tickled by Maxima commit [05c32161] which added code to the parser to report the file position of syntax errors.

    Closing this report as wont-fix. I don't have a work-around.

    For the record, "==" isn't a built-in operator in Maxima, so its presence causes a syntax error. However, you can declare it via infix("==") and then define it "=="(a, b) := ... something ... if you want.

     
  • Robert Dodier

    Robert Dodier - 2015-01-25
    • labels: --> Problem not in Maxima
    • status: open --> wont-fix
     
  • Volker Braun

    Volker Braun - 2015-01-25

    I'm aware that this is a syntax error. Sage doctests that maxima returns an error in this case (http://trac.sagemath.org/ticket/17667)

    On OSX the file-position returns a number (I guess thats good):

    vbraun@osx:Sage$ ecl
    ECL (Embeddable Common-Lisp) 13.5.1 (git:UNKNOWN)
    Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
    Copyright (C) 1993 Giuseppe Attardi
    Copyright (C) 2000 Juan J. Garcia-Ripoll
    ECL is free software, and you are welcome to redistribute it
    under certain conditions; see file 'Copyright' for details.
    Type :h for Help.  
    Top level.
    > (file-position *standard-input*)
    
    2146
    

    but Maxima hangs indefinitely (bad):

    vbraun@osx:Sage$ maxima
    ;;; Loading #P"/Users/vbraun/Sage/local/lib/ecl/sb-bsd-sockets.fas"
    ;;; Loading #P"/Users/vbraun/Sage/local/lib/ecl/sockets.fas"
    ;;; Loading #P"/Users/vbraun/Sage/local/lib/ecl/defsystem.fas"
    ;;; Loading #P"/Users/vbraun/Sage/local/lib/ecl/cmp.fas"
    Maxima 5.35.1 http://maxima.sourceforge.net
    using Lisp ECL 13.5.1
    Distributed under the GNU Public License. See the file COPYING.
    Dedicated to the memory of William Schelter.
    The function bug_report() provides bug reporting information.
    (%i1) 1 == 1;
    

    hangs forever.

     
  • Nils Bruin

    Nils Bruin - 2015-01-25

    I think the problem, and the perceived infinite loop, on OSX arises from nparse.lisp:mread-synerr:

    (let ((fp (file-position *parse-stream*))
    ...
        (flet ((line-number ()
             ;; Fix me: Neither batch nor load track the line number
             ;; correctly. batch, via dbm-read, does not track the
             ;; line number at all (a bug?).
             ;;
             ;; Find the line number by jumping to the start of file
             ;; and reading line-by-line til we reach the current
             ;; position
             (cond ((and fp (file-position *parse-stream* 0))
                    (do ((l (read-line *parse-stream* nil nil) (read-line *parse-stream* nil nil))
                         (o 1                                  (1+ p))
                         (p (file-position *parse-stream*)     (file-position *parse-stream*))
                         (n 1                                  (1+ n)))
                        ((or (null p) (>= p fp))
                         (cons n (- fp o)))))
                   (t '())))
    

    Indeed, on OSX, (file-position <STDIN>) apparently returns a non-nil value with ECL. It may well be that OSX keeps a count of numbers of characters read on STDIN, so returning a value here is quite reasonable. If subsequently, (file-position parse-stream 0) also returns a non-nil value (a terminal is not seekable, so that might be an error on the side of ECL. Can someone with access to ECL on OSX test that (file-position standard-input 0) in the REPL returns T?) then maxima will subsequently proceed reading lines from the parse-stream to determine a line count.

    The same file contains configuration variables:

    (defmvar $report_synerr_line t "If T, report line number where syntax error occurs; otherwise, report FILE-POSITION of error.")
    (defmvar $report_synerr_info t "If T, report the syntax error details from all sources; otherwise, only report details from standard-input.")
    

    but their values only get checked in mread-synerr after the code above gets executed. If the code gets reorganized so that this code is avoided if the values of these variables indicate the line number is needed, at least there would be a workaround by setting these variables to NIL. Presently doing so wouldn't help, because the loop-causing code (which is potentially extremely slow, since it insists on reading the entire input stream line-by-line from the start) gets executed anyway.

     
  • Volker Braun

    Volker Braun - 2015-01-26

    I can confirm that on OSX:

    > (file-position *standard-input* 0)
    
    T
    
     
    • Nils Bruin

      Nils Bruin - 2015-02-01

      Thanks for testing. For SBCL on OSX I also get

      * (file-position *standard-input* 0)
      
      T
      

      so SBCL is just as non-conforming as ECL is, and with it probably all other lisps on OSX. Does Maxima want to depend on a part of CLHS that is so badly supported?

       

      Last edit: Nils Bruin 2015-02-01
  • Andrej Vodopivec

    • labels: Problem not in Maxima -->
    • status: wont-fix --> open
     
  • Andrej Vodopivec

    I think that mread-synerr misbehaves in certain cases.

    Tested with clisp on OSX:

    Maxima branch_5_35_base_136_gbf18486 http://maxima.sourceforge.net
    using Lisp CLISP 2.49 (2010-07-07)
    Distributed under the GNU Public License. See the file COPYING.
    Dedicated to the memory of William Schelter.
    The function bug_report() provides bug reporting information.
    (%i1) 1 == 1;
    /Users/andrej/.maxima/maxima-init.mac:NIL:NIL:incorrect syntax: = is not a prefix operator
    1 ==
      ^
    (%i1)
    

    maxima reports that there is an error in maxima-init.mac, but it is in fact on the command line. After a file is loaded, maxima will report the error in that file instead of command line:

    (%i1) load(solve_rec)$
    (%i2) 1 == 1;
    /Users/andrej/Projects/maxima/share/solve_rec/solve_rec.mac:NIL:NIL:incorrect syntax: = is not a prefix operator
    1 ==
      ^
    (%i2)
    

    ccl on OSX behaves the same. sbcl in all cases hangs instead of reporting the syntax error.

    A possible fix is to disable line/column reporting when parsing from *standard-input*:

    diff --git a/src/nparse.lisp b/src/nparse.lisp
    index aad7e48..5a48b08 100644
    --- a/src/nparse.lisp
    +++ b/src/nparse.lisp
    @@ -37,8 +37,10 @@
     (defmvar $report_synerr_info t "If T, report the syntax error details from all
    
     (defun mread-synerr (format-string &rest l)
    -  (let ((fp (file-position *parse-stream*))
    -       (file (cadr *current-line-info*)))
    +  (let ((fp (and (not (eq *parse-stream* *standard-input*))
    +                 (file-position *parse-stream*)))
    +       (file (and (not (eq *parse-stream* *standard-input*))
    +                   (cadr *current-line-info*))))
         (flet ((line-number ()
                 ;; Fix me: Neither batch nor load track the line number
                 ;; correctly. batch, via dbm-read, does not track the
    

    The line/column is still reported correctly with this patch.

    Maxima branch_5_35_base_136_gbf18486 http://maxima.sourceforge.net
    using Lisp SBCL 1.2.2
    Distributed under the GNU Public License. See the file COPYING.
    Dedicated to the memory of William Schelter.
    The function bug_report() provides bug reporting information.
    (%i1) 1 == 1;
    
    incorrect syntax: = is not a prefix operator
    1 ==
      ^
    (%i1) load("test.mac");
    
    /Users/andrej/.maxima/test.mac:1:3:incorrect syntax: = is not a prefix operator
    1 ==
      ^
    (%i2)
    
     
  • Robert Dodier

    Robert Dodier - 2015-02-02

    OK by me to apply the patch suggested by Andrej V. Someone please go ahead.

     
  • Andrej Vodopivec

    • status: open --> closed
     
  • Andrej Vodopivec

    Committed the patch in [f7c388].

     

Log in to post a comment.