Error stack strawman

Mark S. Miller erights at
Wed Feb 24 20:37:08 UTC 2016

On Wed, Feb 24, 2016 at 11:40 AM, Steve Fink <sphink at> wrote:

> On 02/19/2016 01:26 AM, Andreas Rossberg wrote:
> On 19 February 2016 at 03:13, Gary Guo <nbdd0121 at> wrote:
> If we are not going to indicate tail call some way, debugging might be
>> extremely difficult, and the stack result might be making no sense at all.
> A tail call is a jump. Just like other jumps, you shouldn't expect their
> history to be visible in the continuation (which is what a stack trace
> represents). I agree that JS programmers might be surprised, and will have
> to relearn what they know. But wrt to debugging the situation is the same
> as for loops: you can't inspect their history either. (And functional
> programmers in fact see loops as just an ugly way to express self tail
> recursion. :) )
> To be even more pedantic: the stack trace isn't "the" continuation, it is
> one possible continuation. Other continuations are possible if you throw an
> exception. I guess you could say the stack trace plus the code allows you
> to statically derive the full set of possible continuations.
> But I agree that it's worthwhile to remember the difference, since what is
> being requested for stacks really *is* a history, not a continuation. For
> example, it is desireable to encode "long stacks" or "async stacks" or
> whatever they're being called these days, where eg for an event handler you
> get the stack trace at the point the handler was installed. That is not a
> continuation, that is history. I would be very wary of mandating that full
> history be preserved, since it's easy for it to prevent optimizations or
> inadvertently leak details of the underlying implementation (tail calls,
> inlining, captured environments).
> Does it work to specify something like "if and only if the information is
> available, it shall be encoded like this:..."? That can still leak
> information if not handled carefully, but at least it doesn't inhibit
> optimizations.
> For a wild handwavy example of an information leak: say you do not include
> inlined calls in stack frames, and you only inline a call after the 10th
> invocation. Further assume that you self-host some JS feature. The caller
> can now learn something about how many times that self-hosted feature has
> been used. That feature might happen to be Math.something used only for
> processing non-latin1 characters in a password, or more likely just some
> feature used only if you are logged into a certain site. (Perhaps
> Error.stack is already specced to avoid this, by requiring all frames to be
> included whether inlined or not? Sorry, I don't know anything about it; I'm
> just posting to ask the question about what specifying stack formats
> encompasses.)

This information leak is not specific to tail-call variance. It is a
problem with the whole error.stack interface <>.
Like makeWeakRef <>, that is why
the getStack and getStackString functions won't be generally available to
confined code, but must instead be virtualizable or deniable. Starting with
KeyKOS, capability practitioners refer to this category as "closely held",
as opposed to "ambient". *Everything* in the ES6 standard itself is
ambient, since we postponed spec'ing anything that needs to be closely
held. Now is that time <>.

Again, as with makeWeakRef, by treating getStack and getStackString as
closely held, it is also less damaging[1] for them to leak implementation
non-determinacy that may carry side channels or covert channels.

[1] It is less damaging when the leakage is limited to intra-realm, since
one realm is not in a position to police another. For getStack and
getStackString, this is yet another reason we need to think hard about
cross-realm stacks. I, for one, have not yet done so.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list