[plt-scheme] Suggestion: Backtrace Remembers Last, not First Tail-Recursive Procedure

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Apr 7 23:01:30 EDT 2010

The built-in backtrace does keep track of the most recent call, only.
A typical reason that functions disappear in the stack trace is inlining
by the compiler. Could it be that `stat:fold-files' and the functions
that call it are all inlined into `main'? In that case, there isn't a
call to `stat:fold-files' at the level that the built-in backtrace gets
its information.

In general, the backtrace that you get from the core system (as opposed
to one from DrScheme in debugging more or from `errortrace') is
approximate, and it can be affected in lots of ways by optimization.
It's definitely in the "vague and heuristic" category.

At Wed, 07 Apr 2010 19:42:06 -0700, Synx wrote:
> I'd sure like to make it so that the backtrace kept track not of the 
> first procedure in a round of tail recursion, but the last procedure 
> instead. When a procedure recurses in tail position, it effectively 
> "goes away" and is replaced by the procedure it calls. This should also 
> be true of the backtrace, which I don't think is the case. At the very 
> least I'd like to be able to configure that behavior. Currently I'm 
> dealing with a backtrace like this:
>   === context ===
> /home/*****/.plt-scheme/planet/300/4.2.4/cache/jaymccarthy/sqlite.plt/4/6/sqlit
> e.ss:59:0: 
> sqlite-error
> /home/*****/.plt-scheme/planet/300/4.2.4/cache/jaymccarthy/sqlite.plt/4/6/sqlit
> e.ss:186:0: 
> step
> /var/opt/plt/lib/plt/collects/scheme/contract/private/arrow.ss:1388:3
> /home/*****/code/scheme/util/sqlite.ss:80:9: loop
> /home/*****/code/scheme/backup/scan.ss:56:0: main
> At scan.ss:56:0 there is a procedure called "main" that calls a 
> procedure called "check-sources" that repeatedly calls an anonymous 
> procedure, that calls a procedure called "with-transaction" which calls 
> another lambda that calls a procedure named "stat:fold-files" which 
> calls a third lambda on a bunch of files, which itself calls 
> "vector-ref". Many of those calls are tail recursive, or at least 
> potentially tail recursive, but I would much rather see a stack trace 
> like this:
> /var/opt/plt/lib/plt/collects/scheme/contract/private/arrow.ss:1388:3
> /home/*****/code/scheme/util/sqlite.ss:80:9: loop
> /home/*****/code/scheme/backup/scan.ss:56:0: stat:fold-files
> I don't care that it was called in main, if main has already been 
> tail-call optimized into obscurity. I do however care that the exception 
> occurred in the stat:fold-files function (assuming it did). But when I 
> see "scan.ss:56:0: main" all that tells me is that there was an error 
> somewhere in main, check-sources, with-transaction, stat:fold-files, 
> three anonymous procedures, and vector-ref, and the error could have 
> happened in any of those procedures, because the one it is actually in 
> is not recorded by the stacktrace, while the obsolete procedure at the 
> beginning of the tail-recursive sequence is the only thing preserved.
> I can glean from the error message "SQLite Error: Library used 
> incorrectly" that it probably has something to do with a bug in 
> with-transaction, that blocks the real exception from being displayed by 
> messing up using the sqlite library. But that information is vague and 
> heuristic, and it's much harder to figure out exactly what the problem 
> is. If, however, I actually saw a line like 
> "..util/sqlite.ss:connection%with-transaction:204" then I would be much 
> more sure of where the problem is.
> I know the error happens somewhere inside "main" so I don't need to know 
> anything about that. Therefore I suggest that the backtrace keep track 
> of the lowest tail-recursive call, not the highest one. I can't think of 
> any time that would be a problem... but if so I'd at least like to be 
> able to enable that behavior selectively for myself.

Posted on the users mailing list.