Error stack

# Erik Arvidsson (12 years ago)

I wrote a new strawman for Error stack which is now available in some form in all major browser (if betas are considered).

strawman:error_stack

Feedback wanted.

# John J Barton (12 years ago)

On Thu, Jun 7, 2012 at 11:37 AM, Erik Arvidsson <erik.arvidsson at gmail.com> wrote:

I wrote a new strawman for Error stack which is now available in some form in all major browser (if betas are considered).

strawman:error_stack

Feedback wanted.

You might look at the Mueller format: gist.github.com/312a55532fac0296f2ab

Note that the V8 stack is not a property of the error object but rather a getter. This is a valuable performance advantage since the stack is not converted from C++ array to string until the getter is called.

Critical for tools is the ability to linkify the stack trace so we need the grammar to allow the URLs to be unambiguously parsable, including avoiding content of the error message from interfering.

jjb

# Erik Arvidsson (12 years ago)

On Thu, Jun 7, 2012 at 12:05 PM, John J Barton <johnjbarton at johnjbarton.com> wrote:

On Thu, Jun 7, 2012 at 11:37 AM, Erik Arvidsson <erik.arvidsson at gmail.com> wrote:

I wrote a new strawman for Error stack which is now available in some form in all major browser (if betas are considered).

strawman:error_stack

Feedback wanted.

You might look at the Mueller format: gist.github.com/312a55532fac0296f2ab

Note that the V8 stack is not a property of the error object but rather a getter. This is a valuable performance advantage since the stack is not converted from C++ array to string until the getter is called.

This is well known. Engines can implement lazy data properties too but maybe that is too magical. I'm fine speccing this as an accessor but if it is an accessor we should spec it as on Error.prototype and not on the instance.

Critical for tools is the ability to linkify the stack trace so we need the grammar to allow the URLs to be unambiguously parsable, including avoiding content of the error message from interfering.

Agreed and I believe the V8 format fulfills that requirement.

# John Lenz (12 years ago)

It would be great to see this standardized!

# Jason Orendorff (12 years ago)

On Thu, Jun 7, 2012 at 1:37 PM, Erik Arvidsson <erik.arvidsson at gmail.com> wrote:

I wrote a new strawman for Error stack which is now available in some form in all major browser (if betas are considered).

strawman:error_stack

Feedback wanted.

This isn't machine parseable in all cases, since the .message may contain newlines and can end with something like "\n at ..."

Changing this in Firefox would affect any Firefox addons that use Error.stack, but maybe we can take that hit.

# Erik Arvidsson (12 years ago)

On Thu, Jun 7, 2012 at 1:12 PM, Jason Orendorff <jason.orendorff at gmail.com> wrote:

This isn't machine parseable in all cases, since the .message may contain newlines and can end with something like "\n  at ..."

That is a good point. This also applies to the "name" of a function (and object when included). It is trivial to create a function "name" that breaks the V8 style formatting. SpiderMonkey "gets" away with this by using the name of the function expression and it does not try to deduce a name based on the code..

window['\n@'] = function() { alert(new Error().stack); };

When I first set out to write the proposal I was set on the SpiderMonkey formatting but as I researched this I drifted closer and closer to the V8 formatting. The thing that convinced me was eval.

I also don't think that providing ErrorName: ErrorMessage is a hard requirement. The same information is already available using errorObject.name and errorObject.message.

If we remove the first line and require that non identifiers are quoted I think we can guarantee that the value is machine parseable again.

Changing this in Firefox would affect any Firefox addons that use Error.stack, but maybe we can take that hit.

For web apps we already have to parse two different versions so I'm not too concerned about that case. The WebKit mobile web does not depend on either format (Safari doesn't have it in any shipping version yet) so the two problematic big eco systems are Firefox and Chrome extensions (and Node.js?)

# Domenic Denicola (12 years ago)

Machine-parsability might be reaching too far, especially if you lose the benefits of nice function/method name inference. Instead, perhaps a separate strawman to standardize something like the V8 stack trace API 1?

It is used in Node for providing long stack traces 2, [3], [4]. It's a bit cumbersome, e.g. maybe a separate error.stackFrames getter would be nicer and the Java-style getFileName() methods could become simple properties. But the fact that it exists is extremely useful.

[3]: kriskowal/q/blob/0c1ffdc50bbbba6ea77c3e97075fab35ab9f7b2d/q.js#L261-405, kriskowal/q/blob/0c1ffdc50bbbba6ea77c3e97075fab35ab9f7b2d/q.js#L1307-1321 [4]: NobleJS/WinningJS-todo/commit/2d4ca10c4f672dac9f021b697c4c72bbff321ed9

# Charles Kendrick (12 years ago)

Thanks for taking this on Erik.

I would suggest the following, which is mostly based on the information it was possible to extract from IE6 (which is amazingly still the leader in programmatic access to error information) as well as information we were able to get by writing a Firefox extension.

All of the following might be optionally enabled, similar to Error.stackTraceLimit, if you think it's too verbose.

  1. show the parameter values

.. and do so intelligently:

a. Show Arrays with length: Array[5]

b. truncate long strings and show length: "the quick brown fox jumped ..."[45]

c. format dates compactly: Date(2012/5/2 5:00)

d. for Objects, use the toString() method if it's been customized on the object, and for other objects instead of [Object object] pick salient properties such as ID/id, name, title, type, or label.

For example, in our traces we would show Obj{title:"foo"} if an Object with no customized toString() were present as a parameter and it happened to have a "title" property.

This is a general strategy for dumping the value of something shown in a stack trace and is assumed for other features below.

  1. show the value of "this" if it's not the window

This is extremely important in OO frameworks. It tells you exactly what instances are involved in the call stack. Traces that go through recursive algorithms can be almost useless without this.

For example:

ReferenceError: doSomething is not defined at f (www.example.com/temp.html:5:5) [on Obj{ID:"foo"}] at g (eval at h (www.example.com/temp.html:6:5)) at www.example.com/temp.html:11:1

  1. optionally show the line of code that crashed

ReferenceError: doSomething is not defined code: this.doSomething() at f (www.example.com/temp.html:5:5) at g (eval at h (www.example.com/temp.html:6:5)) at www.example.com/temp.html:11:1

  1. optionally show the line of code that calls down to the next frame

ReferenceError: doSomething is not defined code: this.doSomething() at f (www.example.com/temp.html:5:5) code: if (something) f(); at g (eval at h (www.example.com/temp.html:6:5)) code: g(currentValue); at www.example.com/temp.html:11:1

  1. optionally dump all non-parameter local variables for the crashing frame

