hiding stack trace elements?

96 views
Skip to first unread message

Jochen Theodorou

unread,
Nov 25, 2009, 7:31:04 AM11/25/09
to jvm-la...@googlegroups.com
Hi all,

I thought we should maybe some time talk about the stack traces java
gives. A typical problem for Groovy is, that you a huge trace, which is
of no interest to the user. What is commonly done is to catch the
exception somewhere, edit the array to remove the unwanted elements and
throw it again. This problem applies not only to Groovy, but also to
almost any framework. Now in languages such as Groovy it is very common
to generate helper function in bytecode. But usually I want those to not
to show up. Also my runtime should not really show up to a normal user.
Even Java has several helper methods, that then show up in the trace.

Wouldn't it be possible to give an method an attribute so it will no add
that stack frame to the exception? Is there a problem for the VM to do that?

bye Jochen

--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/

Charles Oliver Nutter

unread,
Nov 30, 2009, 1:21:57 PM11/30/09
to jvm-languages
On Wed, Nov 25, 2009 at 6:31 AM, Jochen Theodorou <blac...@gmx.org> wrote:
> I thought we should maybe some time talk about the stack traces java
> gives. A typical problem for Groovy is, that you a huge trace, which is
> of no interest to the user. What is commonly done is to catch the
> exception somewhere, edit the array to remove the unwanted elements and
> throw it again. This problem applies not only to Groovy, but also to
> almost any framework. Now in languages such as Groovy it is very common
> to generate helper function in bytecode. But usually I want those to not
> to show up. Also my runtime should not really show up to a normal user.
> Even Java has several helper methods, that then show up in the trace.
>
> Wouldn't it be possible to give an method an attribute so it will no add
> that stack frame to the exception? Is there a problem for the VM to do that?

Hello Jochen!

Yes, blasted stack traces...they are a pain to cope with for sure.
JRuby and Jython are probably the only two widely-used JVM languages
that present *nice* stack traces, but we pay a price for it. In JRuby,
we have to maintain a separate frame stack that we push and pop on
call and return. We do this to pass data across calls outside the call
stack (like some "out"-style implicit variables for regexp matching,
etc), but also to maintain only the pertinent information for Ruby
backtraces. So if you have this code:

~/projects/jruby ➔ cat trace.rb
def foo
bar
end

def bar
baz
end

def baz
raise
end

foo

You get this lovely trace:

~/projects/jruby ➔ jruby trace.rb
trace.rb:10:in `baz': unhandled exception
from trace.rb:6:in `bar'
from trace.rb:2:in `foo'
from trace.rb:13

Where the full-on Java trace would be considerably larger (at the end
of this email, because it's so large). We obviously pay a cost for
maintaining these artificial stack frames (2-3x more overhead per call
compared to an empty ruby method with no artificial framing), but I
believe the usability benefits of nice, clean traces outweighs the
cost...for now.

We have implemented a few other options for generating backtraces. The
most promising is to structure our generated method handles and
bytecode-compiled bodies to have method names we can mine out of the
normal Java trace.

You'll note in the Java trace below that method handles and Ruby
method names are specifically structured to be tokenizable into
appropriate pieces for the backtrace, as in "method__2$RUBY$baz". When
an exception needs to be raised from Ruby code, we can pull the Java
trace, look for any elements with RUBY in them, and then pull out only
the relevant information.

This actually works pretty well for compiled code, and produces
nearly-identical traces. Here's an example of a trace generated
entirely from Java backtrace element parsing rather than from our
artificial frames:

~/projects/jruby ➔ jruby --fast trace.rb
trace.rb:10:in `baz': unhandled exception
from trace.rb:6:in `bar'
from trace.rb:2:in `foo'

Where it breaks down, however, is in handling interpreter backtraces.
Since interpretation will always be a part of Ruby applications (eval
is definitely used), we need to have an option that also includes
interpreted frames. So we also have a backtrace mode that looks for
trace elements known to be interpreter entry-points, and the backtrace
builder then pops off frames as it sees them.

