unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* edebug question - context of calling function
@ 2003-10-15  7:18 David Vanderschel
       [not found] ` <mailman.1841.1066353965.21628.help-gnu-emacs@gnu.org>
  2003-10-17 18:35 ` jan
  0 siblings, 2 replies; 9+ messages in thread
From: David Vanderschel @ 2003-10-15  7:18 UTC (permalink / raw)


I sometimes put a source breakpoint in my code to
catch a particular error condition.  When such a
conditional breakpoint fires, the actual problem,
though recognized in the called function, is often
attributable to the calling function.  What I want to
do then is to look around at the state of the calling
function at the time it called the function which
invoked edebug.  I can instrument the calling
function; but, when in the debugger, I cannot see how
to pop the context stack so that I can look around at
the variables in the calling program.  What am I
missing?

Thanks,
  David V.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: edebug question - context of calling function
       [not found] ` <mailman.1841.1066353965.21628.help-gnu-emacs@gnu.org>
@ 2003-10-17  2:19   ` David Vanderschel
  2003-10-18 19:59     ` jan
       [not found]     ` <mailman.1915.1066445382.21628.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 9+ messages in thread
From: David Vanderschel @ 2003-10-17  2:19 UTC (permalink / raw)


"jan" <janmar@iprimus.com.au> wrote in message
news:<mailman.1841.1066353965.21628.help-gnu-emacs@gnu.org>...
> "David Vanderschel" <DJV1@Austin.RR.com> writes:

> > I sometimes put a source breakpoint in my code to catch a particular
> > error condition.  When such a conditional breakpoint fires, the
> > actual problem, though recognized in the called function, is often
> > attributable to the calling function.  What I want to do then is to
> > look around at the state of the calling function at the time it
> > called the function which invoked edebug.  I can instrument the
> > calling function; but, when in the debugger, I cannot see how to pop
> > the context stack so that I can look around at the variables in the
> > calling program.  What am I missing?

> If I understand you correctly, you want to walk up the stack and look
> at the local variable in the functions along the way. I had a quick
> look and both edebug and the standard emacs debugger seem to be
> missing this feature. However, it may not be necessary because elisp
> is a dynamically scoped language, for example:

I think you do understand me correctly.
Unfortunately, I often reuse the same local variables
(eg., i, j, x, ...).  I was also interested in the
calling context in the sense of "Among multiple
possible invocations in the calling program, which
invocation of of the function which noticed the
condition caused this break."

I guess you are correct that I have to move the logic
which catches the inconsistency up a level.  But there
is no one nice place to put it for the bug I am
chasing now.

Regards,
  David V.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: edebug question - context of calling function
  2003-10-15  7:18 edebug question - context of calling function David Vanderschel
       [not found] ` <mailman.1841.1066353965.21628.help-gnu-emacs@gnu.org>
@ 2003-10-17 18:35 ` jan
  1 sibling, 0 replies; 9+ messages in thread
From: jan @ 2003-10-17 18:35 UTC (permalink / raw)
  Cc: help-gnu-emacs

"David Vanderschel" <DJV1@Austin.RR.com> writes:

> I sometimes put a source breakpoint in my code to catch a particular
> error condition.  When such a conditional breakpoint fires, the
> actual problem, though recognized in the called function, is often
> attributable to the calling function.  What I want to do then is to
> look around at the state of the calling function at the time it
> called the function which invoked edebug.  I can instrument the
> calling function; but, when in the debugger, I cannot see how to pop
> the context stack so that I can look around at the variables in the
> calling program.  What am I missing?

If I understand you correctly, you want to walk up the stack and look
at the local variable in the functions along the way. I had a quick
look and both edebug and the standard emacs debugger seem to be
missing this feature. However, it may not be necessary because elisp
is a dynamically scoped language, for example:

(defun function1 ()
  (let ((a 1)
	(b 2))
    (list a b (function2) a b)))

(defun function2 ()
  (let ((b 3)
	(c 4))
    (edebug)
    (setq a 5
	  b 6)
    (+ b c)))

(function1)

when you hit the (edebug) breakpoint in function2 you can just eval
`a' because it is still in scope. You probably already knew this and
want to inspect variables like `b' which have been shadowed by the let
in function2. In this case, I would just move the breakpoint up to the
calling function and make the condition on it more clever so it only
fires under the circumstances you want.

