Message->PrintCurrentStackTrace not really useful

157 views
Skip to first unread message

Sébastien Pierre

unread,
Jun 2, 2009, 11:04:33 AM6/2/09
to v8-u...@googlegroups.com
Hi all,

I've been playing with producing dev-friendly stack traces, and I've found PrintCurrentStackTrace is pretty much the only way without getting too deep into V8 internals. I setup this very simple test script (named fail.js)

function f() {
    function f2() {
        MAKE.ME.FAIL;
    }
    f2()
}
f()

However, the only stack trace that is printed by PrintCurrentStackTrace is

    at #<an Object>.command

( #<an Object>.command being the JS snippet that reads the file and evals it)

While I would expect the stack to be like:

    at fail.js:5 f2()

    at fail.js:7 f()
    at #<an Object>.command

Is there a way to get the invocation stack in a similar way (even without the source code and line) ?

Thanks !

 -- Sébastien

Stephan Beal

unread,
Jun 2, 2009, 11:25:54 AM6/2/09
to v8-u...@googlegroups.com
2009/6/2 Sébastien Pierre <sebastie...@gmail.com>:

>     at #<an Object>.command
>
> ( #<an Object>.command being the JS snippet that reads the file and evals
> it)

i had similar problems when evaling an include()d file and had to do
some hopping around with the exception catching to make it work how i
wanted. See:

http://code.google.com/p/v8-juice/source/browse/trunk/src/lib/juice/juice.cc

in the IncludeScript() function. Inside the do{...}while(false) loop
you'll see some weird stuff with copying an exception object. That
approach allowed me to get the exception back into my main script,
with line numbers and whatnot intact. No idea if all this is really
required, but "it worked for me."

--
----- stephan beal
http://wanderinghorse.net/home/stephan/

Sébastien Pierre

unread,
Jun 2, 2009, 2:25:11 PM6/2/09
to v8-u...@googlegroups.com
I tried doing the same thing as you in your code

    HandleScope handle_scope;
    Handle<Value> exception;
    do {
        TryCatch try_catch;

        // FIXME: The following two may degrade performance. Benchmarks needed !
        try_catch.SetCaptureMessage(true);
        try_catch.SetVerbose(true);

        String::Utf8Value utf8_value(source);

        Handle<Script> script = Script::Compile(source, fromFileName);
        if (script.IsEmpty()) {
            // Print errors that happened during compilation.
            exception = try_catch.Exception();
            //k7::trace(&try_catch);
            //return false;
        }
        Handle<Value> result = script->Run();
        if (result.IsEmpty()) {
            // Print errors that happened during execution.
            exception = try_catch.Exception();
            //k7::trace(&try_catch);
            //return false;
        }
    } while (false);
    if ( !exception.IsEmpty() ) {
        ThrowException(exception);
        return false;
    }
    return true;

but the result is exactly the same as with the previous version... is there something I'm not doing properly ?

 -- Sébastien

Stephan Beal

unread,
Jun 2, 2009, 4:59:23 PM6/2/09
to v8-u...@googlegroups.com
2009/6/2 Sébastien Pierre <sebastie...@gmail.com>:

> I tried doing the same thing as you in your code
...

> but the result is exactly the same as with the previous version... is there
> something I'm not doing properly ?

Doh... after looking more closely: At the catch() point i'm getting
the name of eval()'d file and the byte offset of the error, but not an
informational stacktrace. My apologies for the misdirection.

Sébastien Pierre

unread,
Jun 2, 2009, 5:36:57 PM6/2/09
to v8-u...@googlegroups.com
Ah, OK :/

Any guidance from the V8 dev team ?

 -- Sébastien

ryan dahl

unread,
Jun 8, 2009, 12:17:12 PM6/8/09
to v8-u...@googlegroups.com
> Any guidance from the V8 dev team ?

I'm also interested in this problem.

Christian Plesner Hansen

unread,
Jun 9, 2009, 7:11:35 AM6/9/09
to v8-u...@googlegroups.com
I suspect the reason you don't get the full stack trace is that you
call PrintCurrentStackTrace after the stack has been unwound. If you
use V8::AddMessageListener to add a message callback you will get a
callback before the stack is unwound and PrintCurrentStackTrace should
give you the full stack.

This is not a pretty solution though. The "proper" way to do this
would be to capture the stack trace in the message object at the point
when the exception is thrown and then printing it when the vm has
bailed out and returned to your code. We had an implementation of
that but there were some problems with it so I disabled it.
Eventually we should finish that and reenable that so you don't need
to use AddMessageListener.


-- Christian

Sébastien Pierre

unread,
Jun 11, 2009, 12:24:21 PM6/11/09
to v8-u...@googlegroups.com
Hi Christian,

I've tried your solution by registering a message listener, which is called properly when the program fails because of an exception.

However a call to "message->PrintCurrentStackTrace()" does not print the full stack trace, instead, I still get:


    at #<an Object>.command

instead of


    at fail.js:5 f2()

    at fail.js:7 f()
    at #<an Object>.command

Where the "#<an Object>.command" is a function that loads a file from the disc, reads it and feeds it to V8 for evaluation -- so it seems like PrintCurrentStackTrace does not see what's happening inside the evaluated source code.

The evaluation function used by the command function is this one:
---
Handle<Value> k7::eval (Handle<String> source, Handle<Value> fromFileName) {
    if (source->Length() == 0) return JS_undefined;
    HandleScope handle_scope;
    // FIXME: We disabled this, as we registered a V8 message listener
    //TryCatch try_catch;
    String::Utf8Value utf8_value(source);

    Handle<Script> script = Script::Compile(source, fromFileName);
    if (script.IsEmpty()) {
        // FIXME: We disabled this, as we registered a V8 message listener
        //k7::trace(&try_catch);
        return JS_undefined;

    }
    Handle<Value> result = script->Run();
    if (result.IsEmpty()) {
        // FIXME: We disabled this, as we registered a V8 message listener
        //k7::trace(&try_catch);
        return JS_undefined;
    }
    return result;
}
---

Am I missing something ?

Overall, it seems like PrintStackTrace does not really see the invocation stack, or that the message is perceived after the stack is unwind. Is there an opened ticket for the feature you mention ?

 -- Sébastien

Czarek Tomczak

unread,
Sep 29, 2012, 2:01:33 PM9/29/12
to v8-u...@googlegroups.com, sebastie...@gmail.com
I have the same problem, when handling exception through MessageCallback registered with v8::AddMessageListener, you cannot get original stack trace of the error, instead you get an empty stack trace, seems like the original context is unwound. The only way to get stack trace is to call v8::V8::SetCaptureStackTraceForUncaughtExceptions(true, 10, v8::StackTrace::kDetailed) while initializing v8. Then you can call message->GetStackTrace() to get real stack trace of the error. But I heard that SetCaptureStackTraceForUncaughtExceptions is not recommended as it might cause integration problems with Inspector. So is this the only way?

Czarek.
Reply all
Reply to author
Forward
0 new messages