Obviously both of these techniques are a bit cumbersome, and they're
both definitely experimental.

I am also interested in ways to improve this situation, and I know
Clojure and Scala users/devs would like it two (both have large and
unfriendly backtraces, similar to Groovy).

- Charlie

Neal Gafter

unread,
Nov 30, 2009, 11:00:28 PM11/30/09
to jvm-la...@googlegroups.com
On Wed, Nov 25, 2009 at 4:31 AM, Jochen Theodorou <blac...@gmx.org> wrote:
Wouldn't it be possible to give an method an attribute so it will no add
that stack frame to the exception? Is there a problem for the VM to do that?

The .NET platform uses this solution.  You put an attribute (the equivalent to a Java annotation) on the methods that you don't want to appear in the stack trace, and the VM does the rest.

Cheers,
Neal

Kjetil Valstadsve

unread,
Dec 1, 2009, 3:32:58 AM12/1/09
to jvm-la...@googlegroups.com
May I humbly (and maybe somewhat panickedly) suggest retaining an option to override such an annotation? Given some developers' reluctance to volunteer error information already, I dread giving them the tools to suppress and throw out what's already there, in the name of misunderstood information hiding.

I realize this is meant for all the "infrastructure" layers (of which Groovy is one), giving focus to the business logic and nicing up the user-petrifying stacktraces you get when e.g. multiple layers of dynamic proxies are involved. But this assumes that the error is never in THAT part, which may only be true after considerable maturing of the code. 

Anyway, today we have a of getting out the full stacktrace programmatically, so it can be preserved in full when that makes sense. I just want to point out the real need for keeping that as it is. Everyone probably agrees, but - just in case. In the meantime, hacking a nice, custom stacktrace display using said functionality isn't really that hard, either. 

Sorry for rambling on, I'll go get coffee now.

Kjetil

Jochen Theodorou

unread,
Dec 1, 2009, 5:02:52 AM12/1/09
to jvm-la...@googlegroups.com
Neal Gafter schrieb:
yeah, thought .NET would have a solution for this. And I agree with
Kjetil Valstadsve, that it would good to have an option to turn it off
too. I wonder what problem the JVM could have with that. It is not like
stack frames are not generated or removed like you may want it for tail
recursion. This problem should be much more easy to solve. Maybe I
should do a RFE?

John Wilson

unread,
Dec 1, 2009, 6:13:23 AM12/1/09
to jvm-la...@googlegroups.com
2009/12/1 Jochen Theodorou <blac...@gmx.org>:
> Neal Gafter schrieb:
>> On Wed, Nov 25, 2009 at 4:31 AM, Jochen Theodorou <blac...@gmx.org
>> <mailto:blac...@gmx.org>> wrote:
>>
>>     Wouldn't it be possible to give an method an attribute so it will no add
>>     that stack frame to the exception? Is there a problem for the VM to
>>     do that?
>>
>>
>> The .NET platform uses this solution.  You put an attribute (the
>> equivalent to a Java annotation) on the methods that you don't want to
>> appear in the stack trace, and the VM does the rest.
>
> yeah, thought .NET would have a solution for this. And I agree with
> Kjetil Valstadsve, that it would good to have an option to turn it off
> too. I wonder what problem the JVM could have with that. It is not like
> stack frames are not generated or removed like you may want it for tail
> recursion. This problem should be much more easy to solve. Maybe I
> should do a RFE?


Perhaps the exception cold contain two stack traces - a full and an
edited one. The edited one would be the default but the full one could
be accessed if needed.

John Wilson

Daniel Hicks

unread,
Dec 1, 2009, 7:34:25 AM12/1/09
to JVM Languages
On the JVMs I worked on there was an internal attribute that did this,
but it wasn't exposed. I'm guessing there's one in Sun's
implementation as well.

On Nov 30, 10:00 pm, Neal Gafter <n...@gafter.com> wrote:

Daniel Hicks

unread,
Dec 1, 2009, 7:37:19 AM12/1/09
to JVM Languages
Amen. I've worked on too many systems where there was no way to get a
stack trace other than by decoding a hex dump, and Java is to be
lauded for building in such a good mechanism. Certainly it could be
improved, but it could much more easily be rendered useless, and that
would be a crime.