ReferenceError: doSomething is not defined code: this.doSomething() vars: value: 5 parent: Obj{name:"foo"} at f (www.example.com/temp.html:5:5) [on: Obj{ID:1}] code: if (something) f();


A couple quick notes: some might argue this is pushing stacks to do things debuggers do. But, you don't have a debugger when you are trying to solve a problem in a live application, and you don't have a debugger when a customer is sending you logs and you can't even access the application.

But with stack traces like the above, especially when combined with good logging, you can be almost psychic when analyzing issues.

This information is very easy for the browser implementer to retrieve so I don't think it imposes an undue burden, and from my 13 years of experience helping customers with issues in a large JavaScript framework, I can tell you that the value is difficult to overstate.

# Charles Kendrick (12 years ago)

I agree that something like error.stackFrames would be ideal. However I would say the V8 stack trace API is missing 3 key things:

  1. access to parameter values
  2. access to local variables defined in the function
  3. access to the line of code that crashed / called the next frame without having to go download the source file and use the line number to find it. This is even more important for generated / eval()'d code where there is no source file per se.

Note that access to the function for the frame via getFunction() is inadequate - doesn't work with recursion. APIs to get local variables and parameter values would need to be on the stackFrame.

P.S. fascinating to learn that Node.js does long traces, we have done the same in SmartClient for a long time.

# David Herman (12 years ago)

I wrote a new strawman for Error stack which is now available in some form in all major browser (if betas are considered).

Thanks for writing this up. I left a couple comments on the strawman, but I should just respond here.

  • I'm in favor of trying to come up with a common format as much as possible, so that programs that manipulate stack traces can be written once and don't have to build compatibility layers like stacktracejs.com.

  • But we should be careful not to overspecify in ways that constrain optimizations. Despite the fact that we usually err on the side of full specification, this is actually one place where I think we can and should avoid it. The Chrome stackTraceLimit idea is interesting, but does V8 actually promise never to inline within the most recent n frames?

  • You mentioned that compatibility requires error.stack to be a string, even though programs would really like to have a structured version. Should we offer a different property with structured stack frame info (probably with a getter to allow straight-forward lazy construction), called error.stackFrames or error.stackEntries or something?

Thanks,

# T.J. Crowder (12 years ago)

On 8 June 2012 04:28, David Herman <dherman at mozilla.com> wrote:

  • You mentioned that compatibility requires error.stack to be a string, even though programs would really like to have a structured version. Should we offer a different property with structured stack frame info (probably with a getter to allow straight-forward lazy construction), called error.stackFrames or error.stackEntries or something?

Big +1 on that. Avoiding parsing information the engine has as discrete items already is a Good Thing(tm). Perhaps it'll be aspirational at first, but if specified now it'll happen eventually.

-- T.J.

# Wes Garland (12 years ago)

error.stackFrames, an Array which contains one object per stack frame, describing function name (if any), filename, line number, some kind of instance Id (for closures), arguments, and closed-over variables.... would be absolutely incredible from my POV.

Tie it up in a nice package that can be JSON.stringified, and that SSJS back-ends can send better debug info back to the browser for the developers to consume.

# Erik Arvidsson (12 years ago)

On Thu, Jun 7, 2012 at 3:21 PM, Charles Kendrick <charles at isomorphic.com> wrote:

I agree that something like error.stackFrames would be ideal.  However I would say the V8 stack trace API is missing 3 key things:

  1. access to parameter values
  2. access to local variables defined in the function
  3. access to the line of code that crashed / called the next frame

One thing that might not have been as clear as I wanted is that this is trying to spec Error stack as it exists today. This is not intended to cover any kind of debugging APIs. That is a completely different topic and has a lot of security implications.

# Erik Arvidsson (12 years ago)

On Thu, Jun 7, 2012 at 11:57 PM, T.J. Crowder <tj at crowdersoftware.com> wrote:

On 8 June 2012 04:28, David Herman <dherman at mozilla.com> wrote:

  • You mentioned that compatibility requires error.stack to be a string, even though programs would really like to have a structured version. Should we offer a different property with structured stack frame info (probably with a getter to allow straight-forward lazy construction), called error.stackFrames or error.stackEntries or something?

Big +1 on that. Avoiding parsing information the engine has as discrete items already is a Good Thing(tm). Perhaps it'll be aspirational at first, but if specified now it'll happen eventually.

There has been some interest in trying to align the existing Error stack property and this proposal is about that.

Could we provide a new better alternative API? Of course. Feel free to come up with another proposal.

# Alex Vincent (12 years ago)

---------- Forwarded message ---------- From: Erik Arvidsson <erik.arvidsson at gmail.com> To: es-discuss at mozilla.org Cc: Date: Thu, 7 Jun 2012 11:37:41 -0700 Subject: Error stack I wrote a new strawman for Error stack which is now available in some form in all major browser (if betas are considered).

strawman:error_stack

Feedback wanted.

As the person who originally proposed the stack property to Mozilla over ten years ago, I am absolutely thrilled to see this as a strawman on Harmony. In any form.

For reference, the original bug is at bugzilla.mozilla.org/show_bug.cgi?id=123177 .

The only thing I might ask is to keep the ability to alter the stack - in a controlled way. Specifically, I've had occasion to want to remove the first two or three frames of an error stack, because I was implementing an assert() function. When the assert failed, I wanted the stack to start at the actual line of the assert call, instead of a couple of lines away (new Error(), then the assert function, and then the caller of assert). That said, I'd understand if the Harmony working group rejected this and required the property be read-only and never changeable.

Alex Vincent

# Charles Kendrick (12 years ago)

On Fri, Jun 8, 2012 at 5:38 AM, Patrick Mueller <pmuellr at gmail.com> wrote:

Personally, I'm happy with a user-land way of being able to generate something like this, in V8:

gist.github.com/312a55532fac0296f2ab

You can actually do this now in userland in Chrome (except the CoffeeScript aspect). This link was posted yesterday:

 http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi

.. but I've subsequently commented on the page with some working code since people were having trouble understanding how to get to the array of CallSite objects (it's a pretty bizarre API).

If there's issues dealing with recursion, or whatever, fine, just tell me what they are.

You can't get to function arguments for recursive functions (appears more than once on stack). I filed this bug on it, perhaps you'd like to "star" it:

http://code.google.com/p/v8/issues/detail?id=2169

Note: Erik just mentioned in passing that debugging APIs have security implications - this is potentially true for local variable access, but JavaScript VMs already have to handle correct security for access to function arguments due to the existing function.arguments API. So nothing new there in terms of risk or burden on the browser implementer.

