How to get the stack trace of the caught exception?

4,943 views
Skip to first unread message

Tom Yeh

unread,
Jan 11, 2013, 5:38:30 AM1/11/13
to mi...@dartlang.org
I'd like to print the stack trace of a caught exception (for debugging purpose), but I can't find the right method. Anyone knows it?

Ladislav Thon

unread,
Jan 11, 2013, 5:58:30 AM1/11/13
to mi...@dartlang.org

I'd like to print the stack trace of a caught exception (for debugging purpose), but I can't find the right method. Anyone knows it?

There is no such thing, an exception in Dart doesn't carry a stacktrace. Also note that you can throw any object, not only an exception.

But the stacktrace actually is available, you just have to add a second identifier to the catch clause:

main() {
  try {
    throw "Boo!";
  } catch (e, s) {
    print("Caught: $e");
    print("Stack: $s");
  }
}

Note that the object s is of no ordinary class and the only meaningful operation you can do with it is calling toString().

LT

Eric J. Smith

unread,
Jan 11, 2013, 11:41:42 AM1/11/13
to mi...@dartlang.org
The way you get the stacktrace seems a bit odd.  I guess this is because you can throw any object?

Also, along these lines, is there a way to capture (and log) unhandled exceptions with stacktraces in dart?

Bob Nystrom

unread,
Jan 11, 2013, 11:49:10 AM1/11/13
to General Dart Discussion

On Fri, Jan 11, 2013 at 8:41 AM, Eric J. Smith <er...@codesmithtools.com> wrote:
The way you get the stacktrace seems a bit odd.  I guess this is because you can throw any object?

Lars and co. spent a bunch of time implementing JVMs. Once thing they discovered is that generating and attaching the stack trace to the exception object took time and often wasn't used by the code that catches the exception.

They wanted to avoid that overhead with Dart, so they pulled it out into a separate parameter. When an exception is thrown, the VM walks the callstack to see if any catch clauses will grab the stack trace. If they don't, it doesn't generate it.

As far as I know, it was done purely as a performance optimization.

- bob

Ladislav Thon

unread,
Jan 11, 2013, 11:51:04 AM1/11/13
to mi...@dartlang.org

The way you get the stacktrace seems a bit odd.  I guess this is because you can throw any object?

I think so. Also, collecting a stacktrace isn't always needed -- and when the catch clause doesn't contain the second identifier (and when there isn't a rethrow), Dart implementation can optimize out the stacktrace collection.
 
Also, along these lines, is there a way to capture (and log) unhandled exceptions with stacktraces in dart?

No, at least not right now. Please don't try to put a "global" try/catch into the main function, because that only works if your code is completely synchronous. Since Dart promotes asynchrony very much, the main function usually terminates early and most of the code actually executes outside of the main function.

There is a feature request for it, though: http://dartbug.com/5958

LT

Tom Ball

unread,
Jan 11, 2013, 1:47:02 PM1/11/13
to mi...@dartlang.org
Java exceptions need to be highly optimized because the JVM team learned that no matter how often the "don't use exceptions for flow control" advice was uttered, developers will still occasionally do it.  And by developers, that includes the JVM team itself as there are sun.* classes that still do it to this day.  So optimizing exception handling is important, regardless of how informed its developers might be. :-)

Tom


--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
 
 

Gilad Bracha

unread,
Jan 11, 2013, 2:01:10 PM1/11/13
to General Dart Discussion
"Exception-oriented programming" is a fact of life, and it is unrealistic to assume otherwise.
--
Cheers, Gilad

Ladislav Thon

unread,
Jan 11, 2013, 2:09:32 PM1/11/13
to mi...@dartlang.org
I'm playing with it a little bit and it seems that it doesn't exactly work. Running this program

boo() {
  try {
    throw "Boo!";
  } catch (e, s) {
    print("Caught: $e");
    print("Stack: $s");
  }
}

main() => boo();

produces

Caught: Boo!
Stack: #0      boo (file:///home/ladicek/work/dart/projects/playground/stack.dart:3:5)

on this version of standalone Dart VM:

ladicek@argondie:~/work/dart/projects/playground$ dart --version
Dart VM version: 0.1.2.0_r16973 (Fri Jan 11 06:09:19 2013)


I know there was at least one discussion about this, whether the stacktrace should contain only those stack frames between the throw and the catch or all frames on the stack. Right now, it seems to be the first variant, but I believe that the spec says that it should be the second one; see 13.10:

The active stack trace is an object whose toString() method produces a string that is a record of exactly those function activations within the current isolate that had not completed execution at the point where the current exception was thrown.

Oh, and I actually found bugs filed! If anyone is interested:


LT
Reply all
Reply to author
Forward
0 new messages