On Dec 1, 2:32 am, Kjetil Valstadsve <valstad...@gmail.com> wrote:
> On 2009-12-01, at 5:00 , Neal Gafter wrote:
>

Daniel Hicks

unread,
Dec 1, 2009, 7:40:34 AM12/1/09
to JVM Languages
In our implementation, and, I'm pretty sure, in Sun's, the "stack
trace" contained in the exception is an array of code addresses, and
the details aren't extracted until the trace is materialized. What
you really want is an alternative way to materialize the array.

On Dec 1, 5:13 am, John Wilson <tugwil...@gmail.com> wrote:
> 2009/12/1 Jochen Theodorou <blackd...@gmx.org>:

John Wilson

unread,
Dec 1, 2009, 7:53:30 AM12/1/09
to jvm-la...@googlegroups.com
2009/12/1 Daniel Hicks <jvm...@gmail.com>:
> In our implementation, and, I'm pretty sure, in Sun's, the "stack
> trace" contained in the exception is an array of code addresses, and
> the details aren't extracted until the trace is materialized.  What
> you really want is an alternative way to materialize the array.


I think what I really want is some more methods on Throwable (e.g.
getFullStackTrace and the various flavours of printFullStackTrace).

The internal details of the way in which the stack trace array is
constructed is a matter for the JVM implementers and I would not want
to unnecessarily constrain them.

John Wilson

Kjetil Valstadsve

unread,
Dec 1, 2009, 8:09:42 AM12/1/09
to jvm-la...@googlegroups.com
To be clear: All I want is that Throwable's methods, in particular:

StackTraceElement[] getStackTrace()
Throwable getCause()

continue to work exactly as they have, unaffected by any upcoming annotations. This strikes me as the wrong forum for talking about such changes anyway, but I felt compelled to nip it in the bud (or at least point out the bud) in case the meme travels from here to spheres more influental ... (I guess everyone remembers how ClassCastException suddenly stopped reporting the actual class!)

Kjetil
> --
>
> You received this message because you are subscribed to the Google Groups "JVM Languages" group.
> To post to this group, send email to jvm-la...@googlegroups.com.
> To unsubscribe from this group, send email to jvm-language...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en.
>
>

Rémi Forax

unread,
Dec 1, 2009, 8:38:36 AM12/1/09
to jvm-la...@googlegroups.com
Daniel Hicks a �crit :
> On the JVMs I worked on there was an internal attribute that did this,
> but it wasn't exposed. I'm guessing there's one in Sun's
> implementation as well.
>

As far as I know, there isn't such attribute in hotspot,
hidden stack frame method are hardcoded.

R�mi

Daniel Hicks

unread,
Dec 1, 2009, 10:00:19 PM12/1/09
to JVM Languages
Still reported it on our platform.

Attila Szegedi

unread,
Dec 9, 2009, 12:39:00 PM12/9/09
to jvm-la...@googlegroups.com
On 2009.11.30., at 18:21, Charles Oliver Nutter wrote:

> Yes, blasted stack traces...they are a pain to cope with for sure.
> JRuby and Jython are probably the only two widely-used JVM languages
> that present *nice* stack traces

Rhino, in interpreted mode, will inject script stack elements into the Java stack elements, so above every org.mozilla.javascript.Interpreter.interpret() element, you'll have all the JS frames the interpreter created, with an appropriate syntax (function name + source code name + line number; obviously the class name doesn't apply...).

Here's a stack trace from an edit/run debug cycle iteration from my actual work from last week; with client names stripped out. You can see we actually have two interpreter invocations - Array.forEach() is implementing in Java and is thus traversing Java code, and the JS stack frames are correctly injected in their places. The script elements are "at script...":