I think that getting access to parm values/locals is interesting, but veering into the "land of the debugger".

Just to connect the dots, as I said previously, you don't have a debugger when you are looking at logs for an application you can't access. Programmatic access to this information is critical in that use case, but also extremely valuable just everyday - how many times have you seen an application get into an error state that you aren't sure how to reproduce, when you didn't happen to be in the debugger? If you had robust stack traces you'd have a lot more to go on.

With IE6 we solved dozens of bugs just from stack trace information. Ah the good old days! (yes that's sarcasm + irony)

I'd prefer a clean take on "debugging APIs" rather than evolve it from an exception back-trace use case.  When do we start talking about that?  I'm looking at you, --expose_debug_as (V8 option).

An Array of StackFrame / CallSite objects is pretty much a clean debugging API and not really something grafted on. The same concept appears in most debug APIs, eg Java's:

http://docs.oracle.com/javase/1.4.2/docs/guide/jpda/jdi/com/sun/jdi/StackFrame.html
# Brandon Benvie (12 years ago)

You can get the arguments. Here's an example of getting more info out of a try..catch: gist.github.com/2898384

Which results in error.stack being an array of objects like (function, arguments, and receiver are actual function/array/object)

{ function: <function>, name: "InjectedScript._evaluateOn", inferredName: "_evaluateOn", arguments: <Array[5]>, invocationType: "call", receiver: <receiver>, inferredType: "Object", origin: undefined, column: 33, line: 343, position: 12853, type: "file" };

# Erik Arvidsson (12 years ago)

On Fri, Jun 8, 2012 at 3:25 PM, Brandon Benvie <brandon at brandonbenvie.com> wrote:

You can get the arguments. Here's an example of getting more info out of a try..catch: gist.github.com/2898384

Which results in error.stack being an array of objects like (function, arguments, and receiver are actual function/array/object)

{   function: <function>,   name: "InjectedScript._evaluateOn",   inferredName: "_evaluateOn",   arguments: <Array[5]>,   invocationType: "call",   receiver: <receiver>,   inferredType: "Object",   origin: undefined,   column: 33,   line: 343,   position: 12853,   type: "file" };

Once again, exposing the actual arguments, receiver and function object references is a security issue and completely out of scope for this. This is not related to cross domain access but related to object capabilities.

Here is an example of when this would be a security issue:

function foo(secret) { 'use strict'; thirdPartyFunction(); }

...

function thirdPartyFunction() { getStackTrace(new Error)[1].arguments[0]; // oops I just leaked the secret. }

Any proposal that exposes argument values and/or object references are dead on arrival.

# Wes Garland (12 years ago)

It might be out of scope, but as a developer, I would almost give my left nut to have the kind of information in Brendan's example.

Even more so if it the browser guys made it available as an argument to the window.onerror callback.

# Charles Kendrick (12 years ago)

Once again, exposing the actual arguments, receiver and function object references is a security issue and completely out of scope for this. This is not related to cross domain access but related to object capabilities.

Erik how do you reconcile this with the fact that this information can already be obtained in most production browsers via stack walking?

Also, forgive my ignorance, but is it an explicit goal of the JavaScript language that two scripts in a web page from the same domain must not be able to discover each other's runtime arguments?

# Charles Kendrick (12 years ago)

No, this doesn't work.

When you are in the catch() block you can discover the arguments for the function that contains the catch block and for any (non-recursive) functions further up the stack. But you cannot discover the arguments for functions that were on the stack when the error happened, but have exited by the time you hop back to the catch block.

Your test happens to sidestep this because the catch block is in the function that throws the error. But the more important scenario is that a function somewhere down stack has crashed and you want to see what the arguments were when the crash occurred - because those are the arguments most valuable to know from a troubleshooting perspective.

My test code for the V8 issue demonstrates this problem:

http://code.google.com/p/v8/issues/detail?id=2169
# Brandon Benvie (12 years ago)

Oh I see, the arguments of the just function that throws is unset. I didn't get what you were saying at first.

# Charles Kendrick (12 years ago)

Almost - there are no arguments for the function that throws, as well as all functions between the function that throws and the one that catches.

# Erik Arvidsson (12 years ago)

On Fri, Jun 8, 2012 at 4:10 PM, Charles Kendrick <charles at isomorphic.com> wrote:

Once again, exposing the actual arguments, receiver and function object references is a security issue and completely out of scope for this. This is not related to cross domain access but related to object capabilities.

Erik how do you reconcile this with the fact that this information can already be obtained in most production browsers via stack walking?

Stack walking is not available in strict functions.

# Charles Kendrick (12 years ago)

On Fri, Jun 8, 2012 at 6:48 PM, Erik Arvidsson <erik.arvidsson at gmail.com> wrote:

On Fri, Jun 8, 2012 at 4:10 PM, Charles Kendrick <charles at isomorphic.com> wrote:

Once again, exposing the actual arguments, receiver and function object references is a security issue and completely out of scope for this. This is not related to cross domain access but related to object capabilities.

Erik how do you reconcile this with the fact that this information can already be obtained in most production browsers via stack walking?

Stack walking is not available in strict functions.

Interesting, but it doesn't speak against programmatic access to the call stack.

If "use strict" or any other security feature means that function.arguments are not accessible to a given script, then the same constraint could be trivially enforced with programmatic access to the call stack.

The same could be applied to access to the receiver or values of local variables. In fact, V8's CallSite API makes the receiver inaccessible for a strict mode function (I just checked).

# Brendan Eich (12 years ago)

Charles Kendrick wrote:

On Fri, Jun 8, 2012 at 6:48 PM, Erik Arvidsson<erik.arvidsson at gmail.com> wrote:

On Fri, Jun 8, 2012 at 4:10 PM, Charles Kendrick<charles at isomorphic.com> wrote:

Once again, exposing the actual arguments, receiver and function object references is a security issue and completely out of scope for this. This is not related to cross domain access but related to object capabilities. Erik how do you reconcile this with the fact that this information can already be obtained in most production browsers via stack walking? Stack walking is not available in strict functions.

Interesting, but it doesn't speak against programmatic access to the call stack.

But you wrote "how do you reconcile" and Erik answered. We do not want a non-debugger API that works only some of the time. Debuggers, in contrast, must be able to pierce the veil of "use strict".

Erik's proposal is for the string-valued .stack property.

A debugger API is further off from standardization. Mozilla has a new one:

Video: www.youtube.com/watch?v=WKIkOcuVG7w

wiki.mozilla.org/JSInspector, wiki.mozilla.org/Remote_Debugging_Protocol, wiki.mozilla.org/DevTools/Features/Debugger/Notes

This is in Firefox Nightlies now.

# Geoffrey Sneddon (12 years ago)

On 07/06/12 21:12, Jason Orendorff wrote:

On Thu, Jun 7, 2012 at 1:37 PM, Erik Arvidsson<erik.arvidsson at gmail.com> wrote:

I wrote a new strawman for Error stack which is now available in some form in all major browser (if betas are considered).

strawman:error_stack

Feedback wanted. This isn't machine parseable in all cases, since the .message may contain newlines and can end with something like "\n at ..."

Changing this in Firefox would affect any Firefox addons that use Error.stack, but maybe we can take that hit.

It's not just Firefox addons that will break: GWT's output relies upon the exact format of Error.stack1. I know Google Wave depended upon this, and I believe other Google applications do too.

As such, I'm somewhat dubious as to whether we can actually change the format that much without breaking sites. For reference, we support Error.stack (supposedly identical to SpiderMonkey in format, though obviously not) and Error.stacktrace (which is meant to actually be human readable). Originally, we had Error.stacktrace as Error.stack, but it just broke too much (we spoof UA on some Google sites by default, and have to choose whether to go down IE/Fx/WK code-path, and often all three rely upon non-standard behaviour).

# Erik Arvidsson (12 years ago)

On Sun, Jun 10, 2012 at 6:56 AM, Geoffrey Sneddon <gsneddon at opera.com> wrote:

As such, I'm somewhat dubious as to whether we can actually change the format that much without breaking sites. For reference, we support Error.stack (supposedly identical to SpiderMonkey in format, though obviously not) and Error.stacktrace (which is meant to actually be human readable). Originally, we had Error.stacktrace as Error.stack, but it just broke too much (we spoof UA on some Google sites by default, and have to choose whether to go down IE/Fx/WK code-path, and often all three rely upon non-standard behaviour).

This looks pretty broken to me as is. It does not seem to work correct for the V8 style formatting that is used by Chrome and IE.

The thing is that software on the open web has to handle two different formattings already to work correctly. The reason I picked the V8 style over the SpiderMonkey style is that the SpiderMonkey style is missing essential information like the column number which is a must these days. If we change the SpiderMonkey format we now have 3 incompatible formattings which is even worse.

We could give up on the stack property and introduce a new property that does not require parsing a string.

# T.J. Crowder (12 years ago)

On 10 June 2012 22:31, Erik Arvidsson <erik.arvidsson at gmail.com> wrote:

The thing is that software on the open web has to handle two different formattings already to work correctly. The reason I picked the V8 style over the SpiderMonkey style is that the SpiderMonkey style is missing essential information like the column number which is a must these days. If we change the SpiderMonkey format we now have 3 incompatible formattings which is even worse.

We could give up on the stack property and introduce a new property that does not require parsing a string.

FWIW, speaking as "Joe Developer," if it's really true that the current state of affairs is that there is no robust commonality, that would seem to be the appropriate way forward.

-- T.J.

# Oliver Hunt (12 years ago)

My original implementation in JSC was as an Array, but I found that there were sites that depended on .stack being a string if it was present. Any form of string encoding we expect to be machine parseable by necessity will require escaping and full format description. I've actually been tempted to switch JSC's current icky format into JSON on the basis that JSON is already well defined, and everyone has fast encoders and decoders for JSON these days.

# T.J. Crowder (12 years ago)

On 10 June 2012 22:44, Oliver Hunt <oliver at apple.com> wrote:

My original implementation in JSC was as an Array, but I found that there were sites that depended on .stack being a string if it was present. Any form of string encoding we expect to be machine parseable by necessity will require escaping and full format description. I've actually been tempted to switch JSC's current icky format into JSON on the basis that JSON is already well defined, and everyone has fast encoders and decoders for JSON these days.

Wouldn't changing the existing format of the string break existing code without offering any real benefit over continuing the existing format of that string (for now) but adding a new structured property that code could take advantage of? Not seeing much point in the browser generating JSON that just has to be decoded by anyone who wants to use it (fast or not).

-- T.J.

# Oliver Hunt (12 years ago)

There's no real consistency between any implementations of .stack. The only reason it needs to be a string is so that sites that blindly use .split() on it don't throw an exception.

If you used JSON you could do the following output: {"message":"...","trace":[ {"source":"...", line:...}, {"source":"...", line:...}, {"source":"...", line:...}, ... ]}

.split("\n") would provide a analogous result to the equivalent on current formats, with the added advantage of having automatically escaped anything that needs escaping (so each line in the trace would be guaranteed to be one line.

Better yet, because you're just saying "use JSON" it becomes perfectly possible to add additional fields (function name, inferred name, arguments, type,... whatever) without requiring re-specifying the format, or trying to add new fields without breaking existing parsers.

Note: this is just if we wanted to use .stack -- my original implementation was prefixed and just produced an array iirc, but i was convinced to use .stack so sites wouldn't have to manually select the stack property to use. This then broke many big sites that always do .split() on .stack, which didn't work as the result was not a string. Yay!

# Brendan Eich (12 years ago)

No commonality is a problem if enough content detects implementations and depends on each one's .stack. Not sure this is true, just sayin' (ignoring implementation-specific dependencies, e.g. addons).

The easy way out is Error.prototype.stackTrace, a getter that exposes, deeply and lazily, objects with string and number valued properties cleanly reflecting the desired information -- and without any capability leaks.

At this point, perhaps better is better. Any such stackTrace spec should not diverge too far from the various .stack implementations, in that one should be able to construct the latter from the fomer one true .stackTrace or .stackFrames or whatever it must be called.

# John Tamplin (12 years ago)

On Sun, Jun 10, 2012 at 5:31 PM, Erik Arvidsson <erik.arvidsson at gmail.com>wrote:

On Sun, Jun 10, 2012 at 6:56 AM, Geoffrey Sneddon <gsneddon at opera.com> wrote:

As such, I'm somewhat dubious as to whether we can actually change the format that much without breaking sites. For reference, we support Error.stack (supposedly identical to SpiderMonkey in format, though obviously not) and Error.stacktrace (which is meant to actually be human readable). Originally, we had Error.stacktrace as Error.stack, but it just broke too much (we spoof UA on some Google sites by default, and have to choose whether to go down IE/Fx/WK code-path, and often all three rely upon non-standard behaviour).

[1]:

code.google.com/p/google-web-toolkit/source/browse/releases/2.4/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java

This looks pretty broken to me as is. It does not seem to work correct for the V8 style formatting that is used by Chrome and IE.

Note that GWT uses deferred binding to substitute browser-specific implementations for the version being compiled -- see code.google.com/p/google-web-toolkit/source/browse/releases/2.4/user/src/com/google/gwt/core/CoreWithUserAgent.gwt.xml where the mappings are defined. So, for Chrome, CollectorChrome is used instead of Collector.

# John Tamplin (12 years ago)

On Sun, Jun 10, 2012 at 9:56 AM, Geoffrey Sneddon <gsneddon at opera.com>wrote:

It's not just Firefox addons that will break: GWT's output relies upon the exact format of Error.stack[1]. I know Google Wave depended upon this, and I believe other Google applications do too.

Note that GWT can supply different deferred-bound implementations for different browsers, though generally we do runtime detection rather than compile time if there are few differences between versions. Of course, that would only affect deployed apps if they recompiled, but I wouldn't expect that would be much of a problem for any currently maintained apps.

# Geoffrey Sneddon (12 years ago)

On 10/06/12 23:57, John Tamplin wrote:

On Sun, Jun 10, 2012 at 9:56 AM, Geoffrey Sneddon<gsneddon at opera.com>wrote:

It's not just Firefox addons that will break: GWT's output relies upon the exact format of Error.stack[1]. I know Google Wave depended upon this, and I believe other Google applications do too.

Note that GWT can supply different deferred-bound implementations for different browsers, though generally we do runtime detection rather than compile time if there are few differences between versions. Of course, that would only affect deployed apps if they recompiled, but I wouldn't expect that would be much of a problem for any currently maintained apps.

Well, the Wave team only shipped Gecko/WebKit code, so you had to be compatible with either one of the compile-time branches if you wanted to have a browser that supported Wave. The fact it can support different implementations is only relevant if people ship the code. :)

To be fair, I've only seen a few things that have relied upon Error.stack (all through GWT and not shipping all the various compile-time options!) and I think they were all Google sites, so hopefully they'd all be updated, allowing convergence of Error.stack implementations.

(Though it is perhaps saying about maintenance of that code that the Opera code-branch relies upon Futhark behaviour, which hasn't been shipped in desktop or mobile for over two years now, and the specific behaviour it relies on depends upon a non-standard pref setting that didn't even exist in mobile.)

# Mark S. Miller (12 years ago)

Oliver Hunt wrote:

[...] If you used JSON [...]

On Mon, Jun 11, 2012 at 6:35 AM, Brendan Eich <brendan at mozilla.org> wrote:

The easy way out is Error.prototype.stackTrace, a getter that exposes, deeply and lazily, objects with string and number valued properties cleanly reflecting the desired information -- and without any capability leaks.

At this point, perhaps better is better. Any such stackTrace spec should not diverge too far from the various .stack implementations, in that one should be able to construct the latter from the fomer one true .stackTrace or .stackFrames or whatever it must be called.

code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/debug.js#63

getCWStack(err) returns a JSON-able representation, but only to those that possess the getCWStack function, which is not generally available, as that would be a bad information leak (though still not a capability leak). getStack(err) at code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/debug.js#204 turns this back into a v8-like stack description string, but again only to those that possess the getStack function (which should be co-available with getCWStack). The overall debug.js file is a SES shim for retrofitting this behavior securely onto v8 and, to varying degrees, other browsers

# Charles Kendrick (12 years ago)

On Sat, Jun 9, 2012 at 12:26 PM, Brendan Eich <brendan at mozilla.org> wrote:

We do not want a non-debugger API that works only some of the time.

What we want (IMO) is an API that allows runtime diagnostics to be collected.

By necessity, function arguments would be unavailable for some stack frames.

This is not a new situation or a flaw in the proposal, it's a situation which exists already for the function.arguments API.

Debuggers, in contrast, must be able to pierce the veil of "use strict".

Clearly.

A debugger API is further off from standardization. Mozilla has a new one: ...

This is great but pretty much unrelated - clearly we shouldn't cripple a runtime diagnostic API because there's a debugger API - these are two different use cases.

Let's get concrete here - because function.arguments is actually available but not exposed by error.stack, we have implemented a system that parses error.stack, using its information to find live function instances, grabs the arguments and receiver from those and injects them into a new, enhanced stack trace which we log.

And of course we have to cover the recursive case and show the arguments as not available..

Because runtime diagnostic information like this is so critical, you'll see this approach being taken by a bunch of frameworks - don't you find this distasteful and a clear indication that the standard should be exposing this information directly?

# Brendan Eich (12 years ago)

Charles Kendrick wrote:

On Sat, Jun 9, 2012 at 12:26 PM, Brendan Eich<brendan at mozilla.org> wrote:

We do not want a non-debugger API that works only some of the time.

What we want (IMO) is an API that allows runtime diagnostics to be collected.

By necessity, function arguments would be unavailable for some stack frames.

This is not a new situation or a flaw in the proposal, it's a situation which exists already for the function.arguments API.

It seems to me we've lost the thread (maybe you haven't, but I have

# Charles Kendrick (12 years ago)

It seems to me we've lost the thread (maybe you haven't, but I have -- apologies for revisiting).

In a nutshell, I'm looking for access to function arguments, the receiver, and ideally even local variable values via some runtime diagnostic API.

These could be all be exposed in an error.stack String or in a more OO API (say, error.stackFrames as an array of objects with various properties).

I think the best solution is to have both. In the field right now, error.stack is a String. Adding error.stackFrames this would mean:

  1. we avoid breaking code in the field

  2. we provide a convenient error.stack for people who don't want to deal with error.stackFrames

  3. we avoid people who want to add richer information having to parse an error.stack String

  4. we eliminate all the issues we're running into in trying to standardize error.stack; it wouldn't be so important for it to expose more information or have really smart formatting rules like I previously proposed [1]. It would no longer need to be machine parsable. It might even be OK for it's format to remain completely unspecified since it's just a convenience.

The confusing bit: Erik objected to making arguments available in error.stack for security reasons, and Erik is correct that "use strict" implies arguments would not be available in that case.

However, I see no issue with error.stack or an error.stackFrames API providing function arguments only when allowed; it's not a new security issue or a new burden on browser / VM implementers since they must already correctly implement security checks for the equivalent function.arguments API.

[1] esdiscuss/2012-June/023247

# Brendan Eich (12 years ago)

I have a sinking feeling it may be better to do just error.stackFrames, the new object/number/string lazy stack-trace reflection. We can model it on the union of error.stack implementations in the field, so those could be reimplemented under/on-top-of error.stackFrames. But we'll have no compatibility problems to sort out, and fewer complaints about the string-valued property (it may be fine to remain underspecified or unspecified).

Your point about not violating "use strict" or elaborating too much is good, but I want to push back on one thing: local vars may be a bridge too far, especially with optimizing JITs, block-scoped let bindings, etc. Making arguments available is easier.

Erik, what do you think?

# Mark S. Miller (12 years ago)

On Tue, Jun 12, 2012 at 7:12 AM, Brendan Eich <brendan at mozilla.org> wrote:

Your point about not violating "use strict" or elaborating too much is good, but I want to push back on one thing: local vars may be a bridge too far, especially with optimizing JITs, block-scoped let bindings, etc. Making arguments available is easier.

Revealing secrets passed in arguments? C'mon. Making arguments generally available would be fatal. That's why you need something like the getStack function I suggested earlier: debugging info is accessed only by rights amplification, and the amplifier is not made generally available.

# Charles Kendrick (12 years ago)

Your point about not violating "use strict" or elaborating too much is good, but I want to push back on one thing: local vars may be a bridge too far, especially with optimizing JITs, block-scoped let bindings, etc. Making arguments available is easier.

I definitely recognize that making local vars available is different-in-kind from making function arguments available. However I would ideally like to see it mentioned in the spec with "recommended but not required" wording.

However what about receivers / "this" value? That seems to me to be more in the realm of function arguments, and reasonable to require. As I mentioned previously, this is available from Chrome's JavaScriptStackTrace API, but not for a function defined with "use strict".

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

On Tue, Jun 12, 2012 at 7:12 AM, Brendan Eich<brendan at mozilla.org> wrote:

Your point about not violating "use strict" or elaborating too much is good, but I want to push back on one thing: local vars may be a bridge too far, especially with optimizing JITs, block-scoped let bindings, etc. Making arguments available is easier.

Revealing secrets passed in arguments? C'mon.

I know, but see below.

Also, as you pointed out, even error.stack leaks information. Where do you draw the line?

Making arguments generally available would be fatal.

I think Charles was arguing that anyone keeping secrets would need "use strict" to protect those secrets anyway, because otherwise arguments.caller.arguments[i] (given non-strict caller and callee) can get them.

That's why you need something like the getStack function I suggested earlier: debugging info is accessed only by rights amplification, and the amplifier is not made generally available.

This is a good argument for Error.getStack(errObj), indeed.

# Mark S. Miller (12 years ago)

On Tue, Jun 12, 2012 at 7:38 AM, Brendan Eich <brendan at mozilla.org> wrote:

Also, as you pointed out, even error.stack leaks information. Where do you draw the line?

Conservatively. I suggest that there be no error.stack, but rather getStack(error), in order to avoid this information leak.

I think Charles was arguing that anyone keeping secrets would need "use strict" to protect those secrets anyway, because otherwise arguments.caller.arguments[i] (given non-strict caller and callee) can get them.

Non-strict functions should not be assumed to be encapsulated, so it would be ok if they leaked info in yet more ways. However, a stack consists of a mixture of strict and non-strict activations, so I don't see how this helps.

This is a good argument for Error.getStack(errObj), indeed.

Not Error.getStack. Error is generally available, so if the amplifier were Error.getStack, it would be generally available too.

This leaves open the question of where to get things that are not generally available. I hope and expect that we can find good answers in the module system. The getStack amplifier should be obtained by importing a module that is not generally importable. We've already encountered the need for such privileged imports...

# Charles Kendrick (12 years ago)

On Mon, Jun 11, 2012 at 4:51 PM, Mark S. Miller <erights at google.com> wrote:

On Tue, Jun 12, 2012 at 7:38 AM, Brendan Eich <brendan at mozilla.org> wrote:

I think Charles was arguing that anyone keeping secrets would need "use strict" to protect those secrets anyway, because otherwise arguments.caller.arguments[i] (given non-strict caller and callee) can get them.

Non-strict functions should not be assumed to be encapsulated, so it would be ok if they leaked info in yet more ways. However, a stack consists of a mixture of strict and non-strict activations, so I don't see how this helps.

It helps because, whether we are talking about a String API or an OO API, you make available arguments for non-strict functions, whereas for strict functions you do not.

This doesn't expose any more information than is already exposed by function.arguments.

This means a library using "use strict" and passing a secret to a non-strict function might have that secret revealed, and this is, again, already the case today (via function.arguments).

This is a good argument for Error.getStack(errObj), indeed.

Not Error.getStack. Error is generally available, so if the amplifier were Error.getStack, it would be generally available too.

This leaves open the question of where to get things that are not generally available. I hope and expect that we can find good answers in the module system. The getStack amplifier should be obtained by importing a module that is not generally importable. We've already encountered the need for such privileged imports...

I'm reading this as saying that stack traces in general should not be available unless the code is privileged in some way. This can't be what you mean, so could you clarify?

# Erik Arvidsson (12 years ago)

On Mon, Jun 11, 2012 at 4:12 PM, Brendan Eich <brendan at mozilla.org> wrote:

I have a sinking feeling it may be better to do just error.stackFrames, the new object/number/string lazy stack-trace reflection. We can model it on the union of error.stack implementations in the field, so those could be reimplemented under/on-top-of error.stackFrames. But we'll have no compatibility problems to sort out, and fewer complaints about the string-valued property (it may be fine to remain underspecified or unspecified).

Your point about not violating "use strict" or elaborating too much is good, but I want to push back on one thing: local vars may be a bridge too far, especially with optimizing JITs, block-scoped let bindings, etc. Making arguments available is easier.

Erik, what do you think?

Yes, at this point I'm also convince that we should provide a new property that provides structured information of the stack trace and not specify Error "stack" at all.

# Mark S. Miller (12 years ago)

On Tue, Jun 12, 2012 at 7:59 AM, Charles Kendrick <charles at isomorphic.com> wrote:

I'm reading this as saying that stack traces in general should not be available unless the code is privileged in some way.  This can't be what you mean, so could you clarify?

That is exactly what I mean.

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

On Tue, Jun 12, 2012 at 7:38 AM, Brendan Eich<brendan at mozilla.org> wrote:

Also, as you pointed out, even error.stack leaks information. Where do you draw the line?

Conservatively. I suggest that there be no error.stack, but rather getStack(error), in order to avoid this information leak.

With some kind of

import getStack from "@reflect";

or similar, and SES uses a custom loader to censor @reflect?

I think Charles was arguing that anyone keeping secrets would need "use strict" to protect those secrets anyway, because otherwise arguments.caller.arguments[i] (given non-strict caller and callee) can get them.

Non-strict functions should not be assumed to be encapsulated, so it would be ok if they leaked info in yet more ways. However, a stack consists of a mixture of strict and non-strict activations, so I don't see how this helps.

I thought so too, but Charles is arguing both (a) no worse than today (not better than today); (b) useful for people who prefer non-strict code and a more useful stack-tracing API in the core language.

This is a matter of preference, not necessity, if we're talking about the language as it is. We won't be making "use strict" the default. We are trying to avoid more modes (1JS). We're not talking about SES. So I don't see how it can be argued logically that a non-strict-only arguments-disclosing stack-tracing API is either never helpful nor always helpful. YMMV.

This is a good argument for Error.getStack(errObj), indeed.

Not Error.getStack. Error is generally available, so if the amplifier were Error.getStack, it would be generally available too.

This leaves open the question of where to get things that are not generally available. I hope and expect that we can find good answers in the module system. The getStack amplifier should be obtained by importing a module that is not generally importable. We've already encountered the need for such privileged imports...

Fromstrawman:weak_references: Pending an accepted modules proposal, we do not yet specify in what namespace this constructor [makeWeakRef] is found. Note that makeWeakRef is not safe for general access since it grants access to the non-determinism inherent in observing garbage collection. The resulting side channel reveals information that may violate the confidentiality assumptions of other programs.

I see -- thanks. We should try to detail the privileged APIs and their module(s) a bit more. I used "@reflect" above but I didn't mean to equate it to Tom's Reflect.* used in conjunction with direct proxies. And not all reflection facilities are privileged -- more the reverse for the direct proxy stuff, right?

# Charles Kendrick (12 years ago)

On Mon, Jun 11, 2012 at 5:55 PM, Mark S. Miller <erights at google.com> wrote:

On Tue, Jun 12, 2012 at 7:59 AM, Charles Kendrick <charles at isomorphic.com> wrote:

I'm reading this as saying that stack traces in general should not be available unless the code is privileged in some way.  This can't be what you mean, so could you clarify?

That is exactly what I mean.

The only way I can see this working is if there is a way for a given piece of code to trap an error and ask some kind of (elevated privilege) logging system to provide diagnostic information that a (privileged) end user can see. It also seems like, in addition to this, you should be able to get to stack information programmatically so long as you stay within your module or modules that have the same privilege.

This doesn't sound like something that could be reasonably standardized into ECMAScript in the near future, and, without all those pieces in place, it doesn't seem like ECMAScript should just disallow the ability to get stack traces.

Brendan brought up SES - I know little about it, but for its sake I hope this critical use case is taken into account.

On Mon, Jun 11, 2012 at 6:17 PM, Brendan Eich <brendan at mozilla.org> wrote:

I thought so too, but Charles is arguing both (a) no worse than today (not better than today); (b) useful for people who prefer non-strict code and a more useful stack-tracing API in the core language.

Just to clarify, I prefer some of the ideas behind "use strict" and in fact we built a subset of "use strict" into our in-house tools long before JSLint existed.

But if it's going to impose a security boundary between my own methods and reduce the utility of stack traces which are sometimes the only thing you have to go on.. no thank you. That seems to me to conflate useful error checking and security; there is overlap, but not 100% overlap by any means.

# Tom Van Cutsem (12 years ago)

2012/6/12 Brendan Eich <brendan at mozilla.org>

I see -- thanks. We should try to detail the privileged APIs and their module(s) a bit more. I used "@reflect" above but I didn't mean to equate it to Tom's Reflect.* used in conjunction with direct proxies. And not all reflection facilities are privileged -- more the reverse for the direct proxy stuff, right?

That's right. The reflection API specced at < harmony:reflect_api> was meant to

encapsulate both proxies and all the utility methods that a proxy handler needs to uniformly "forward" trapped ops to a target object. AFAICT, none of these operations are privileged: it's easy enough to define them in terms of more primitive, immediately available JS built-ins/operators.

# Mark S. Miller (12 years ago)

On Tue, Jun 12, 2012 at 9:17 AM, Brendan Eich <brendan at mozilla.org> wrote:

Mark S. Miller wrote:

On Tue, Jun 12, 2012 at 7:38 AM, Brendan Eich<brendan at mozilla.org>  wrote:

Also, as you pointed out, even error.stack leaks information. Where do you draw the line?

Conservatively. I suggest that there be no error.stack, but rather getStack(error), in order to avoid this information leak.

With some kind of

import getStack from "@reflect";

or similar, and SES uses a custom loader to censor @reflect?

Yes, that's the kind of thing I have in mind. Perhaps an @privileged?

This is a matter of preference, not necessity, if we're talking about the language as it is. We won't be making "use strict" the default. We are trying to avoid more modes (1JS). We're not talking about SES. So I don't see how it can be argued logically that a non-strict-only arguments-disclosing stack-tracing API is either never helpful nor always helpful. YMMV.

I'm not yet arguing that or the opposite, rather, I'm confused about what "non-strict-only" means in this context. Actual stacks consist of a mixture of strict and non-strict activations. How would the proposed API deal with that?

I see -- thanks. We should try to detail the privileged APIs and their module(s) a bit more. I used "@reflect" above but I didn't mean to equate it to Tom's Reflect.* used in conjunction with direct proxies. And not all reflection facilities are privileged -- more the reverse for the direct proxy stuff, right?

yup. JS is an amazingly reflective language. We've taken care in both the ES5 and ES6 efforts that all reflective operations uphold the ocap security of strict functions -- so far without needing a special @privileged module. getStack and makeWeakRef are the first reflective operations that do require some such privilege separation.

Given an @privileged module and a desire to inspect the arguments of non-strict activations, we should consider whether @privileged should also grant the ability to inspect the arguments of strict activations.

Is @privileged per global context (frame)? If so, does it only provide privileges over objects from that same global context? Or is it more like browser chrome js vs page js, where special chrome privileges apply to all page js objects it encounters? Might we eventually standardize a module that provides all the privileges needed to implement a portable debugger? Is it appropriate for the language to define multiple kinds of privilege-granting modules, or should the language delegate this to the host?

# Mark S. Miller (12 years ago)

On Tue, Jun 12, 2012 at 10:14 AM, Charles Kendrick <charles at isomorphic.com> wrote:

On Mon, Jun 11, 2012 at 5:55 PM, Mark S. Miller <erights at google.com> wrote:

On Tue, Jun 12, 2012 at 7:59 AM, Charles Kendrick <charles at isomorphic.com> wrote:

I'm reading this as saying that stack traces in general should not be available unless the code is privileged in some way.  This can't be what you mean, so could you clarify?

That is exactly what I mean.

The only way I can see this working is if there is a way for a given piece of code to trap an error and ask some kind of (elevated privilege) logging system to provide diagnostic information that a (privileged) end user can see.

I'm not sure what you mean by "trap to an error", but the rest of your description seems close to how SES's console.log, console.warn, etc work. They are endowed with access to the privileged getStack function and use it to display stack traces on the console's output. See code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/logger.js#28, code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/logger.js#157, code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/useHTMLLogger.js#116

We assume that unprivileged code generally has no way to read the console's output.

It also seems like, in addition to this, you should be able to get to stack information programmatically so long as you stay within your module or modules that have the same privilege.

If we're talking about code with some privilege to see some stacks, why not reify such privilege in a getStack function importable from some @privileged module? If you don't reify this distinction, then you're suggesting above that an access be dependent on the module from which the access is directly made. What if the access is made indirectly through some intermediary? Does it then fail, even though all other accesses can be delegated to the same intermediary? If the access is simply a property access,

function intermediary(base, name) { return base[name]; }

defined in some other module.

This doesn't sound like something that could be reasonably standardized into ECMAScript in the near future, and, without all those pieces in place, it doesn't seem like ECMAScript should just disallow the ability to get stack traces.

In this thread, we've already considered APIs other than ".stack". Given anything else, why is getStack(err) is any worse than introducing a novel property name?

Regarding near future, any such proposal -- whether ".stack", getStack, or whatever -- has already missed the boat for ES6. getStack certainly could be considered in an ES7 timeframe.

Brendan brought up SES - I know little about it, but for its sake I hope this critical use case is taken into account.

Yes. The code I link to above dates from February.

On Mon, Jun 11, 2012 at 6:17 PM, Brendan Eich <brendan at mozilla.org> wrote:

I thought so too, but Charles is arguing both (a) no worse than today (not better than today); (b) useful for people who prefer non-strict code and a more useful stack-tracing API in the core language.

Just to clarify, I prefer some of the ideas behind "use strict" and in fact we built a subset of "use strict" into our in-house tools long before JSLint existed.

But if it's going to impose a security boundary between my own methods and reduce the utility of stack traces which are sometimes the only thing you have to go on.. no thank you.  That seems to me to conflate useful error checking and security; there is overlap, but not 100% overlap by any means.

How do getStack and @privileged reduce the utility of stack traces? Regarding access to arguments, depending on how much privilege @privileged should give (see questions at end of my previous email), it is conceivable that it should give access to strict arguments as well. Or that there be an @turbo_privileged that grants this additional level of access. Until we have some experience using the module system on both browser and server, these issues are hard to think about.

# Andreas Rossberg (12 years ago)

On 12 June 2012 01:36, Charles Kendrick <charles at isomorphic.com> wrote:

Your point about not violating "use strict" or elaborating too much is good, but I want to push back on one thing: local vars may be a bridge too far, especially with optimizing JITs, block-scoped let bindings, etc. Making arguments available is easier.

I definitely recognize that making local vars available is different-in-kind from making function arguments available.  However I would ideally like to see it mentioned in the spec with "recommended but not required" wording.

I would also push back very hard on this. Besides semantic issues, it would screw compilers, because (among other things) it requires extending liveness of all local variables till the end of their scope (or at least till after its last impure operation). The effect on performance would be significant, I'm sure.

"Recommended but not required" gives you the worst of both worlds: the user cannot rely on the feature, and the implementer is not relieved from the pressure to eventually implement it anyway.

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

I'm not yet arguing that or the opposite, rather, I'm confused about what "non-strict-only" means in this context. Actual stacks consist of a mixture of strict and non-strict activations.

This isn't so in personal projects or even all-homegrown products or shared projects that eschew "use strict", as Charles wrote.

How would the proposed API deal with that?

Eliding strict frames' arguments, Charles wrote.

I objected that this makes any such stack trace API hard to use in the large, compared to an information-leaking string-valued .stack approach.

# Charles Kendrick (12 years ago)

On Tue, Jun 12, 2012 at 5:19 AM, Mark S. Miller <erights at google.com> wrote:

On Tue, Jun 12, 2012 at 10:14 AM, Charles Kendrick <charles at isomorphic.com> wrote:

The only way I can see this working is if there is a way for a given piece of code to trap an error and ask some kind of (elevated privilege) logging system to provide diagnostic information that a (privileged) end user can see.

I'm not sure what you mean by "trap to an error",

My actual words were "to trap an error" so that probably explains the confusion :)

