Hello,
I just discovered, by accident, another way CMUCL's GC went
into an
infinite loop. I am not sure whether its related to the
previous problem
(1K socket connections). But here goes (Note: I am using
CMUCL 19c, TBNL) -
Recently I added a piece of code to our website which makes
an HTTP post
request to another machine. However, the IP address of that
machine was
*not* accessible at the time. And what happened was that our
website
became unresponsive. When I connected to the running lisp
and tried to
evaluate any form, nothing was returned. Then I pressed
Ctrl-C, and got
the following message in the debugger, and GC went into an
infinite loop:
Interrupted at #xFFFFE40E.
[Condition of type SIMPLE-CONDITION]
Restarts:
0: [CONTINUE] Return from BREAK.
1: [DESTROY ] Destroy the process
Debug (type H for help)
(UNIX::SIGINT-HANDLER #<unused-arg>
#<unused-arg> #.(SYSTEM:INT-SAP
#x3FFFC8D8))
Source: Error finding source:
Error in function DEBUG::GET-FILE-TOP-LEVEL-FORM: Source
file no longer
exists:
target:code/signal.lisp.
0]
; [GC threshold exceeded with 12,532,272 bytes in use.
Commencing GC.]
; [GC completed with 685,144 bytes retained and 11,847,128
bytes freed.]
; [GC will next occur when at least 12,685,144 bytes are in
use.]
; [GC threshold exceeded with 12,698,704 bytes in use.
Commencing GC.]
; [GC completed with 695,208 bytes retained and 12,003,496
bytes freed.]
; [GC will next occur when at least 12,695,208 bytes are in
use.]
; [GC threshold exceeded with 12,708,768 bytes in use.
Commencing GC.]
; [GC completed with 713,464 bytes retained and 11,995,304
bytes freed.]
.
.
.
On entering option 1, I can usually get out of this loop,
but then again
no Lisp forms were evaluated. I used the following modified
version of
trivial-http:http-post to send the request -
(defun http-post (url content-type content &key (timeout
120))
(let* ((host (url-host url))
(port (url-port url))
(stream (open-stream host port)))
(unwind-protect
(mp:with-timeout (timeout (error "Timeout
occurred. Current
timeout value - ~a sec" timeout))
(format stream "POST ~A HTTP/1.0~AHost:
~A~AUser-Agent:
Trivial HTTP for Common Lisp~AContent-Type:
~A~AContent-Length: ~D~A~A~A"
url +crlf+ host +crlf+ +crlf+
content-type +crlf+
(length content) +crlf+ +crlf+ content)
(force-output stream)
(response-read-code stream)
(response-read-headers stream)
(with-output-to-string (s)
(loop for line = (copy-seq (read-line stream
nil nil))
while line do (write-string line s))))
(when stream
(close stream)))))
I am using it this way - I create a new process (using
mp:make-process),
and call http-post from that process -
(defun send-other-request (content)
(mp:make-process (lambda ()
(handler-case (thttp:http-post
*remote-listener-url*
"application/x-www-form-urlencoded" content)
(error () nil)))))
send-other-request is called by one of the (URL) handler
functions in TBNL.
Everything is ok when the remote machine is accessible. It
only happens
when its not. Any pointers on why its happening?
Thanks,
Chaitanya
|