org.mozilla.javascript.EcmaError: TypeError: Cannot find function getAlertId in object [object Object]. (http://localhost:8080/applications/*************/3.0/main.js#19)
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3753)
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3731)
at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3759)
at org.mozilla.javascript.ScriptRuntime.typeError2(ScriptRuntime.java:3778)
at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3842)
at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2343)
at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2310)
at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:1515)
at script(http://localhost:8080/applications/*************/3.0/main.js:19)
at script(jar:http://localhost:8080/platform/7.2.0/tools/tools.jar!/com/*******7/workflow/alert/callbacks.js:81)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:845)
at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
at org.mozilla.javascript.NativeArray.iterativeMethod(NativeArray.java:1559)
at org.mozilla.javascript.NativeArray.execIdCall(NativeArray.java:340)
at org.mozilla.javascript.IdFunctionObject.call(IdFunctionObject.java:129)
at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:1702)
at script(jar:http://localhost:8080/platform/7.2.0/tools/tools.jar!/com/*******7/workflow/alert/callbacks.js:80)
at script(jar:http://localhost:8080/platform/7.2.0/tools/tools.jar!/com/*******7/workflow/alert/alert.js:84)
at script(http://localhost:8080/applications/*************/3.0/main.js:27)
at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:845)
at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:426)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3157)
at org.mozilla.javascript.Context.callFunctionWithContinuations(Context.java:1204)
at org.mozilla.javascript.Context.executeScriptWithContinuations(Context.java:1171)
...

Attila.

Attila Szegedi

unread,
Dec 9, 2009, 12:49:49 PM12/9/09
to jvm-la...@googlegroups.com
I would agree - I've been involved in pretty-printing stack traces in two of my projects; in the previous post, I mentioned Rhino and how its exceptions interweave JS and Java stack frames.

A different approach we took with FreeMarker is that the exceptions first print an error message in plain English and a stack trace in terms of the native programming language (FreeMarker Template Language in this case), and below it, visually distinguished, the Java stack trace, in case the developer wishes to check it. We make it explicit that the topmost information - FreeMarker stack trace - is more useful to template developers, and the bottom information - Java stack trace - is advanced info that might be more useful to Java developers. So far, people seem to really like the format.

Examples are abundant on the web as FreeMarker is quite widely used, here's one I found through googling for "Java backtrace for programmers" @ <http://www.ambraproject.org/trac/ticket/1275>. You can see how FreeMarker provides a logical trace through only those elements that are actually helpful in locating the bug: includes and macro/function invocations:

2009-04-28 12:20:04,196 ERROR runtime(PLoSONE)> [http-8080-Processor24 freemarker.runtime]
Expression currentIssue is undefined on line 31, column 26 in journals/plosone/article/browseVolume.ftl.
The problematic instruction:
----------
==> ${currentIssue.id} [on line 31, column 24 in journals/plosone/article/browseVolume.ftl]
in user-directive s.url [on line 30, column 9 in journals/plosone/article/browseVolume.ftl]
in include "${templateFile}" [on line 31, column 1 in templates/main_template.ftl]
----------

Java backtrace for programmers:
----------
freemarker.core.InvalidReferenceException: Expression currentIssue is undefined on line 31, column 26 in journals/plosone/article/browseVolume.ftl.
at freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124)
at freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:134)
...

Attila.

Charles Oliver Nutter

unread,
Dec 9, 2009, 12:55:24 PM12/9/09
to jvm-languages
On Wed, Dec 9, 2009 at 11:39 AM, Attila Szegedi <szeg...@gmail.com> wrote:
> On 2009.11.30., at 18:21, Charles Oliver Nutter wrote:
>
>> Yes, blasted stack traces...they are a pain to cope with for sure.
>> JRuby and Jython are probably the only two widely-used JVM languages
>> that present *nice* stack traces
>
> Rhino, in interpreted mode, will inject script stack elements into the Java stack elements, so above every org.mozilla.javascript.Interpreter.interpret() element, you'll have all the JS frames the interpreter created, with an appropriate syntax (function name + source code name + line number; obviously the class name doesn't apply...).

I'm not sure I'd call that *nice* but it does at least include
information you would otherwise be missing. A couple of JRuby's
stacktrace modes will do the same thing, but in our case we actually
omit the interpreter frames in place of the actual code's frames.

