From 2b9a533d1d40f7111ca3ca41c261c8bec92d3123 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 26 Sep 2013 13:31:17 +0800 Subject: [PATCH] Add process.getCurrentStackTrace(), returning V8::getCurrentStackTrace(). --- common/api/atom_bindings.cc | 38 ++++++++++++++++++++++++++++++++++++++ common/api/atom_bindings.h | 1 + common/v8_conversions.h | 4 ++++ 3 files changed, 43 insertions(+) diff --git a/common/api/atom_bindings.cc b/common/api/atom_bindings.cc index 32afe3b..3216232 100644 --- a/common/api/atom_bindings.cc +++ b/common/api/atom_bindings.cc @@ -7,17 +7,35 @@ #include "base/debug/debugger.h" #include "base/logging.h" #include "common/atom_version.h" +#include "common/v8_conversions.h" #include "vendor/node/src/node.h" namespace atom { namespace { +static int kMaxCallStackSize = 200; // Same with WebKit. + static uv_async_t dummy_uv_handle; void UvNoOp(uv_async_t* handle, int status) { } +v8::Handle DumpStackFrame(v8::Handle stack_frame) { + v8::Local result = v8::Object::New(); + result->Set(ToV8Value("line"), ToV8Value(stack_frame->GetLineNumber())); + result->Set(ToV8Value("column"), ToV8Value(stack_frame->GetColumn())); + + v8::Handle script = stack_frame->GetScriptName(); + if (!script.IsEmpty()) + result->Set(ToV8Value("script"), script); + + v8::Handle function = stack_frame->GetScriptNameOrSourceURL(); + if (!function.IsEmpty()) + result->Set(ToV8Value("function"), function); + return result; +} + } // namespace // Defined in atom_extensions.cc. @@ -37,6 +55,7 @@ void AtomBindings::BindTo(v8::Handle process) { node::SetMethod(process, "crash", Crash); node::SetMethod(process, "activateUvLoop", ActivateUVLoop); node::SetMethod(process, "log", Log); + node::SetMethod(process, "getCurrentStackTrace", GetCurrentStackTrace); process->Get(v8::String::New("versions"))->ToObject()-> Set(v8::String::New("atom-shell"), v8::String::New(ATOM_VERSION_STRING)); @@ -111,4 +130,23 @@ v8::Handle AtomBindings::Log(const v8::Arguments& args) { return v8::Undefined(); } +// static +v8::Handle AtomBindings::GetCurrentStackTrace( + const v8::Arguments& args) { + v8::HandleScope scope; + + int stack_limit = kMaxCallStackSize; + FromV8Arguments(args, &stack_limit); + + v8::Local stack_trace = v8::StackTrace::CurrentStackTrace( + stack_limit, v8::StackTrace::kDetailed); + + int frame_count = stack_trace->GetFrameCount(); + v8::Local result = v8::Array::New(frame_count); + for (int i = 0; i < frame_count; ++i) + result->Set(i, DumpStackFrame(stack_trace->GetFrame(i))); + + return scope.Close(result); +} + } // namespace atom diff --git a/common/api/atom_bindings.h b/common/api/atom_bindings.h index 31b0152..84fc098 100644 --- a/common/api/atom_bindings.h +++ b/common/api/atom_bindings.h @@ -24,6 +24,7 @@ class AtomBindings { static v8::Handle Crash(const v8::Arguments& args); static v8::Handle ActivateUVLoop(const v8::Arguments& args); static v8::Handle Log(const v8::Arguments& args); + static v8::Handle GetCurrentStackTrace(const v8::Arguments& args); DISALLOW_COPY_AND_ASSIGN(AtomBindings); }; diff --git a/common/v8_conversions.h b/common/v8_conversions.h index c59a88a..bd5f72a 100644 --- a/common/v8_conversions.h +++ b/common/v8_conversions.h @@ -77,6 +77,10 @@ inline v8::Handle ToV8Value(bool b) { return v8::Boolean::New(b); } +inline v8::Handle ToV8Value(const char* s) { + return v8::String::New(s); +} + inline v8::Handle ToV8Value(const std::string& s) { return v8::String::New(s.data(), s.size()); } -- 2.7.4