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) ?
2009/6/2 Sébastien Pierre <sebastien.pie...@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:
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."
On Tue, Jun 2, 2009 at 11:25 AM, Stephan Beal <sgb...@googlemail.com> wrote:
> 2009/6/2 Sébastien Pierre <sebastien.pie...@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:
> 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."
2009/6/2 Sébastien Pierre <sebastien.pie...@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.
On Tue, Jun 2, 2009 at 4:59 PM, Stephan Beal <sgb...@googlemail.com> wrote:
> 2009/6/2 Sébastien Pierre <sebastien.pie...@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.
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.
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
On Tue, Jun 9, 2009 at 7:11 AM, Christian Plesner Hansen <
> 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
> On Mon, Jun 8, 2009 at 6:17 PM, ryan dahl<coldredle...@gmail.com> wrote:
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?
On Thursday, June 11, 2009 6:24:21 PM UTC+2, Sébastien Pierre wrote:
> 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 ?