Print debugging is great. A carefully placed print statement is something many great programmers swear by [1], despite the existence of "sophisticated" debuggers (see footnote in OP). This is a complement to this when you want to play around with the data directly.
> Not only def's are abused contrary to their intended use, they are difficult to distinguish from legitimate defs, and thus some may (and will!) slip away into the wild.
Never been an issue for me. It's just an extension and morphing of playing around with data in a standalone REPL. The temporary defs are never used in actual code logic, the prefix character makes it clear it is purely for exploration. Is it a dirty hack? Yes, but one might argue that's partly what Lisp is too: The most intelligent way to misuse a computer - Dijkstra (paraphrasing) Lisp
Some unsolicited feedback: you might want to consider that there is more than one way to skin a cat. If you want to understand the trade-offs of solutions people find, you might find it useful to not dismiss solutions outright. Especially something as universally useful like print debugging, considering how many people use it. Instead, a more useful question to ask yourself is: why do experienced programmers use print debugging when they are aware of the existence of debuggers? That might expand your worldview, as opposed to categorizing these people as "doing it wrong". See Worse is Better etc.
1: From this lovely quote by Brian Kernighan: The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.
I think a lot of the constraints can be relaxed during the development phase.
For example a dynamic variable could be accessible in the debug repl:
CL-USER 56 > (defvar *bar*)
*BAR*
CL-USER 57 > (defun foo (baz)
(let ((*bar* (* 1000 baz)))
(break)
*bar*))
FOO
CL-USER 58 > (foo 5)
Break.
1 (continue) Return from break.
2 (abort) Return to level 0.
3 Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
CL-USER 59 : 1 > *bar*
5000
The value of a lexical variable can be retrieved. CL-USER 60 : 1 > :l baz
Value of BAZ is:
5
CL-USER 61 : 1 > *
5
In something like McCLIM or SLIME I would print the object to a listener and the window system remembers the value.In some other Lisp I would call (inspect foo) instead of (print foo) and the inspected values would be available in a stack of inspectors. Alternatively I would trace the functions, and the tracer would record the passed and returned objects.