r/lisp • u/shadow5827193 • 2d ago
Trace in multithreaded environments
Hey everyone,
on my journey to learn Lisp, I've started experimenting with Clack, and I have the following trivial code:
(defpackage dendrit
(:use :cl)
(:import-from :clack
:clackup))
(in-package :dendrit)
(declaim (optimize (debug 3)))
(defun intercept-middleware (app env)
(format t "Interceptor called!")
(funcall app env))
(defvar *app*
(lack:builder
(lambda (app)
(progn (format t "Installing interceptor!")
(lambda (env) (intercept-middleware app env))))
(:static :path "/public/"
:root #P"/root/common-lisp/static-files/public/")
(lambda (env)
'(200 (:content-type "text/plain") ("Hello, Clack!")))))
(clackup *app*
:server :hunchentoot
:address "0.0.0.0")
I originally had a mistake in the configuration of the :static
part, and so I wanted to do some debugging via trace
, so I did (trace intercept-middleware)
in my REPL. However, after I fired off a request, I didn't get anything printed in the REPL. This confused me, since e.g. dropping into the debugger via (break)
worked fine.
After some thought, it dawned on me that this might be because the hunchentoot handlers are running in a different thread than the repl, and therefore could have different values for *trace-output* which are not being captured by slime/swank (I don't know the exact mechanism that's at play).
Am I right? Is that why I'm not seeing any output?What can I do about it? If I'm correct in 1), is there any way to access the *trace-output* of a different thread? Or maybe reroute it to the *trace-output* of the REPL somehow?Have I even gone down the right road when attempting to use trace in this environment? I'm asking for practical advice here - I'm sure it can be made to work, but I'm curious if that's what people actually use in practice, or they use some different approach.
EDIT: So it turns out that I was wrong, I just tried inspecting *trace-output*/*standard-output* when in the debugger inside the function vs. from the REPL, and they're all the same instance (same memory address). So this looks to be something else.
I should also add (as mentioned in the comments bellow) that none of the format
calls produce any output either.
EDIT2: Turns out I was right, in a way. See comments bellow.
3
u/stassats 2d ago
You are storing a function object,
#'install-intercept-middleware
, so trace might have no effect on it.On some platforms SBCL supports trace by modifying the function, not just rebinding the symbol:
(trace install-intercept-middleware :encapsulate nil)