I don't want to complicate the potential RFE too much, but there's
actually two cases we need to support:

* Being able to omit elements from the backtraces
* Being able to add or replace elements in the backtrace

Both of these currently require either post-processing (slow) or
artificial call stacks (slow). We have modes using both techniques in
JRuby, and it's frustrating for us that our desire to produce nice
stack traces for our users means we're often slower (in default modes)
than other JVM dynlangs. With that stuff turned off, we're very nearly
the fastest dynlang.

So yes, we would love to see a lighter-weight way to help the JVM
produce "nice" stack traces.

Is there a debugger hook we might be able to use in some situations? I
know the automatic argument against that would be "nobody will run
debug mode in production", but the counter to that is "nobody will run
Java 7 + nice-stacktrace-support in production either." Something that
*works* in the short term could help bootstrap a future JSR or RFE,
even if it's based on debug mode that most folks won't use.

- Charlie

Hannes Wallnoefer

unread,
Dec 9, 2009, 1:06:51 PM12/9/09
to jvm-la...@googlegroups.com
2009/12/9 Attila Szegedi <szeg...@gmail.com>:
> On 2009.11.30., at 18:21, Charles Oliver Nutter wrote:
>
>> Yes, blasted stack traces...they are a pain to cope with for sure.
>> JRuby and Jython are probably the only two widely-used JVM languages
>> that present *nice* stack traces
>
> Rhino, in interpreted mode, will inject script stack elements into the Java stack elements, so above every org.mozilla.javascript.Interpreter.interpret() element, you'll have all the JS frames the interpreter created, with an appropriate syntax (function name + source code name + line number; obviously the class name doesn't apply...).

Not to forget the getScriptStackTrace() method in RhinoException. This
works in both compiled and interpreted mode, and returns a (synthetic)
stack trace including only the script sources. In Helma NG the
developer is usually presented two dedicated stack traces as shown
below. I think this is much preferable to messing with the actual
stack trace which diminishes its usefulness for the language
implementor.

ReferenceError: "foo" is not defined.
Script Stack
at actions.js:67
at helma/webapp.js:97
at helma/webapp.js:47
at helma/middleware/notfound.js:10
at helma/middleware/error.js:13
at helma/middleware/responselog.js:26
at helma/middleware/etag.js:15
at helma/middleware/gzip.js:15
at helma/jsgi.js:31
Java Stack
org.mozilla.javascript.EcmaError: ReferenceError: "foo" is not
defined. (actions.js#67)
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3753)
at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3731)
at org.mozilla.javascript.ScriptRuntime.notFoundError(ScriptRuntime.java:3816)
at org.mozilla.javascript.ScriptRuntime.nameOrFunction(ScriptRuntime.java:1826)
at org.mozilla.javascript.ScriptRuntime.name(ScriptRuntime.java:1765)
at org.mozilla.javascript.gen.actions_js_29._c_logging_7(actions.js:67)
at org.mozilla.javascript.gen.actions_js_29.call(actions.js)
...

Hannes

Charles Oliver Nutter

unread,
Dec 9, 2009, 2:26:05 PM12/9/09
to jvm-languages
On Wed, Dec 9, 2009 at 12:06 PM, Hannes Wallnoefer <han...@gmail.com> wrote:
>> Rhino, in interpreted mode, will inject script stack elements into the Java stack elements, so above every org.mozilla.javascript.Interpreter.interpret() element, you'll have all the JS frames the interpreter created, with an appropriate syntax (function name + source code name + line number; obviously the class name doesn't apply...).
>
> Not to forget the getScriptStackTrace() method in RhinoException. This
> works in both compiled and interpreted mode, and returns a (synthetic)
> stack trace including only the script sources. In Helma NG the
> developer is usually presented two dedicated stack traces as shown
> below. I think this is much preferable to messing with the actual
> stack trace which diminishes its usefulness for the language
> implementor.
>
> ReferenceError: "foo" is not defined.
> Script Stack
>        at actions.js:67
>        at helma/webapp.js:97
>        at helma/webapp.js:47
>        at helma/middleware/notfound.js:10
>        at helma/middleware/error.js:13
>        at helma/middleware/responselog.js:26
>        at helma/middleware/etag.js:15
>        at helma/middleware/gzip.js:15
>        at helma/jsgi.js:31