-- 
jan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: edebug question - context of calling function
  2003-10-17  2:19   ` David Vanderschel
@ 2003-10-18 19:59     ` jan
       [not found]     ` <mailman.1915.1066445382.21628.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 9+ messages in thread
From: jan @ 2003-10-18 19:59 UTC (permalink / raw)
  Cc: help-gnu-emacs

"David Vanderschel" <DJV1@Austin.RR.com> writes:

> > > I sometimes put a source breakpoint in my code to catch a
> > > particular error condition.  When such a conditional breakpoint
> > > fires, the actual problem, though recognized in the called
> > > function, is often attributable to the calling function.  What I
> > > want to do then is to look around at the state of the calling
> > > function at the time it called the function which invoked
> > > edebug.  I can instrument the calling function; but, when in the
> > > debugger, I cannot see how to pop the context stack so that I
> > > can look around at the variables in the calling program.  What
> > > am I missing?

> > If I understand you correctly, you want to walk up the stack and
> > look at the local variable in the functions along the way. I had a
> > quick look and both edebug and the standard emacs debugger seem to
> > be missing this feature. However, it may not be necessary because
> > elisp is a dynamically scoped language, for example:

> I think you do understand me correctly.  Unfortunately, I often
> reuse the same local variables (eg., i, j, x, ...).

I'm guessing that i and j are iteration variables, and x is a position
on an x-axis. If not, I think you need to use more descriptive
variable names, and use dabbrev-expand (M-/) or hippie-expand to save
yourself the extra typing.

> I was also interested in the calling context in the sense of "Among
> multiple possible invocations in the calling program, which
> invocation of of the function which noticed the condition caused
> this break."  I guess you are correct that I have to move the logic
> which catches the inconsistency up a level.  But there is no one
> nice place to put it for the bug I am chasing now.
 
If you can reproduce the bug consistently, just use the backtrace to
find out which function to move the breakpoint up into.

Otherwise, if you're willing to recompile emacs then the following
function combined with the backtrace should give you all the info you
need to piece together what's happening.


(defun edebug-symbol-values (symbol)
  "Display SYMBOL's values in the minibuffer.
If interactive, prompt for SYMBOL.

See `symbol-values' documentation for more details,
including bugs and limitations."
  (interactive "SSymbol: ")
  (princ (symbol-values symbol)))

