我想用sbcl + hunchentoot创建一个http服务器。只要我在REPL中测试代码或直接运行脚本文件,一切都会顺利进行,但当我将核心保存为可执行文件时,每当我试图访问hunchentoot服务器的网页时,服务器就会崩溃。
测试代码相当简单,在server.lisp文件中,我们有:
#!/usr/local/bin/sbcl --script
(require :asdf)
(asdf:load-system :hunchentoot)
(defpackage :http-server
(:use :cl :hunchentoot))
(in-package :http-server)
(defvar *my-acceptor* (make-instance 'easy-acceptor :port 6161))
(defun main ()
(format t "Starting http server on port ~a~%" (acceptor-port *my-acceptor*))
(start *my-acceptor*)
(handler-case
(loop do (sleep 1000))
(condition () nil)))
(defun hello ()
(format nil "Hello, it works!"))
(push
(create-prefix-dispatcher "/hello.html" #'hello)
*dispatch-table*)
;; (sb-ext:save-lisp-and-die "http-server" :toplevel 'main :executable t)
(main)现在,如果我直接在终端上运行脚本,它的工作就完美无缺了。可以访问hello.html页面。然后我将最后两行更改为
(sb-ext:save-lisp-and-die "http-server" :toplevel 'main :executable t)
;; (main)我的意图是再次运行脚本,它将生成一个可执行文件http-server。,那我们就有问题了,。
我通过执行可执行文件http-server启动服务器,每次访问"http://127.0.0.1:6161/hello.html"“时,http-服务器进程就会崩溃,其中包含以下错误消息:
Starting http server on port 6161
CORRUPTION WARNING in SBCL pid 206086 tid 206091:
Memory fault at 0x7f9c7c58b000 (pc=0x53617132 [code 0x53616f20+0x212 ID 0x43a3], fp=0x7f696af2dbc0, sp=0x7f696af2db68) tid 206091
The integrity of this image is possibly compromised.
Continuing with fingers crossed.
CORRUPTION WARNING in SBCL pid 206086 tid 206091:
Memory fault at 0x7f9c7c58b000 (pc=0x53617c03 [code 0x53617a30+0x1D3 ID 0x43a5], fp=0x7f696af2dc40, sp=0x7f696af2dc18) tid 206091
The integrity of this image is possibly compromised.
Continuing with fingers crossed.有人能帮我查一下这是怎么回事吗?在REPL中或作为脚本运行相同的代码是不合理的,但是不能作为可执行文件工作。我生成可执行文件的方式有问题吗?
我的操作系统是LinuxMint 21。sbcl版本为2.2.8,hunchentoot版本为1.3.0。
非常感谢!
一些更新这个问题可以很容易地用最新的SBCL2.2.9+最新的hunchentoot1.3.0复制。在准备充分的环境中,只需运行脚本并生成可执行文件,您就可以进行调查了。由于SBCL和hunchentoot在社区中都很受欢迎,所以我们对这个问题没有一个解释。
另一个更新--我改变了生成可执行文件的方法,这次工作了。事实证明,我必须从REPL创建可执行文件,而不是使用上面的脚本文件。我认为它可能与shebang行有关,"--script“将禁用ldb调试器,这可能不是生成可执行文件的理想方法。我们已经吸取了教训。
最终更新实际上我们仍然可以从脚本文件生成可执行文件,只要我们不使用“--脚本”选项。例如,将这些行放在脚本文件的开头,它就能工作(请记住从原始脚本中删除最后两行):
#|
# This is the correct way to generate the executable from this script file
sbcl --noinform --no-userinit --load "$0" --eval $'(sb-ext:save-lisp-and-die "http-server" :toplevel \'http-server::main :executable t)'
exit 0
|#发布于 2022-10-14 09:20:30
你可以用罗斯威尔。
安装罗斯韦尔如下:https://towardsdatascience.com/how-to-set-up-common-lisp-ide-in-2021-5be70d88975b (我是本文作者)。
在其中生成一个文件夹service和cd service。
我将您的脚本放入文件中:service.lisp
(ql:quickload :hunchentoot)
(defpackage :http-server
(:use :cl :hunchentoot))
(in-package :http-server)
(defvar *my-acceptor* (make-instance 'easy-acceptor :port 6161))
(defun main ()
(format t "Starting http server on port ~a~%" (acceptor-port *my-acceptor*))
(start *my-acceptor*)
(handler-case
(loop do (sleep 1000))
(condition () nil)))
(defun hello ()
(format nil "Hello, it works!"))
(push
(create-prefix-dispatcher "/hello.html" #'hello)
*dispatch-table*)
;; (sb-ext:save-lisp-and-die "http-server" :toplevel 'main :executable t)
(main)然后,我跑
$ ros init service它生成一个文件service.ros,该文件的内容为:
#!/bin/sh
#|-*- mode:lisp -*-|#
#|
exec ros -Q -- $0 "$@"
|#
(progn ;;init forms
(ros:ensure-asdf)
#+quicklisp(ql:quickload '() :silent t)
)
(defpackage :ros.script.service.3874727090
(:use :cl))
(in-package :ros.script.service.3874727090)
(defun main (&rest argv)
(declare (ignorable argv))
(load "service.lisp")
(main))
;;; vim: set ft=lisp lisp:然后,您必须将脚本安装到roswell中:
$ ros install service.ros它将显示出一条道路。就我而言,就像:~/.roswell/bin/service。已经有一个名为service的linux程序。所以我化名为:$ alias serveit="~/.roswell/bin/service"
现在我可以开火了:$ serveit
serveit
To load "hunchentoot":
Load 1 ASDF system:
hunchentoot
; Loading "hunchentoot"
....
Starting http server on port 6161这里解释了罗斯韦尔脚本:https://roswell.github.io/Roswell-as-a-Scripting-Environment.html
https://stackoverflow.com/questions/74054993
复制相似问题