Can one of you describe how this is done internally in Rhino? We
obviously have the same challenge in JRuby (and probably in Jython
too) but you may have a simpler or more efficient way to do it.

- Charlie

Tobias Ivarsson

unread,
Dec 9, 2009, 3:06:11 PM12/9/09
to jvm-la...@googlegroups.com
If you have a point where you can intercept the exception (such as a catch-block where you rethrow the exception, or if it's an exception type you control, you can do it when it is constructed) you can use the getStackTrace and setStackTrace methods to extract the stack-trace and create a new one that better reflects your language.

I'm guessing Rhino does something like that, but I would love to get enlightened on either a better way of doing it or the details on how it's done.

We currently don't do this in Jython, but we might experiment with doing it in the future. In Jython today we do the same thing you do in JRuby - we keep our own stack of heap-allocated frame objects and construct our own python-traceback from that.

Here is a link to code from another project I'm involved with that does filtering of stack traces to not expose the generated glue-methods and internals of the runtime:

/Tobias

Hannes Wallnoefer

unread,
Dec 9, 2009, 3:56:38 PM12/9/09
to jvm-la...@googlegroups.com
2009/12/9 Charles Oliver Nutter <hea...@headius.com>:
It's really rather a low-tech approach.
RhinoException.getScriptStackTrace() loops through the exception's
stack trace and tries to pick only those elements that represent a
script source. It returns a String with the rendered stack trace, not
an array of stack trace elements, so its only purpose is to be shown
to a human being.

The hardest part is merging compiled and interpreted code, which can
be on the stack at the same time. For compiled code, it's easy - we
just check the StackTraceElement's fileName against a file name
pattern, which is *.js by default but you can define your own
java.io.FilenameFilter if you want.

For interpreted code it's a bit harder. The interpreter keeps its own
call frame stack and when a RhinoException is initialized the
interpreter fills in its current stack. Now when walking the java
stack in getScriptStackTrace(), we simply look for frames that
represent the interpreter loop (method "interpretLoop" in class
"org.mozilla.javascript.Interpreter"). If there is a matching
interpreter stack frame as there should be, we fill in its file name
and line number.

As I said, the approach is simple and pragmatical, but it works well
for what it is supposed to do.

Hannes

Charles Oliver Nutter

unread,
Dec 9, 2009, 4:09:49 PM12/9/09
to jvm-languages
On Wed, Dec 9, 2009 at 2:56 PM, Hannes Wallnoefer <han...@gmail.com> wrote:
> It's really rather a low-tech approach.
> RhinoException.getScriptStackTrace() loops through the exception's
> stack trace and tries to pick only those elements that represent a
> script source. It returns a String with the rendered stack trace, not
> an array of stack trace elements, so its only purpose is to be shown
> to a human being.
>
> The hardest part is merging compiled and interpreted code, which can
> be on the stack at the same time. For compiled code, it's easy - we
> just check the StackTraceElement's fileName against a file name
> pattern, which is *.js by default but you can define your own
> java.io.FilenameFilter if you want.
>
> For interpreted code it's a bit harder. The interpreter keeps its own
> call frame stack and when a RhinoException is initialized the
> interpreter fills in its current stack. Now when walking the java
> stack in getScriptStackTrace(), we simply look for frames that
> represent the interpreter loop (method "interpretLoop" in class
> "org.mozilla.javascript.Interpreter"). If there is a matching
> interpreter stack frame as there should be, we fill in its file name
> and line number.

Ok...sounds about like what we do in JRuby, though we generally still
also maintain a stack for compiled code too (since we're mixed-mode
jitting code at runtime). We seek to eliminate that artificial
framing, but it's harder to maintain a nice backtrace without it.

- Charlie
Reply all
Reply to author
Forward
0 new messages