Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 308 lines (233 sloc) 9.367 kb

trivial-dump-core is an MIT-licensed wrapper that provides a common interface between lisp implementations for the creation of lisp image files and executables.

Currently trivial-dump-core supports SBCL, Clozure CL and CLISP.

Installation

trivial-dump-core is available via quicklisp:

(ql:quickload "trivial-dump-core")

The source repository is at https://github.com/rolando2424/trivial-dump-core

Library functions

There are two main functions in trivial-dump-core:

  • dump-image
  • save-executable

dump-image

The dump-image function is used to freeze the state of your Lisp session and store it in an “image file.” You can then, at a later time, load that image file back into your Lisp implementation.

The dump-image function takes the path of the image file as its only argument.

save-executable

The save-executable function creates an executable file that includes the Lisp image (you can distribute it as-is without needing to install the Lisp implementation on the target machine). Some implementations (Clozure, SBCL) will exit after this function is called.

The save-executable function takes 3 arguments:

  • filename - Path of the executable file
  • init-function - Zero-argument function object that acts as the entry point to your executable (the equivalent of main() in C).

Examples

dump-image

Let’s open up, for example, Clozure CL:

rolando@rolando-desktop:~$ ccl
Welcome to Clozure Common Lisp Version 1.7-r14925M  (LinuxX8632)!
?

Now we load trivial-dump-core (we assume you have quicklisp installed already).

? (ql:quickload "trivial-dump-core")
To load "trivial-dump-core":
  Load 1 ASDF system:
    trivial-dump-core
; Loading "trivial-dump-core"
[package trivial-dump-core]
(TRIVIAL-DUMP-CORE)
?

Let’s define a new function:

? (defun hello-world ()
    (format t "Hello, World!"))
HELLO-WORLD
?

So now this lisp interpreter has a function called hello-world. Let’s save dump the interpreter state to a file called “my-core.ccl”:

? (trivial-dump-core:dump-image "my-core.ccl")
To run the image, use the following command in the terminal:
ccl -I my-core.ccl
rolando@rolando-desktop:~$

You’ll notice that we’re back in the command-line. This behaviour is implementation-dependent. For example, in CLISP you stay in the REPL even after creating an image.

Also notice the command ccl -I my-core.ccl appeared. That’s the command you have to type in the command-line to make ccl open the image you just created. Even though the specific flags you need to use change from implementation to implementation, trivial-dump-core will always show you the command you need to use to open back the image.

So let’s open it.

rolando@rolando-desktop:~$ ccl -I my-core.ccl
Welcome to Clozure Common Lisp Version 1.7-r14925M  (LinuxX8632)!
?

So far, everything is the same as usual right? However, before creating this image, we defined a new function called hello-world. This function should still exist, even though we closed the lisp interpreter.

? (hello-world)
Hello, World!
NIL
?

As you can see, the function still exists.

Currently, you can use the dump-image function in SBCL, CLISP and Clozure CL.

Keep in mind that you can’t open an image using a implementation that’s different from the one that created it, ie. you can’t create an image in SBCL and then open it in CLISP.

save-executable

This time, let’s open up SBCL.

rolando@rolando-desktop:~$ sbcl
This is SBCL 1.0.55, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
*

As before, we’ll need to load trivial-dump-core using quicklisp.

* (ql:quickload 'trivial-dump-core)
To load "trivial-dump-core":
  Load 1 ASDF system:
    trivial-dump-core
; Loading "trivial-dump-core"
[package trivial-dump-core]
(TRIVIAL-DUMP-CORE)
*

Let’s define a new function.

* (defun hello-world ()
    (format t "Hello, World!~%"))

HELLO-WORLD
*

Finally, we create an executable with the name “sbcl-hello-world” using the save-executable function, using the hello-world has the entry point.

* (trivial-dump-core:save-executable "sbcl-hello-world" #'hello-world)
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into sbcl-hello-world:
writing 3512 bytes from the read-only space at 0x01000000
writing 2224 bytes from the static space at 0x01100000
writing 32231424 bytes from the dynamic space at 0x09000000
done]
rolando@rolando-desktop:~$

As it already happened with Clozure CL during the dump-image example, what happens after you call save-executable is implementation-dependent. In this case, the lisp interpreter closed and we are back in the command-line.

However, there’s now a new executable file in the folder. Let’s run it.

rolando@rolando-desktop:~$ ./sbcl-hello-world
Hello, World!
rolando@rolando-desktop:~$

SBCL and Slime

There a problem with saving core images in SBCL when it’s running more than one thread, as is the case with the SBCL+Slime combination.

So to use trivial-dump-core with SBCL running with a Slime prompt, the process is a little different.

You call the functions dump-image and save-executable as usual, but those functions instead of working the normal way, they print out a sexp that you need to evaluate in the *inferior-lisp* buffer.

Example

Inside emacs press C-u M-x slime RET sbcl RET.

When the prompt opens, load trivial-dump-core as normal.

CL-USER> (ql:quickload 'trivial-dump-core)
To load "trivial-dump-core":
  Load 1 ASDF system:
    trivial-dump-core
; Loading "trivial-dump-core"

(TRIVIAL-DUMP-CORE)
CL-USER>

Let’s create a new image using dump-image.

CL-USER> (trivial-dump-core:dump-image "sbcl-slime")
Cannot dump an sbcl image from inside Slime.

Please go to the *inferior-lisp* buffer in emacs and run the following code:

(trivial-dump-core::sbcl-dump-image-slime "sbcl-slime")
NIL
CL-USER>

Notice the sexp in the message. Copy it into emacs’ kill-ring and open the *inferior-lisp* buffer using C-x b *inferior-lisp* RET and paste the sexp there.

* (trivial-dump-core::sbcl-dump-image-slime "sbcl-slime")
;; swank:close-connection: NIL
To run the image, use the following command in the terminal:
sbcl --core sbcl-slime
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into sbcl-slime:
writing 3512 bytes from the read-only space at 0x01000000
writing 2224 bytes from the static space at 0x01100000
writing 35590144 bytes from the dynamic space at 0x09000000
done]

Process inferior-lisp finished

The end result is a core file similar to one created in the command-line.

The same thing happens when you try to use save-executable with SBCL in Slime.

CL-USER> (ql:quickload 'trivial-dump-core)
To load "trivial-dump-core":
  Load 1 ASDF system:
    trivial-dump-core
; Loading "trivial-dump-core"

(TRIVIAL-DUMP-CORE)
CL-USER> (trivial-dump-core:save-executable "sbcl-exec-slime" #'(lambda () (format t "Hello, World!")))
Cannot run save an sbcl image from inside Slime.

Please go to the *inferior-lisp* buffer in emacs and run the following code:

(trivial-dump-core::sbcl-save-slime-and-die "sbcl-exec-slime" #'(LAMBDA ()
                                                                  (FORMAT
                                                                   T
                                                                   "Hello, World!")))
NIL
CL-USER>

Copy and paste the form into the *inferior-lisp* buffer to create an executable.

* (trivial-dump-core::sbcl-save-slime-and-die "sbcl-exec-slime" #'(LAMBDA ()
                                                                  (FORMAT
                                                                   T
                                                                   "Hello, World!")))
;; swank:close-connection: NIL
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into sbcl-exec-slime:
writing 3512 bytes from the read-only space at 0x01000000
writing 2224 bytes from the static space at 0x01100000
writing 35340288 bytes from the dynamic space at 0x09000000
done]

Process inferior-lisp finished
Something went wrong with that request. Please try again.