but the rest of your description seems close to how SES's console.log, console.warn, etc work. They are endowed with access to the privileged getStack function and use it to display stack traces on the console's output. See code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/logger.js#28, code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/logger.js#157, code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/useHTMLLogger.js#116

Yes, this is the pattern I had in mind. This also means there would be no need to worry about exposing too much information in a stack trace.

It also seems like, in addition to this, you should be able to get to stack information programmatically so long as you stay within your module or modules that have the same privilege.

If we're talking about code with some privilege to see some stacks, why not reify such privilege in a getStack function importable from some @privileged module?

I don't have an objection to this being treated as an import.

This doesn't sound like something that could be reasonably standardized into ECMAScript in the near future, and, without all those pieces in place, it doesn't seem like ECMAScript should just disallow the ability to get stack traces.

In this thread, we've already considered APIs other than ".stack". Given anything else, why is getStack(err) is any worse than introducing a novel property name?

There's no problem with the API being changed to a getter method as opposed to error.stack / error.stackFrames.

It would be a problem for access to a stack trace to require @import or other features that are not yet present in all mainstream browsers. If browser implementers cannot add this feature to engines which are basically only ES4/5, it's not going to be usable for mainstream code until 2019 or something - in reality, non-standard APIs will continue to be implemented and used.

Regarding near future, any such proposal -- whether ".stack", getStack, or whatever -- has already missed the boat for ES6. getStack certainly could be considered in an ES7 timeframe.

Fortunately, these milestones have little to do with when features appear in browsers. And this is one of those features where it's valuable the moment it appears in just one browser.

All we really need is clear consensus, so as to influence browser vendors' existing efforts in this area.

Just to clarify, I prefer some of the ideas behind "use strict" and in fact we built a subset of "use strict" into our in-house tools long before JSLint existed.

But if it's going to impose a security boundary between my own methods and reduce the utility of stack traces which are sometimes the only thing you have to go on.. no thank you.  That seems to me to conflate useful error checking and security; there is overlap, but not 100% overlap by any means.

How do getStack and @privileged reduce the utility of stack traces?

They don't. The above discussion is about "use strict" and is not about SES.