[Top][All Lists]

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

Re: Broken Backtraces, and Part of a Solution

From: Noah Lavine
Subject: Re: Broken Backtraces, and Part of a Solution
Date: Wed, 18 Apr 2012 20:13:53 -0400

Sorry for the quick update, but this seems to be a result of commit
283ab48d3f20a5c5281cafc29f0c30c8d8ace9ee, on March 7th.

The fluid %stacks is set in %start-stack, in boot-9.scm. %start-stack
calls make-prompt-tag, also in boot-9.scm. The commit above switched
prompt tags from using gensyms to using lists. This is much faster,
but it also made backtraces break, because narrow_stack has the
ability to search for symbols but not for lists.

The fix I'd like to implement is to change the make-stack interface.
It trims stacks according to its arguments, but it tries to be too
clever - if it's passed an integer, it trims that many frames. If it's
passed a procedure, it trims that many procedures. If it's passed a
symbol, it trims until it sees the corresponding prompt. That worked
fine as long as prompt tags are always symbols, but breaks when they
are not.

We could fix it quickly by letting make-stack trim on pairs the same
as symbols, but that seems likely to break again. Instead, what if the
user could specify the sort of trimming they wanted? Something like

  (make-stack #t '(inner prompt-tag ("start-stack"))) would trim the
stack from the innermost frame looking for prompt tag
'("start-stack"). (make-stack #t (outer frames 3)) would trim the
outermost 3 frames from the stack.

The make-stack interface isn't used very much, according to grep, so
it wouldn't be hard to change all of its uses over to the new one.


On Wed, Apr 18, 2012 at 8:02 PM, Noah Lavine <address@hidden> wrote:
> Hello all,
> I recently realized that backtraces weren't working for me in the most
> recent build of Guile master. Specifically, I could get to a debug
> prompt fine, but when I tried to get a backtrace, it always came up
> empty. The problem happens in this code in
> module/system/repl/error-handling.scm:
>               (let* ((tag (and (pair? (fluid-ref %stacks))
>                                (cdar (fluid-ref %stacks))))
>                      (stack (narrow-stack->vector
>                              (make-stack #t)
>                              ;; Cut three frames from the top of the stack:
>                              ;; make-stack, this one, and the throw handler.
>                              3
>                              ;; Narrow the end of the stack to the most recent
>                              ;; start-stack.
>                              tag
>                              ;; And one more frame, because
> %start-stack invoking
>                              ;; the start-stack thunk has its own frame too.
>                              0 (and tag 1)))
>                      (error-msg (error-string stack key args))
>                      (debug (make-debug stack 0 error-msg #f)))
> (note: there are two instances of almost exactly the same code. the
> problem I see happens at the second instance, but the first would
> probably be the same)
> The problem is that narrow-stack->vector returns #(). It does this
> because the stack is narrowed to nothing. The narrowing really happens
> in the functions scm_make_stack and narrow_stack, in stacks.c.
> The reason it narrows to nothing is the third argument to
> narrow-stack->vector, tag. On my Guile build, tag evaluates to
> '("start-stack"). The code is trying to use the tag to trim extra
> frames off of the stack, but we can only trim with procedures,
> symbols, and integers. The fallback behavior is to eliminate the
> entire stack, which is what we see here.
> It's possible to solve this problem by using %start-stack instead of
> '("start-stack"), but that doesn't seem to be as general as the
> solution in this function. Instead, here's a question - why are we
> using (cdar (fluid-ref %stacks)) to get the stack tag, and what was
> someone expecting that to return when they wrote it?
> Thanks,
> Noah

reply via email to

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