The questions that burns my lips are: How is it done? Is it
implementation dependant? Is it a mandatory feature of ANSI Common Lisp?
Curiously,
Nowhere man
--
nowhe...@levallois.eu.org
OpenPGP 0xD9D50D8A
> I've already read quite some times that one of the wonderful features of
> Lisp is the ability to debug an application that is running, by changing
> it's state and even definitions (macros, functions, objects and so on).
> It is a known anecdote, I think, that it has been done with the
> controlling system of a space device in orbit, from earth.
>
> The questions that burns my lips are: How is it done? Is it
> implementation dependant? Is it a mandatory feature of ANSI Common Lisp?
It is a mandatory feature of ANSI Common Lisp.
When you call a function, it goes thru the symbol, (unless the
function is declared inline).
You can try the following:
(defun f () (print 'Hi))
(defun strange-repl ()
(loop
(f)
(format t "STRANGE> ")
(finish-output)
(let ((form (read)))
(if (equalp form '(quit))
(return-from strange-repl)
(print (eval form))))))
(strange-repl)
Then, at the STRANGE> prompt, enter another definition for f, for example:
(defun f () (print 'Ho!) (terpri))
Note that if your application doesn't provide a "REPL", a way to read
and evaluate lisp forms, the lisp debugger normally does, so you only
have to break into the debugger to be able to modify the program.
Also note that you can change the function binding of the symbol whose
function is currently running, but this doesn't modify the function
currently running. If at the STRANGE> prompt you defined a new
STRANGE-REPL function, it wouldn't be enacted until you call it again.
--
__Pascal Bourguignon__ http://www.informatimago.com/
In deep sleep hear sound,
Cat vomit hairball somewhere.
Will find in morning.
A trivially redefinable REPL could use a recursive function:
(defun repl ()
(print (eval (read)))
(repl))
or the above STRANGE-REPL could be modified and reinvoked from the
STRANGE-REPL itself
STRANGE> (defun strange-repl () ...)
STRANGE-REPL
STRANGE> (strange-repl)
STRANGE>
although this would mean that when you (QUIT) from the nested REPL, you'd
end up in the original REPL.
Of course, depending upon what you're doing, not being able to replace the
fundamental REPL might not be a bad thing.
You Just Do It. For example:
SW> (defun test ()
(write-line "i'm a buggy version of test"))
test
SW> (defparameter *test-thread*
(withThread "test-thread"
(loop
(test)
(sleep 10))))
i'm a buggy version of test
i'm a buggy version of test
i'm a buggy version of test
...etc...
*test-thread*
SW> (defun test ()
(write-line "i'm a non-buggy version of test"))
style-warning: redefining test in DEFUN
test
i'm a non-buggy version of test
i'm a non-buggy version of test
i'm a non-buggy version of test
...etc...
--
mvh, Lars Rune Nøstdal
http://lars.nostdal.org/
I think you forgot about the bit in which you first get to a Lisp prompt
on a satellite a kabillion miles away.
kt
--
Cells: http://common-lisp.net/project/cells/
"I'll say I'm losing my grip, and it feels terrific."
-- Smiling husband to scowling wife, New Yorker cartoon
HOUSTON> (connect (find-satellite :distance +one-kabillion-miles+))
SW> ...
Right:
ssh la...@space-station.org
..
la...@space-station.org:-$ screen -r
Or stuff like Swank (in Slime) or detachtty would also work. Now the
really hard part I've not managed to solve is building a satelilite and
launching it. ... :)
Lars Rune Nřstdal wrote:
> Ken Tilton wrote:
>
You have longer arms than I do if you can reach the break key from here.
<I think that is part of the OP's confusion>
Hm - well, now I'm confused also. I've got a machine running a
Lisp-instance 100 miles away from here - but I can still "press the
break key" on that machine while at home using any of the methods
mentioned above.
Isn't both the question of changing stuff at runtime and doing it
remotely answered?
Does ssh "behave well" when network lag is in the order of minutes?
hours?
Ok it is a little further away than a satellite..
Evan
Hm, not really. It might be better to debug/simulate in a local IDE
then send a bigger chunk of Lisp-code - instead of keypress-events
moving around on some remote IDE - to the remote site that eventually
redefines stuff at runtime there. I'm not that familiar with Swank, but
I think it could handle something like this.
But I'm thinking the OP does not have problems with lag of several
minutes or hours.
I (loosely) meant I did not see where you explained to the OP all the
deets about Lisp being dynamic (so when a function gets entered after a
new version is compiled the new version gets run), nor that part of the
trick is getting to a prompt within the running Lisp process. The first
was implicit but unstated, the second -- well, you just offered a
console session with a thread spawned on the fly. Someone asking that
question might be accustomed to the C/C++ model where the compiler is
not around at runtime, and where a runtime is not malleable. etc etc.
Part of my questioning was in fact how to have the ability to connect to
the running Lisp, and if this ability is defined in the standard.
That is, without anything like swank running, if I have access to a
system where a Lisp application is running, can I debug it? Or do I have
to prepare the running application to be able to be remotely debugged,
and run something like swank?
To be clear, I think the word remotely is a bit misleading here. It
could be a Lisp application on the same host.
> But I'm thinking the OP does not have problems with lag of several
> minutes or hours.
Unless my provider finally sets up it's server room in space, yes.
Not exactly. Moreover, the sonde may be behind the Sun.
That's why you'd use the InterPlaNet instead of the Internet:
http://www.ipnsig.org/
Basically, the feeling of the communication is more like email (with
long and variable delays) than telnet or ssh.
--
__Pascal Bourguignon__ http://www.informatimago.com/
Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.
If you do not have anything like Swank or SSH running you cannot have
access to a system where the Lisp-application is running - and hence
you cannot debug it either. Remotely implies something like sockets and
this is not part of the standard - so you either need to do something
implementation dependant in your Lisp-program, or use external tools
like SSH/Swank/Slime to access it.
Using SSH or detachtty you do not need to do anything non-standard or
prepare something in your Lisp-code to access remotely and debug at
all. The Lisp-image/session does not know nor care where the code sent
to its REPL/etc. comes from.
*shrug* I dunno if I'm explaining this wrong or not explaining it at
all.
> To be clear, I think the word remotely is a bit misleading here. It
> could be a Lisp application on the same host.
What would be the difference? You can tell SSH or Swank to connect to
`localhost' if you want; Slime does this already (if I'm not mistaken).
I meant Lisp-image/session.
> If you do not have anything like Swank or SSH running you cannot have
> access to a system where the Lisp-application is running - and hence
> you cannot debug it either. Remotely implies something like sockets and
> this is not part of the standard - so you either need to do something
*terminal-io* bound to a serial port could do the job :-)
Petter
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Let's take an example. I've written this buggy application with
AllegroServe that just answer "Im' buggy." in HTML to any HTTP request.
It's run as a service by some script, e.g. /etc/init.d/buggy, which
essentially does `sbcl --load run-my-app.lisp`
Now I want to modify some global variable and a function... What should
I do?
You should have set up some way for you to inject commands into the
running Lisp. Several ways this could be accomplished are:
* Running the Lisp image in screen(1) or attachtty(1). You could then
attach to the running image's TTY and type commands to the listener
as usual.
* Load Swank in the image, which would allow you to connect to your
server with Slime (http://common-lisp.net/project/slime/). Change
definitions with Slime as usual.
* Roll your own method of injecting commands. There are myriad ways
this could be done.
Basically, a Lisp image is a very flexible system, but you need some way
to mutate it to change anything. (Think of what a security hole it
would be otherwise! :)
-bcd
--
*** Brian Downing <bdowning at lavos dot net>
:-) Hilarious!
On a side note, I had to look-up wikipedia for names for large numbers
http://en.wikipedia.org/wiki/Names_of_large_numbers
The largest of them all is a googolplex = ((10 ^ 10) ^ 100) = (1 x (10
^ 1000))
Whereas a kabillion is a very large amount i.e. untold billions
or it is Millions upon millions.
http://www.urbandictionary.com/define.php?term=kabillion
Alok.
This is interesting!
Consider the scenario where you have a micro Lisp system on a device,
akin to one of those java systems in smart cards and mobile phones. And
you also have a relevant interface in the device to interact with the
system. Would the device mutate the running Lisp image based on new
definitions?
Surely there must be some portions of the image marked as read-only, so
that next time the devices is turned on, it can start from an initial
state. And hence they cannot be altered. This means that the mutable
read-only portions will simply be masked by newer user defined
definitions, and they will be executed instead of original function
definitions from the read-only image.
For system architectures where such original Lisp image is on a faster
memory cache, and user memory is on slower add-on memory, this could
imply a slow execution time penalty for mutating functions defined in
the original image. This is on account of more time required to fetch
definitions not in the faster cache memory.
So in this case, which I think is a pretty general scenario, does it
help, given the hit on execution speed, in mutating the Lisp image?
Also, are there programmable devices with Lisp'ish system running in
them? (Any of them available cheaply?)
Alok.
> Let's take an example. I've written this buggy application with
> AllegroServe that just answer "Im' buggy." in HTML to any HTTP request.
> It's run as a service by some script, e.g. /etc/init.d/buggy, which
> essentially does `sbcl --load run-my-app.lisp`
Start you sbcl session under screen. I have something like (using
cmucl):
screen -D -m -S aserve /usr/bin/lisp \
-eval "(asdf:operate 'asdf:load-op :web)" \
-eval "(mp:make-process #'web:start-web-server)" \
-eval '(mp::startup-idle-and-top-level-loops)'
This starts my web server. Whenever I want to I can log on to the
machine using ssh and type "screen -r aserve" and be in the REPL. I
can then start the swank server:
(asdf:operate 'asdf:load-op :swank)
(swank:create-swank-server 4005)
Then I use M-x slime-connect in emacs to connect to the session. You
can of course add the two swank forms prefixed by -eval above to start
swank initially. You can also use ssh to connect to swank and tramp to
edit the files.
Yeah, I forgot to mention the remote-part; thanks for pointing that
out.
Both how people interpret and explain something is full of seemingly
random holes and missing parts that exists implicitly or obviously for
others; you never know either way around. But instead of guessing what
the OP is really after by filling in every possible single combination,
the OP will later just re-request like he does below or you did for him
then steer the discussion in the right direction and arrive at the goal
much faster. Somewhere at, in-between or beyond what Petter Gustad,
Brian Downing and I mention about screen, slime, swank, ssh and
possibly something that hasn't been mentioned yet - he will find what
he's looking for either in it or a direction to follow (docs and
man-pages) based on it.
I'm just lazy hoping c.l.l. will fill in the blanks. :)
Various implementations may provide something useful,
e.g., CMUCL provides MP::START-LISP-CONNECTION-LISTENER:
> (describe 'mp::start-lisp-connection-listener)
START-LISP-CONNECTION-LISTENER is an internal symbol in the
MULTIPROCESSING package.
...
Function arguments:
(&key (port 1025) (password (random (expt 2 24))))
Function documentation:
Create a Lisp connection listener, listening on a TCP port for new
connections and starting a new top-level loop for each. If a password
is not given then one will be generated and reported. A search is
performed for the first free port starting at the given port which
defaults to 1025.
...
> (mp::start-lisp-connection-listener :password "foobar")
#<Process Anonymous {489C2AB5}>
;;; Started lisp connection listener on port 1025 with password foobar
> (defun foo (x) (+ x 37))
FOO
>
Then in another window [note that the password is read with the
Lisp reader, so in this case we must type the string quotes, too]:
$ telnet localhost 1025
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Enter password: "foobar"
> (foo 10)
47
> ^]
telnet> q
Connection closed.
$
-Rob
-----
Rob Warnock <rp...@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
Thanks for the link ! very interesting and I wasn't aware of that :)
Evan
Which it perfectly did, BTW...
Remotely,
Great! That even made me know the -m and -s options of screen, BTW...
Combined with saving a core file after the loading of all required
packages, that makes a wonderfully easy way to start a debug-ready Lisp
application!
Gratefully,
Silly question, may be last blank: how do you do if the Lisp image is
running under Windows?
I'm fighting with Swank but I didn't manage to connect to it from a
Linux box to a Windows one. As there's nothing like SSH toward Windows
(XP, for what matters), I connect with Putty to the Linux box from
Windows, creating a remote port forwarding, and then start a swank
server. With Lispbox CLisp and ACL flavours, it didn't work (connection
closed unexpectedly, returned abnormally with error 256, IIRC).
So how are you guys doing to connect to a Lisp image on Windows?
Locally,
> Le Tue, 08 Aug 2006 01:48:25 -0700, Lars Rune Nøstdal a écrit :
>> I'm just lazy hoping c.l.l. will fill in the blanks. :)
>
> Silly question, may be last blank: how do you do if the Lisp image is
> running under Windows?
>
> I'm fighting with Swank but I didn't manage to connect to it from a
> Linux box to a Windows one. As there's nothing like SSH toward Windows
Install cygwin and launch sshd in cygwin.
> (XP, for what matters), I connect with Putty to the Linux box from
> Windows, creating a remote port forwarding, and then start a swank
> server.
The swank server could listen on a normal TCP/IP port. Insecure, but
you could protect it on a LAN not connected to the Internet (which you
should already have if you're running a Microsoft OS anyways).
> With Lispbox CLisp and ACL flavours, it didn't work (connection
> closed unexpectedly, returned abnormally with error 256, IIRC).
>
> So how are you guys doing to connect to a Lisp image on Windows?
>
> Locally,
> Nowhere man
> --
> nowhe...@levallois.eu.org
> OpenPGP 0xD9D50D8A
>
--
__Pascal Bourguignon__ http://www.informatimago.com/
"Logiciels libres : nourris au code source sans farine animale."
I find the latency in ssh sessions to my web server bad enough without
the added ~20 minute delay for a round trip to a space vehicle 100M
miles distant.
Of course NASA didn't have to go through all that. They just fixed
the bug in their test system on the ground and beemed it into space.
Then they crossed their fingers and held their breath.
--
The lithobraker. Zero distance stops at any speed.
This post uses 100% post consumer electrons and 100% virgin photons.
At 2.6 miles per minute, you don't really have time to get bored.
--- Pete Roehling on rec.motorcycles