I'm trying to run a program under CCL, so that when the program finishes running for any reason, it should exit back to the operating system. Currently using this command line (on Windows):
\ccl\wx86cl -l test.lisp -e (quit)
This exits when the program successfully runs to normal completion, but if there is an error e.g. out of memory, it ends up in the debugger. How do you tell Clozure to also exit when there is an error?
Not only you want to catch all errors, but you also want to prevent going into the debugger when INVOKE-DEBUGGER is called. You can set *DEBUGGER-HOOK* to a function that quits on unhandled errors.
$ ./bin/ccl/lx86cl64
Clozure Common Lisp Version 1.11.5/v1.11.5 (LinuxX8664)
For more information about CCL, please see http://ccl.clozure.com.
CCL is free software. It is distributed under the terms of the Apache
Licence, Version 2.0.
? *debugger-hook*
NIL
? (setf *debugger-hook*
(lambda (error hook)
(declare (ignore hook))
(format *error-output* "Crash: ~a" error)
(quit)))
#<Anonymous Function #x302000998C3F>
Now, test it with an unhandled error:
? (error "Oh no")
Crash: Oh no
Then, you are back to the shell.
Notice that BREAK always enters the debugger, because it binds *debugger-hook* to NIL (this is on purpose, for debugging).
Related
I'm trying to run an executable with an Hunchentoot server and I'm getting (after an unusual high CPU usage):
<INFO> [17:55:14] weblocks/server server.lisp (start) -
Starting weblocks WEBLOCKS/SERVER::PORT: 40001
WEBLOCKS/SERVER::SERVER-TYPE: :HUNCHENTOOT DEBUG: T
debugger invoked on a SB-INT:EXTENSION-FAILURE in thread
#<THREAD "main thread" RUNNING {1008C1EA13}>:
Don't know how to REQUIRE sb-cltl2.
Do you have any idea what's going on ? It works correctly on Slime where I use the start function.
(sbcl manual: http://www.sbcl.org/manual/#Customization-Hooks-for-Users)
In the main entry point, I try to capture the running thread so that I keep the server running on the foreground (my notes). This pattern worked with another clack-based web framework.
(defun start ()
(weblocks/debug:on)
(weblocks/server:start :port *port*))
(defun main ()
(defvar *port* (find-port:find-port))
(start)
(handler-case (bt:join-thread (find-if (lambda (th)
(search "hunchentoot" (bt:thread-name th)))
(bt:all-threads)))
(#+sbcl sb-sys:interactive-interrupt
#+ccl ccl:interrupt-signal-condition
#+clisp system::simple-interrupt-condition
#+ecl ext:interactive-interrupt
#+allegro excl:interrupt-signal
() (progn
(format *error-output* "Aborting.~&")
(uiop:quit 1))
;; for others, unhandled errors (we might want to do the same).
(error (c) (format t "Woops, an unknown error occured:~&~a~&" c)))))
Or any indication of what could be the cause ?
Thanks again.
(I'm using 40ants' weblocks:reblocks branch)
SBCL Debian 1.2.4
edit I tried
export SBCL_HOME=/usr/local/lib/sbcl/
I build with
build:
$(LISP) --quit \
--eval '(ql:quickload "foo")' \
--eval '(require :sb-cltl2)' \
--eval '(asdf:make :foo)'
=>
fatal error encountered in SBCL pid 25248(tid 140737353910016):
can't load .core for different runtime, sorry
Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb>
The following environment failed:
export SBCL_HOME=/usr/local/lib/sbcl/
The error message tells us the following:
can't load .core for different runtime, sorry
Apparently the SBCL you ran used the given SBCL_HOME to find its core file, but failed due to the core being generated by different version SBCL.
A quick look at SBCL's source (starting from require) shows that the underlying function #'SB-INT:SBCL-HOMEDIR-PATHNAME is called to determine the installation path.
It looks like the one installed from the Debian package was installed in /usr/lib/sbcl/. The core file was easily found when starting Slime. You also had another version of SBCL in ~/.roswell/, but I guess you also ran ros install which installed it under /usr/local/lib/sbcl (/usr/local/ is for software that is not managed by the system).
Starting the roswell one when setting SBCL_HOME to the directory of the Debian one provoked the error about the incompatible core file (I guess).
What remains suprising is that (SB-INT:SBCL-HOMEDIR-PATHNAME) returns nil when starting your main function.
If I want to create a Lisp-image of my program, how do I do it properly? Are there any prerequisites? And doesn't it play nicely with QUICKLISP?
Right now, if I start SBCL (with just QUICKLISP pre-loaded) and save the image:
(save-lisp-and-die "core")
And then try to start SBCL again with this image
sbcl --core core
And then try to do:
(ql:quickload :cl-yaclyaml)
I get the following:
To load "cl-yaclyaml":
Load 1 ASDF system:
cl-yaclyaml
; Loading "cl-yaclyaml"
.......
debugger invoked on a SB-INT:EXTENSION-FAILURE in thread
#<THREAD "main thread" RUNNING {100322C613}>:
Don't know how to REQUIRE sb-sprof.
See also:
The SBCL Manual, Variable *MODULE-PROVIDER-FUNCTIONS*
The SBCL Manual, Function REQUIRE
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [RETRY ] Retry completing load for #<REQUIRE-SYSTEM "sb-sprof">.
1: [ACCEPT ] Continue, treating completing load for #<REQUIRE-SYSTEM "sb-sprof"> as having been successful.
2: Retry ASDF operation.
3: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the configuration.
4: [ABORT ] Give up on "cl-yaclyaml"
5: Exit debugger, returning to top level.
(SB-IMPL::REQUIRE-ERROR "Don't know how to ~S ~A." REQUIRE "sb-sprof")
0]
Alternatively, if I try:
(require 'sb-sprof)
when sbcl is started with saved core, I get the same error. If sbcl is started just as sbcl there is no error reported.
In fact, pre-loading QUICKLISP is not a problem: the same problem happens if sbcl is called initially with sbcl --no-userinit --no-sysinit.
Am I doing it wrong?
PS. If I use roswell, ros -L sbcl-bin -m core run somehow doesn't pick up the image (tested by declaring variable *A* before saving and not seeing it once restarted).
PS2. So far what it looks like is that sbcl does not provide extension modules (SB-SPROF, SB-POSIX, etc.) unless they are explicitly required prior saving the image.
Thanks for the help from #jkiiski here is the full explanation and solution:
SBCL uses extra modules (SB-SPROF, SB-POSIX and others) that are not always loaded into the image. These module reside in contrib directory located either where SBCL_HOME environment variable pointing (if it is set) or where the image resides (for example, in /usr/local/lib/sbcl/).
When an image is saved in another location and if SBCL_HOME is not set, SBCL won't be able to find contrib, hence the errors that I saw.
Setting SBCL_HOME to point to contrib location (or copying contrib to image location or new image to contrib location) solves the problem.
Finally, about roswell: roswell parameter -m searches for images in a specific location. For SBCL (sbcl-bin) it would be something like ~/.roswell/impls/x86-64/linux/sbcl-bin/1.3.7/dump/. Secondly, the image name for SBCL must have the form <name>.core. And to start it, use: ros -m <name> -L sbcl-bin run. (Quick edit: better use ros dump for saving images using roswell as it was pointed out to me)
If you want to create executables, you could try the following:
(sb-ext:save-lisp-and-die
"core"
:compression t
;; this is the main function:
:toplevel (lambda ()
(print "hell world")
0)
:executable t)
With this you should be able to call QUICKLOAD as you wish. Maybe you want to checkout my extension to CL-PROJECT for creating executables: https://github.com/ritschmaster/cl-project
I started playing with SBCL Common Lisp and want to develop a small web application using Hunchentoot. For easy deployment I planned to save everything in a binary using sb-ext:save-lisp-and-die as I can live with the big output size.
For the executable you need to supply a toplevel function. The problem is that the program exits when the toplevel function returns. I tried to start Hunchentoot from the executable, but the program ended after two seconds.
How can I wait until Hunchentoot was shut down (from inside a request) before stopping the program? Can I do something like join the Hunchentoot acceptor thread? Or can I even include the REPL into the executable to be able to do live debugging?
(ql:quickload :hunchentoot)
(use-package :hunchentoot)
(defun main ()
(hunchentoot:start-server :port 8082)
(sb-thread:join-thread (find-if
(lambda (th)
(string= (sb-thread:thread-name th) "hunchentoot-listener-1"))
(sb-thread:list-all-threads))))
No explicit code is required to give you access to a REPL if you keep a terminal open (perhaps via GNU Screen). Send Ctrl+C to the terminal to break into the debugger.
;;; I simply use sleep to yield the main thread.
;;; To start the server while developing I use
;;; start-server. For deployment I use the main
;;; function.
(defun start-server ()
(hunchentoot:start
(make-instance 'hunchentoot:easy-acceptor :port 8000)))
(defun main()
(start-server)
(sleep #xffffffff))
Some days ago I updated SBCL to 1.2.1 and I thought it couldn't hurt to update the quick lisp dist/client as well.
WRONG!
After firing up slime in Emacs, I got this error:
; caught ERROR:
; READ error during COMPILE-FILE:
;
; Symbol "CODE-TRACE-TABLE-OFFSET-SLOT" not found in the SB-VM package.
;
; Line: 1507, Column: 70, File-Position: 60197
;
; Stream: #<SB-SYS:FD-STREAM
; for "file /Users/fyi/quicklisp/dists/quicklisp/software/slime-2.7/swank-sbcl.lisp"
; {1008B07E43}>
;
; compilation unit aborted
; caught 1 fatal ERROR condition
; caught 1 ERROR condition
; printed 1 note
;;
;; Error while compiling /Users/fyi/quicklisp/dists/quicklisp/software/slime-2.7/swank-sbcl.lisp:
;; COMPILE-FILE returned NIL.
;; Aborting.
If you're using the quicklisp-slime-helper, so as I, the path to slime comes form the ~/quicklisp/dists/quicklisp/installed/systems/swank.txt file. Slime 2.8 should fix that error, but there is no quicklisp distribution that contains slime 2.8.
Coming down to my actual question. Is there a way to specify a library location outside of a quicklisp distribution? Or will I have to wait unit the next distribution has been made available and is there a guaranty a library will be updated in the next distribution?
I am sure I'm missing something, but the whole distribution stuff seems to me more of a hindrance than a help.
The next Quicklisp dist update is coming July 12 or 13. It will include a new SLIME that is compatible with SBCL 1.2.1. In the meantime, the easiest fix is to install SBCL 1.2.0.
Another option is to comment out the quicklisp-slime-helper lines in ~/.emacs and install slime according to its own procedure.
I am working some lisp code on sbcl in order to run function in mode daemon.
The problem is when I use the function sb-thred:make-thread, for instance as follow:
(sb-thread:make-thread (lambda () (progn (sleep 1) (when t (print "background action")))))
I get the following error message:
Not supported in unithread builds. [Condition of type SIMPLE-ERROR]
What is wrong ? ... thanks for help.
SBCL has threads disabled by default on Mac OS X. To check if SBCL is build with threads run in the repl
(member :sb-thread *features*)
If not, compile it from source (using your current SBCL). From the INSTALL
sh make.sh --with-sb-thread