Simon, thanks for the clarification. Does this mean that there's no 
reliable way to get this information with the current V8 public API?

I went ahead and wrote a simple example illustrating the issue and tried 
running it on different platforms. And the results were surprising.

Here's the sample code I wrote:

    Isolate::CreateParams create_params;
    create_params.array_buffer_allocator = &allocator_;
    Isolate* isolate = Isolate::New(create_params);
    Isolate::Scope isolate_scope(isolate);
    HandleScope handle_scope(isolate);
    Local<ObjectTemplate> globalTemplate = ObjectTemplate::New(isolate);
    Local<Context> context = Context::New(isolate, nullptr, globalTemplate);
    context->Enter();

    Local<v8::Function> captureFunc = v8::Function::New(context, [](const 
FunctionCallbackInfo<Value>& info) {
        Isolate* isolate = info.GetIsolate();
        Local<Context> context = isolate->GetCurrentContext();
        Local<Object> exception = 
Exception::Error(v8::String::NewFromUtf8(isolate, "", 
NewStringType::kNormal, 0).ToLocalChecked()).As<Object>();
        Local<Value> stackProperty = exception->Get(context, 
v8::String::NewFromUtf8(isolate, "stack", NewStringType::kNormal, 
5).ToLocalChecked()).ToLocalChecked();
        v8::String::Utf8Value stackStr(isolate, stackProperty);
        printf("%s\n\n", *stackStr);
        
        Local<StackTrace> stack = 
v8::StackTrace::CurrentStackTrace(isolate, 10, 
v8::StackTrace::StackTraceOptions::kDetailed);

        for (int i = 0; i < stack->GetFrameCount(); i++) {
            Local<v8::StackFrame> frame = stack->GetFrame(isolate, i);
            Local<v8::String> funcName = frame->GetFunctionName();
            v8::String::Utf8Value str(isolate, funcName);
            const char* name = *str;
            printf("%s (%d:%d)\n", name, frame->GetLineNumber(), 
frame->GetColumn());
        }
    }).ToLocalChecked();
    assert(context->Global()->Set(context, v8::String::NewFromUtf8(isolate, 
"captureTrace", NewStringType::kNormal, 12).ToLocalChecked(), 
captureFunc).FromMaybe(false));

    std::string src =
        "(function test() {"
        "    const viewModel = new Object();"
        "    viewModel.onTap = () => { captureTrace(); };"
        "    viewModel.onTap.apply(viewModel, []);"
        "})();";
    Local<Script> script = Script::Compile(context, 
v8::String::NewFromUtf8(isolate, src.c_str(), NewStringType::kNormal, 
(int)src.length()).ToLocalChecked()).ToLocalChecked();
    Local<Value> result;
    assert(script->Run(context).ToLocal(&result));

On V8 8.0.0 
(https://chromium.googlesource.com/v8/v8.git/+/50031fae736fac7b2b309369df492bfd0edd7553),
 
running in --jitless on an arm64 iOS device, I get the following output:

Error
    at Object.onTap (<anonymous>:1:84)
    at test (<anonymous>:1:122)
    at <anonymous>:1:145

(null) (1:84)
test (1:122)
(null) (1:145)

and on V8 7.7.299.11 
(https://chromium.googlesource.com/v8/v8.git/+/027689dbfcb2a9bbc8ceec4db2631c558e879633),
 
running on an arm64 Android device, I get the following output:

Error
        at Object.viewModel.onTap (<anonymous>:1:84)
        at test (<anonymous>:1:122)
        at <anonymous>:1:145

viewModel.onTap (1:84)
test (1:122)
(null) (1:145)

Do you know what might explain the discrepancy between those two platforms?

On Tuesday, November 19, 2019 at 7:58:10 AM UTC+2, Simon Zünd wrote:
>
> This is a bug in our API implementation. Or better, there is a mismatch 
> between API and what we do internally. "Method names" and "class names" are 
> stored separately from function names. This can be seen here, when we 
> collect all the information for a single frame: 
> https://cs.chromium.org/chromium/src/v8/src/heap/factory.cc?rcl=e1eb815647f334a8cf970439343a8febfa9f6d11&l=3732
>
> There is really no reason why this information shouldn't be made available 
> in the API. The only tricky thing is to come up with a better API, as some 
> of the getters change meaning depending whether its a JS or WASM frame and 
> I am not really happy with the current solution.
>
> On Mon, Nov 18, 2019 at 4:40 PM Darin Dimitrov <darin....@gmail.com 
> <javascript:>> wrote:
>
>> I am embedding V8 and trying to capture the current javascript stacktrace 
>> using the "v8::StackTrace::CurrentStackTrace":
>>
>> Isolate* isolate = info.GetIsolate();
>>
>> Local<StackTrace> stack = v8::StackTrace::CurrentStackTrace(isolate, 10, 
>> v8::StackTrace::StackTraceOptions::kDetailed);
>>
>> *for* (*int* i = 0; i < stack->GetFrameCount(); i++) {
>>
>>     Local<v8::StackFrame> frame = stack->GetFrame(isolate, i);
>>
>>     Local<v8::String> funcName = frame->GetFunctionName();
>>
>>     v8::String::Utf8Value str(isolate, funcName);
>>
>>     *const* *char** name = *str;
>>
>>     printf("%s (%d:%d)\n", name, frame->GetLineNumber(), frame->GetColumn
>> ());
>>
>> }
>>
>> I have placed this code inside a custom function that I have registered 
>> to the global scope.
>>
>> Before calling my custom function, I tried logging the stack property of 
>> an Error object (by using : console.log(new Error().stack)) and I obtained 
>> the following output:
>>
>> Error
>>     at bar (file:///app/bundle.js:266:29)
>>     at test (file:///app/bundle.js:267:15)
>>     at Observable.onTap (file:///app/bundle.js:268:11)
>>     at Button.notify (file:///app/vendor.js:3620:32)
>>     at Button._emit (file:///app/vendor.js:3640:18)
>>     at TapHandlerImpl.tap (file:///app/vendor.js:15540:19)
>>
>> With the "v8::StackTrace::CurrentStackTrace" method I get:
>>
>> bar (266:29)
>> test (267:15)
>> (null) (268:11)
>> (null) (3620:32)
>> (null) (3640:18)
>> (null) (15540:19)
>>
>> I am getting empty function names from some frames, while all the other 
>> information is present (script name, line, column numbers, ...).
>>
>> Do you know what might be the reason for getting empty function names?
>>
>> -- 
>> -- 
>> v8-users mailing list
>> v8-u...@googlegroups.com <javascript:>
>> http://groups.google.com/group/v8-users
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "v8-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to v8-u...@googlegroups.com <javascript:>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/v8-users/64d9e4ca-b271-4d83-aace-753c28e193f4%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/v8-users/64d9e4ca-b271-4d83-aace-753c28e193f4%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>  

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/v8-users/4584bfec-aa64-4a6f-9a81-e3b0e8808b0d%40googlegroups.com.

Reply via email to