emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problems with debug-on-entry in the Lisp debugger.


From: Lute Kamstra
Subject: Re: Problems with debug-on-entry in the Lisp debugger.
Date: Wed, 09 Mar 2005 11:14:49 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

Stefan Monnier <address@hidden> writes:

>> This gives a backtrace like this:
>
>> ------ Buffer: *Backtrace* ------ 
>> Debugger entered--entering a function:
>> * (lambda (var) (if (or inhibit-debug-on-entry debugger-jumping-flag) nil 
>> (debug ...)) (list (quote setq) var (list ... var)))(x)
>>   (inc x)
>>   (progn (setq x 0) (inc x))
>>   eval((progn (setq x 0) (inc x)))
>>   eval-last-sexp-1(nil)
>>   eval-last-sexp(nil)
>>   call-interactively(eval-last-sexp)
>> ------ Buffer: *Backtrace* ------ 
>
>> where you can see the debug-entry-code (if (or inhibit-debug-on-entry
>> debugger-jumping-flag) nil (debug ...)).  I would prefer to hide the
>> internals of the debugger from its users.
>
> debug.el already hides its internals.  See debugger-setup-buffer.
> It just has to be updated to hide this part of the internals.

In this case, hiding the internals is possible.  It will be clumsy
though.  You have to search for debug-entry-code as text, which can be
abbreviated like in "(if (or inhibit-debug-on-entry
debugger-jumping-flag) nil (debug ...))".  You probably can only do
that easily for a specific example of debug-entry-code.  So the next
time debug-entry-code is changed, debug.el breaks in yet another
place.  (Remember that when you introduced the (if ...) test in
debug-entry-code, debug.el already had to be changed in 3 defuns to
compensate for this?)  So debug.el will become more difficult to
maintain.

In the other case I mentioned, hiding the debugger's internals is not
possible.  When you encounter debug-entry-code while stepping with
`d', it will not be possible to hide this.  You could hide the code
visually by deleting it from the backtrace buffer, but then the user
would still have to press `d' a couple of times (seemingly without any
effect) to step through the debug-entry-code.

>> You proposed to change defun, defsubst, defalias and defmacro to
>> add debug-entry-code when their argument was in
>> debug-function-list.  That is a similarly big change.
>
> There's no need to do that.  The hooks are already present for
> defadvice, so we should simply use them.

Hmm, I'm don't see how you can use these hooks except by using
defadvice: they seem to be designed to handle only advice.  I'd have
to change Ffset to deal with debug-on-entry.  Am I missing something?

> Better yet, we should use defadvice directly:
>
>    (defadvice <FOO> (before debug-on-entry activate)
>      (if inhibit-debug-on-entry nil (debug 'debug)))
>
> This will properly survive function redefinitions.

It does survive function redefinition.  I think this solution is worse
than the problem it tries to solve, however.  The defadvice changes a
function definition quite a bit.  The hapless debugger user might not
recognize his own function anymore:

(defun fun () "Return one." 1)
(symbol-function 'fun)
  => (lambda nil "Return one." 1)
(defadvice fun (before debug-on-entry activate)
  (if inhibit-debug-on-entry nil (debug 'debug)))
(symbol-function 'fun)
  => (lambda nil "$ad-doc: fun$" 
       (let (ad-return-value) 
         (if inhibit-debug-on-entry 
             nil 
           (debug (quote debug))) 
         (setq ad-return-value (ad-Orig-fun)) 
         ad-return-value))

Stepping through this will cause some confusion, I think.  Can you
think of an easy way to hide the debugger's internals when you use
advice like this?

Lute.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]