Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to guarantee a clean exit from sbcl

I am calling my common-lisp program via a shellscript which calls sbcl with the necessary parameters and I have to guarantee that anyhow the actual program finishes the call will end clean with some/none output.

My current solution looks like this:

sbcl --eval "(unwind-protect 
               (handler-case 
                   (progn 
                      (declaim #+sbcl(sb-ext:muffle-conditions style-warning))
                      (let ((*standard-output* (make-broadcast-stream)))
                        (ql:quickload \"module\"))
                   (eval (read-from-string \"(package:start)\"))) ;this starts the program
                  (error (err) 
                                (FORMAT t \"Something went really wrong:~a~%\" err) 
                                (sb-ext:exit))) 
              (sb-ext:exit))"

But in the following two szenarios it wont work:

sbcl --eval "(unwind-protect 
                 (handler-case 
                    (progn 
                       (define-condition bad () ())
                       (error 'bad)) 
                   (error (err) 
                                 (FORMAT t \"Something went really wrong:~a~%\" err) 
                                 (sb-ext:exit))) 
                 (sb-ext:exit))"

sbcl --eval "(unwind-protect 
                 (handler-case 
                     (progn 
                       (labels ((rek () (rek)))
                         (rek)))
                   (error (err) 
                                 (FORMAT t \"Something went really wrong:~a~%\" err) 
                                 (sb-ext:exit))) 
               (sb-ext:exit))"

I am now wondering if there is another solution which will catch ANY possible outcome of a called program and will ensure that the sbcl call will exit clean?

For the first scenario a general catch which does not specify what to catch, would probably do the deal. The second scenario has to be able to cope with bugs/errors which would result in the low-level-debuger being called.

like image 875
Sim Avatar asked Dec 21 '12 02:12

Sim


1 Answers

The --non-interactive switch will ensure that SBCL never enters the debugger or the REPL. It's similar to passing --disable-debugger and using --eval "(sb-ext:quit)". You can also customize sb-ext:*invoke-debugger-hook* if you don't want it to print a backtrace in the event of an error.

like image 99
Xach Avatar answered Oct 28 '22 02:10

Xach