* Broken Backtraces, and Part of a Solution @ 2012-04-19 0:02 Noah Lavine 2012-04-19 0:13 ` Noah Lavine 2012-04-19 0:56 ` Andy Wingo 0 siblings, 2 replies; 11+ messages in thread From: Noah Lavine @ 2012-04-19 0:02 UTC (permalink / raw) To: guile-devel 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 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-19 0:02 Broken Backtraces, and Part of a Solution Noah Lavine @ 2012-04-19 0:13 ` Noah Lavine 2012-04-19 0:56 ` Andy Wingo 1 sibling, 0 replies; 11+ messages in thread From: Noah Lavine @ 2012-04-19 0:13 UTC (permalink / raw) To: guile-devel 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 this: (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. Noah On Wed, Apr 18, 2012 at 8:02 PM, Noah Lavine <noah.b.lavine@gmail.com> 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 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-19 0:02 Broken Backtraces, and Part of a Solution Noah Lavine 2012-04-19 0:13 ` Noah Lavine @ 2012-04-19 0:56 ` Andy Wingo 2012-04-19 1:08 ` Noah Lavine 1 sibling, 1 reply; 11+ messages in thread From: Andy Wingo @ 2012-04-19 0:56 UTC (permalink / raw) To: Noah Lavine; +Cc: guile-devel On Wed 18 Apr 2012 17:02, Noah Lavine <noah.b.lavine@gmail.com> writes: > 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"). Aaaaah. I was seeing something like this as well but I didn't figure out why. Thanks for tracking this down! The reason is that the type of make-prompt-tag changed, and the stack narrowing code didn't adapt accordingly. We need to change to default to consider generic objects as eq?-compared prompt tags. Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-19 0:56 ` Andy Wingo @ 2012-04-19 1:08 ` Noah Lavine 2012-04-19 1:36 ` Andy Wingo 0 siblings, 1 reply; 11+ messages in thread From: Noah Lavine @ 2012-04-19 1:08 UTC (permalink / raw) To: Andy Wingo; +Cc: guile-devel On Wed, Apr 18, 2012 at 8:56 PM, Andy Wingo <wingo@pobox.com> wrote: > On Wed 18 Apr 2012 17:02, Noah Lavine <noah.b.lavine@gmail.com> writes: > >> 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"). > > Aaaaah. I was seeing something like this as well but I didn't figure > out why. Thanks for tracking this down! The reason is that the type of > make-prompt-tag changed, and the stack narrowing code didn't adapt > accordingly. We need to change to default to consider generic objects > as eq?-compared prompt tags. I agree, but you still couldn't use procedures or integers as prompt tags if you wanted make-stack to work, because those are special cases. That's why I thought of just changing the interface to make-stack to specify what you want - it's such a weird restriction that someone could be bitten by it and have a lot of trouble tracking it down. And because an argument can mean three different things, code that uses make-stack is hard to understand (or at least it was for me). What do you think? Noah ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-19 1:08 ` Noah Lavine @ 2012-04-19 1:36 ` Andy Wingo 2012-04-19 2:13 ` Noah Lavine 0 siblings, 1 reply; 11+ messages in thread From: Andy Wingo @ 2012-04-19 1:36 UTC (permalink / raw) To: Noah Lavine; +Cc: guile-devel On Wed 18 Apr 2012 18:08, Noah Lavine <noah.b.lavine@gmail.com> writes: >> We need to change to default to consider generic objects as >> eq?-compared prompt tags. > > I agree, but you still couldn't use procedures or integers as prompt > tags if you wanted make-stack to work, because those are special > cases. Yeah, but the whole point of prompt tags is that you can make a new one and know that it is eq?-unique, which is not the case for integers. So integers are not in the general case. It seems useful to add procedures as a special case too, no? > That's why I thought of just changing the interface to make-stack to > specify what you want - it's such a weird restriction that someone > could be bitten by it and have a lot of trouble tracking it down. And > because an argument can mean three different things, code that uses > make-stack is hard to understand (or at least it was for me). It's something of a nasty interface, I agree. But it's been around for a long time; if we can make a minimal change, we should, it seems to me. Want to make a patch? Regards, Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-19 1:36 ` Andy Wingo @ 2012-04-19 2:13 ` Noah Lavine 2012-04-20 2:47 ` Noah Lavine 0 siblings, 1 reply; 11+ messages in thread From: Noah Lavine @ 2012-04-19 2:13 UTC (permalink / raw) To: Andy Wingo; +Cc: guile-devel [-- Attachment #1: Type: text/plain, Size: 1440 bytes --] Here's a patch that fixes the bug for me. I'd also like to add a test suite for the stack functions, to make sure this doesn't happen again, but I'll look at that later. Noah On Wed, Apr 18, 2012 at 9:36 PM, Andy Wingo <wingo@pobox.com> wrote: > On Wed 18 Apr 2012 18:08, Noah Lavine <noah.b.lavine@gmail.com> writes: > >>> We need to change to default to consider generic objects as >>> eq?-compared prompt tags. >> >> I agree, but you still couldn't use procedures or integers as prompt >> tags if you wanted make-stack to work, because those are special >> cases. > > Yeah, but the whole point of prompt tags is that you can make a new one > and know that it is eq?-unique, which is not the case for integers. So > integers are not in the general case. It seems useful to add procedures > as a special case too, no? > >> That's why I thought of just changing the interface to make-stack to >> specify what you want - it's such a weird restriction that someone >> could be bitten by it and have a lot of trouble tracking it down. And >> because an argument can mean three different things, code that uses >> make-stack is hard to understand (or at least it was for me). > > It's something of a nasty interface, I agree. But it's been around for > a long time; if we can make a minimal change, we should, it seems to me. > > Want to make a patch? > > Regards, > > Andy > -- > http://wingolog.org/ [-- Attachment #2: 0001-make-stack-handles-prompt-tags-better.patch --] [-- Type: application/octet-stream, Size: 4375 bytes --] From d1beca7eac1958ee786f01af13df732c212cfd07 Mon Sep 17 00:00:00 2001 From: Noah Lavine <noah.b.lavine@gmail.com> Date: Wed, 18 Apr 2012 22:10:21 -0400 Subject: [PATCH] make-stack handles prompt tags better * libguile/stacks.c: update make-stack and narrow_stack to handle prompt tags that are not symbols. --- libguile/stacks.c | 66 ++++++++++++++++++++++++++-------------------------- 1 files changed, 33 insertions(+), 33 deletions(-) diff --git a/libguile/stacks.c b/libguile/stacks.c index 13d347a..3f3f132 100644 --- a/libguile/stacks.c +++ b/libguile/stacks.c @@ -109,7 +109,7 @@ find_prompt (SCM key) } static void -narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key) +narrow_stack (SCM stack, SCM inner_cut, SCM outer_cut) { unsigned long int len; SCM frame; @@ -118,57 +118,67 @@ narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key) frame = SCM_STACK_FRAME (stack); /* Cut inner part. */ - if (scm_is_true (scm_procedure_p (inner_key))) + if (scm_is_true (scm_procedure_p (inner_cut))) { /* Cut until the given procedure is seen. */ - for (; inner && len ; --inner) + for (; len ;) { SCM proc = scm_frame_procedure (frame); len--; frame = scm_frame_previous (frame); - if (scm_is_eq (proc, inner_key)) + if (scm_is_eq (proc, inner_cut)) break; } } - else if (scm_is_symbol (inner_key)) - { - /* Cut until the given prompt tag is seen. FIXME, assumes prompt tags are - symbols. */ - SCM *fp = find_prompt (inner_key); - for (; len; len--, frame = scm_frame_previous (frame)) - if (fp == SCM_VM_FRAME_FP (frame) - SCM_VM_FRAME_OFFSET (frame)) - break; - } - else + else if (scm_is_integer (inner_cut)) { /* Cut specified number of frames. */ + long inner = scm_to_int (inner_cut); + for (; inner && len; --inner) { len--; frame = scm_frame_previous (frame); } } + else + { + /* Cut until the given prompt tag is seen. */ + SCM *fp = find_prompt (inner_cut); + for (; len; len--, frame = scm_frame_previous (frame)) + if (fp == SCM_VM_FRAME_FP (frame) - SCM_VM_FRAME_OFFSET (frame)) + break; + } SCM_SET_STACK_LENGTH (stack, len); SCM_SET_STACK_FRAME (stack, frame); /* Cut outer part. */ - if (scm_is_true (scm_procedure_p (outer_key))) + if (scm_is_true (scm_procedure_p (outer_cut))) { /* Cut until the given procedure is seen. */ - for (; outer && len ; --outer) + for (; len ;) { frame = scm_stack_ref (stack, scm_from_long (len - 1)); len--; - if (scm_is_eq (scm_frame_procedure (frame), outer_key)) + if (scm_is_eq (scm_frame_procedure (frame), outer_cut)) break; } } - else if (scm_is_symbol (outer_key)) + else if (scm_is_integer (outer_cut)) + { + /* Cut specified number of frames. */ + long outer = scm_to_int (outer_cut); + + if (outer < len) + len -= outer; + else + len = 0; + } + else { - /* Cut until the given prompt tag is seen. FIXME, assumes prompt tags are - symbols. */ - SCM *fp = find_prompt (outer_key); + /* Cut until the given prompt tag is seen. */ + SCM *fp = find_prompt (outer_cut); while (len) { frame = scm_stack_ref (stack, scm_from_long (len - 1)); @@ -177,14 +187,6 @@ narrow_stack (SCM stack, long inner, SCM inner_key, long outer, SCM outer_key) break; } } - else - { - /* Cut specified number of frames. */ - if (outer < len) - len -= outer; - else - len = 0; - } SCM_SET_STACK_LENGTH (stack, len); } @@ -308,10 +310,8 @@ SCM_DEFINE (scm_make_stack, "make-stack", 1, 0, 1, } narrow_stack (stack, - scm_is_integer (inner_cut) ? scm_to_int (inner_cut) : n, - scm_is_integer (inner_cut) ? SCM_BOOL_T : inner_cut, - scm_is_integer (outer_cut) ? scm_to_int (outer_cut) : n, - scm_is_integer (outer_cut) ? SCM_BOOL_T : outer_cut); + inner_cut, + outer_cut); n = SCM_STACK_LENGTH (stack); } -- 1.7.6 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-19 2:13 ` Noah Lavine @ 2012-04-20 2:47 ` Noah Lavine 2012-04-20 14:13 ` Andy Wingo 2012-04-22 10:53 ` Ludovic Courtès 0 siblings, 2 replies; 11+ messages in thread From: Noah Lavine @ 2012-04-20 2:47 UTC (permalink / raw) To: Andy Wingo; +Cc: guile-devel After looking at it more, there aren't really enough stack functions to warrant a test suite. Any objections if I push this to master? Noah On Wed, Apr 18, 2012 at 10:13 PM, Noah Lavine <noah.b.lavine@gmail.com> wrote: > Here's a patch that fixes the bug for me. I'd also like to add a test > suite for the stack functions, to make sure this doesn't happen again, > but I'll look at that later. > > Noah > > On Wed, Apr 18, 2012 at 9:36 PM, Andy Wingo <wingo@pobox.com> wrote: >> On Wed 18 Apr 2012 18:08, Noah Lavine <noah.b.lavine@gmail.com> writes: >> >>>> We need to change to default to consider generic objects as >>>> eq?-compared prompt tags. >>> >>> I agree, but you still couldn't use procedures or integers as prompt >>> tags if you wanted make-stack to work, because those are special >>> cases. >> >> Yeah, but the whole point of prompt tags is that you can make a new one >> and know that it is eq?-unique, which is not the case for integers. So >> integers are not in the general case. It seems useful to add procedures >> as a special case too, no? >> >>> That's why I thought of just changing the interface to make-stack to >>> specify what you want - it's such a weird restriction that someone >>> could be bitten by it and have a lot of trouble tracking it down. And >>> because an argument can mean three different things, code that uses >>> make-stack is hard to understand (or at least it was for me). >> >> It's something of a nasty interface, I agree. But it's been around for >> a long time; if we can make a minimal change, we should, it seems to me. >> >> Want to make a patch? >> >> Regards, >> >> Andy >> -- >> http://wingolog.org/ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-20 2:47 ` Noah Lavine @ 2012-04-20 14:13 ` Andy Wingo 2012-04-22 10:53 ` Ludovic Courtès 1 sibling, 0 replies; 11+ messages in thread From: Andy Wingo @ 2012-04-20 14:13 UTC (permalink / raw) To: Noah Lavine; +Cc: guile-devel On Thu 19 Apr 2012 19:47, Noah Lavine <noah.b.lavine@gmail.com> writes: > After looking at it more, there aren't really enough stack functions > to warrant a test suite. Any objections if I push this to master? I haven't had time to look at it, but if you think it's right, please go ahead. :) Cheers, Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-20 2:47 ` Noah Lavine 2012-04-20 14:13 ` Andy Wingo @ 2012-04-22 10:53 ` Ludovic Courtès 2012-04-24 1:42 ` Noah Lavine 1 sibling, 1 reply; 11+ messages in thread From: Ludovic Courtès @ 2012-04-22 10:53 UTC (permalink / raw) To: guile-devel Hi Noah, Noah Lavine <noah.b.lavine@gmail.com> skribis: > After looking at it more, there aren't really enough stack functions > to warrant a test suite. Sounds like a fallacious argument to me. ;-) Would it be possible for you to add test cases? There are a few tests under “stacks” in eval.test; perhaps something along these lines would work? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-22 10:53 ` Ludovic Courtès @ 2012-04-24 1:42 ` Noah Lavine 2012-04-24 16:58 ` Ludovic Courtès 0 siblings, 1 reply; 11+ messages in thread From: Noah Lavine @ 2012-04-24 1:42 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guile-devel Hello, >> After looking at it more, there aren't really enough stack functions >> to warrant a test suite. > > Sounds like a fallacious argument to me. ;-) > > Would it be possible for you to add test cases? There are a few tests > under “stacks” in eval.test; perhaps something along these lines would > work? Yes, you're right. Those tests showed me how to get a stack. I pushed the fix with two new test cases, and then cleaned up the stack-test code a bit. Thanks a lot, Noah ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Broken Backtraces, and Part of a Solution 2012-04-24 1:42 ` Noah Lavine @ 2012-04-24 16:58 ` Ludovic Courtès 0 siblings, 0 replies; 11+ messages in thread From: Ludovic Courtès @ 2012-04-24 16:58 UTC (permalink / raw) To: Noah Lavine; +Cc: guile-devel Noah Lavine <noah.b.lavine@gmail.com> skribis: > Yes, you're right. Those tests showed me how to get a stack. I pushed > the fix with two new test cases, and then cleaned up the stack-test > code a bit. Excellent, thank you! Ludo’. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2012-04-24 16:58 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-04-19 0:02 Broken Backtraces, and Part of a Solution Noah Lavine 2012-04-19 0:13 ` Noah Lavine 2012-04-19 0:56 ` Andy Wingo 2012-04-19 1:08 ` Noah Lavine 2012-04-19 1:36 ` Andy Wingo 2012-04-19 2:13 ` Noah Lavine 2012-04-20 2:47 ` Noah Lavine 2012-04-20 14:13 ` Andy Wingo 2012-04-22 10:53 ` Ludovic Courtès 2012-04-24 1:42 ` Noah Lavine 2012-04-24 16:58 ` Ludovic Courtès
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).