(require 'edebug)
(define-key edebug-mode-map "s" 'edebug-symbol-values)
(define-key global-edebug-map "s" 'edebug-symbol-values)


I had to drop into C to write symbol-values. I added it to
../emacs-21.2/src/data.c just after the definition for symbol-value.


DEFUN ("symbol-values", Fsymbol_values, Ssymbol_values, 1, 1, 0,
  "Return SYMBOL's special binding stack as a list.\n\
The first value in the returned list is the current value.\n\
The last value in the returned list is the global value.\n\n\
 Bugs:\n\
There is no way to distinguish a void value from the symbol `unbound'.\n\
Buffer-local, frame-local and terminal-local variables are ignored.")
  (symbol)
     Lisp_Object symbol;
{
  Lisp_Object values = Qnil;
  struct specbinding *specpdl_iterator = specpdl;

  CHECK_SYMBOL (symbol, 0);

  for (;specpdl_iterator < specpdl_ptr; ++specpdl_iterator)
    {
      if (EQ (specpdl_iterator->symbol, symbol))
	values = Fcons (specpdl_iterator->old_value, values);
    }

  return Fcons (XSYMBOL (symbol)->value, values);
}


And don't forget to register the function with defsubr, again I added
it just after the symbol_value version.


  defsubr (&Ssymbol_values);


-- 
jan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: edebug question - context of calling function
       [not found]     ` <mailman.1915.1066445382.21628.help-gnu-emacs@gnu.org>
@ 2003-10-24 12:16       ` David Vanderschel
  2003-10-24 15:51         ` Stefan Monnier
                           ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: David Vanderschel @ 2003-10-24 12:16 UTC (permalink / raw)


"jan" <janmar@iprimus.com.au> wrote in message
news:mailman.1915.1066445382.21628.help-gnu-emacs@gnu.org...
> "David Vanderschel" <DJV1@Austin.RR.com> writes:
> > I think you do understand me correctly.
> > Unfortunately, I often reuse the same local
> > variables (eg., i, j, x, ...).

> I'm guessing that i and j are iteration variables,
> and x is a position on an x-axis. If not, I think
> you need to use more descriptive variable names, and
> use dabbrev-expand (M-/) or hippie-expand to save
> yourself the extra typing.

I did not post in order to get advice on programming
style.  When I am using a variable intensely and
locally, I personally find that the code is easier to
read if the symbol for that variable is short - more
like doing mathematics.  I believe that for such
variables, it is better to learn the usage of the
short symbol than to clutter the code with repetitious
occurrences of a symbol which persists in always
'explaining' itself.  When appropriate, I do put an
extensive comment where the variable is declared,
explaining how it is used.  (Actually, for something
like an array index, not even such an explanation is
needed.  Eg., (loop for i to 20 do (aset v i ...)).
'i' is a variable I am especially fond of reusing as
an index variable in a loop.)  For more global things
where usage is not locally intensive but thinly
distributed, I _do_ use long, carefully chosen names
which suggest the function without much extra
documentation.  This also avoids naming conflicts in
the not-very-hierarchical name space offered by emacs.

> > I was also interested in the calling context in
> > the sense of "Among multiple possible invocations
> > in the calling program, which invocation of of the
> > function which noticed the condition caused this
> > break."  I guess you are correct that I have to
> > move the logic which catches the inconsistency up
> > a level.  But there is no one nice place to put it
> > for the bug I am chasing now.

> If you can reproduce the bug consistently, just use
> the backtrace to find out which function to move the
> breakpoint up into.

I already know which is the calling the function.  The
problem is that that code contains multiple
invocations of the function which notices the error
condition, and I want to know which _one_ of those
invocations made the call exhibiting the problem.  In
the extreme and when it is possible for the called
function to return anyway, I can instrument the
calling function myself, by placing a check after each
invocation to see if the error condition arose during
processing by the called function.  (It can set a flag
when the error condition is seen.)  However, I was
hoping that one would not need to go to such lengths.

I am familiar with other debuggers which allow you to
proceed up and down the stack of call frames, looking
at context (including location of the call in each
calling program) in a whole hierarchy of calling
functions.  I just expected such capability in edebug
and was trying to find out how to exercise it.
However, I am willing to accept that the capability is
not there.

> Otherwise, if you're willing to recompile emacs then
> the following function combined with the backtrace
> should give you all the info you need to piece
> together what's happening.

Unfortunately, I am not in a position to recompile
emacs.  However, even if I were, I fear that I have
missed the point of jan's edebug-symbol-values.  I
have no difficulty getting edebug to show me symbol
values as it is now.  Indeed, it already has an "eval"
function (bound to 'e').  (Actually, I can usually
just put the cursor on an instance of a variable I
want the value of and hit C-x e.)  The eval function
does correctly evaluate the variables of the calling
function when I have not reused them in the called
function; but it does not help to find the context in
the calling program from which the invocation
occurred.

Regards,
  David V.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: edebug question - context of calling function
  2003-10-24 12:16       ` David Vanderschel
@ 2003-10-24 15:51         ` Stefan Monnier
  2003-10-24 18:41           ` David Vanderschel
  2003-10-26  3:13         ` jan
       [not found]         ` <mailman.2431.1067076191.21628.help-gnu-emacs@gnu.org>
  2 siblings, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2003-10-24 15:51 UTC (permalink / raw)


[ I haven't seen the earlier part of the thread. ]

> I am familiar with other debuggers which allow you to
> proceed up and down the stack of call frames, looking
> at context (including location of the call in each
> calling program) in a whole hierarchy of calling
> functions.  I just expected such capability in edebug
> and was trying to find out how to exercise it.
> However, I am willing to accept that the capability is
> not there.

I don't think edebug has that feature, although I can't think of
any particular reason why not (as long as the calling function
you want to look at is instrumented, of course).

If your calling function is byte-compiled, you can improve things a little
by using the non-byte-compiled version in which case the backtrace will give
you more than just the calling function's name and arguments.  It won't give
you line numbers, but you should/might be able to recognize the calling
context enough to figure out which of the calls is currently active.


        Stefan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: edebug question - context of calling function
  2003-10-24 15:51         ` Stefan Monnier
@ 2003-10-24 18:41           ` David Vanderschel
  0 siblings, 0 replies; 9+ messages in thread
From: David Vanderschel @ 2003-10-24 18:41 UTC (permalink / raw)


"Stefan Monnier" <monnier@iro.umontreal.ca> wrote in message
news:<jwvu15yskro.fsf-monnier+gnu.emacs.help@vor.iro.umontreal.ca>...
> > I am familiar with other debuggers which allow you to
> > proceed up and down the stack of call frames, looking
> > at context (including location of the call in each
> > calling program) in a whole hierarchy of calling
> > functions.  I just expected such capability in edebug
> > and was trying to find out how to exercise it.
> > However, I am willing to accept that the capability is
> > not there.

> I don't think edebug has that feature, although I can't think of
> any particular reason why not (as long as the calling function
> you want to look at is instrumented, of course).

I could not think of any such reason either, which is
why I was looking for the functionality.  (I was
instrumenting the calling function.)

> If your calling function is byte-compiled, you can
> improve things a little by using the
> non-byte-compiled version in which case the
> backtrace will give you more than just the calling
> function's name and arguments.  It won't give you
> line numbers, but you should/might be able to
> recognize the calling context enough to figure out
> which of the calls is currently active.

If the calling function has been instrumented, the
point about byte-compiling is moot.  The particular
function which intiated this quest is one in which I
made rather heavy use of CL macros.  The result is
fairly effective obfuscation of any recognizable
context.

I just discovered something which does help:  After
the source breakpoint is hit, I can set a breakpoint
at the end of the called function (or step down to
there).  Then I can step through the return to the
calling function and I _do_ wind up in the context of
the calling program.  So this approach can be used
whenever it is possible to make a return from the
function which recognizes the problem - a possibility
which does exist in the situation which concerned me.
I'd still prefer to be able to get there without executing
the remainder of the called function.

Regards,
  David V.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: edebug question - context of calling function
  2003-10-24 12:16       ` David Vanderschel
  2003-10-24 15:51         ` Stefan Monnier
@ 2003-10-26  3:13         ` jan
       [not found]         ` <mailman.2431.1067076191.21628.help-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 9+ messages in thread
From: jan @ 2003-10-26  3:13 UTC (permalink / raw)
  Cc: help-gnu-emacs

"David Vanderschel" <DJV1@Austin.RR.com> writes:

> I did not post in order to get advice on programming style.

Consider it a bonus ;-)

Actually, I didn't mean to offend, I haven't seen your code and was
stabbing in the dark at possible causes of your problem.

> I already know which is the calling the function.  The problem is
> that that code contains multiple invocations of the function which
> notices the error condition, and I want to know which _one_ of those
> invocations made the call exhibiting the problem.

Sorry, I misunderstood this before.

> Unfortunately, I am not in a position to recompile emacs.  However,
> even if I were, I fear that I have missed the point of jan's
> edebug-symbol-values.

Perhaps the doc strings didn't make much sense, here is an example:

(let ((a 1))
  (let ((a 3))
    (symbol-values 'a))) => (3 1 unbound)

(setq a 5) => 5

(let ((a 1))
  (let ((a 3))
    (symbol-values 'a))) => (3 1 5)

but it doesn't work with lexical-let.

-- 
jan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: edebug question - context of calling function
       [not found]         ` <mailman.2431.1067076191.21628.help-gnu-emacs@gnu.org>
@ 2003-10-30  3:38           ` David Vanderschel
  0 siblings, 0 replies; 9+ messages in thread
From: David Vanderschel @ 2003-10-30  3:38 UTC (permalink / raw)


"jan" <janmar@iprimus.com.au> wrote in message
news:mailman.2431.1067076191.21628.help-gnu-emacs@gnu.org...
> "David Vanderschel" <DJV1@Austin.RR.com> writes:
> > Unfortunately, I am not in a position to recompile emacs.  However,
> > even if I were, I fear that I have missed the point of jan's
> > edebug-symbol-values.

> Perhaps the doc strings didn't make much sense, here is an example:

> (let ((a 1))
>   (let ((a 3))
>     (symbol-values 'a))) => (3 1 unbound)

I get it now.  It is relevant.  Wish I had it.

Thanks,
  David V.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2003-10-30  3:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-10-15  7:18 edebug question - context of calling function David Vanderschel
     [not found] ` <mailman.1841.1066353965.21628.help-gnu-emacs@gnu.org>
2003-10-17  2:19   ` David Vanderschel
2003-10-18 19:59     ` jan
     [not found]     ` <mailman.1915.1066445382.21628.help-gnu-emacs@gnu.org>
2003-10-24 12:16       ` David Vanderschel
2003-10-24 15:51         ` Stefan Monnier
2003-10-24 18:41           ` David Vanderschel
2003-10-26  3:13         ` jan
     [not found]         ` <mailman.2431.1067076191.21628.help-gnu-emacs@gnu.org>
2003-10-30  3:38           ` David Vanderschel
2003-10-17 18:35 ` jan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).