Enable the embedder to provide stack trace printing

BUG=none
R=yangguo@chromium.org

Change-Id: I53811859efacee9126ba1bdbe5690793833c96e1
Reviewed-on: https://chromium-review.googlesource.com/456338
Commit-Queue: Jochen Eisinger <jochen@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43892}
This commit is contained in:
Jochen Eisinger 2017-03-17 12:41:30 +01:00 committed by Commit Bot
parent 6934d92220
commit 876725d5d5
8 changed files with 43 additions and 7 deletions

View File

@ -212,6 +212,14 @@ class Platform {
/** Removes tracing state change observer. */
virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
typedef void (*StackTracePrinter)();
/**
* Returns a function pointer that print a stack trace of the current stack
* on invocation. Disables printing of the stack trace if nullptr.
*/
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
};
} // namespace v8

View File

@ -38,7 +38,7 @@ V8_BASE_EXPORT void DisableSignalStackDump();
// A stacktrace can be helpful in debugging. For example, you can include a
// stacktrace member in a object (probably around #ifndef NDEBUG) so that you
// can later see where the given object was created from.
class StackTrace {
class V8_BASE_EXPORT StackTrace {
public:
// Creates a stacktrace from the current location.
StackTrace();

View File

@ -13,6 +13,16 @@
namespace v8 {
namespace base {
namespace {
void (*g_print_stack_trace)() = nullptr;
} // namespace
void SetPrintStackTrace(void (*print_stack_trace)()) {
g_print_stack_trace = print_stack_trace;
}
// Explicit instantiations for commonly used comparisons.
#define DEFINE_MAKE_CHECK_OP_STRING(type) \
template std::string* MakeCheckOpString<type, type>(type, type, char const*);
@ -57,11 +67,8 @@ extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) {
va_end(arguments);
v8::base::OS::PrintError("\n#\n");
v8::base::debug::StackTrace trace;
trace.Print();
if (v8::base::g_print_stack_trace) v8::base::g_print_stack_trace();
fflush(stderr);
// Avoid dumping stack trace on abort signal.
v8::base::debug::DisableSignalStackDump();
v8::base::OS::Abort();
}

View File

@ -37,6 +37,9 @@ extern "C" PRINTF_FORMAT(3, 4) V8_NORETURN V8_BASE_EXPORT
namespace v8 {
namespace base {
// Overwrite the default function that prints a stack trace.
V8_BASE_EXPORT void SetPrintStackTrace(void (*print_stack_trace_)());
// CHECK dies with a fatal error if condition is not true. It is *not*
// controlled by DEBUG, so the check will be executed regardless of
// compilation mode.

View File

@ -24,7 +24,6 @@
#include "include/libplatform/v8-tracing.h"
#include "src/api.h"
#include "src/base/cpu.h"
#include "src/base/debug/stack_trace.h"
#include "src/base/logging.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/time.h"
@ -2893,7 +2892,6 @@ static void DumpHeapConstants(i::Isolate* isolate) {
int Shell::Main(int argc, char* argv[]) {
std::ofstream trace_file;
v8::base::debug::EnableInProcessStackDumping();
#if (defined(_WIN32) || defined(_WIN64))
UINT new_flags =
SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;

View File

@ -8,6 +8,7 @@
#include <queue>
#include "include/libplatform/libplatform.h"
#include "src/base/debug/stack_trace.h"
#include "src/base/logging.h"
#include "src/base/platform/platform.h"
#include "src/base/platform/time.h"
@ -17,8 +18,20 @@
namespace v8 {
namespace platform {
namespace {
void PrintStackTrace() {
v8::base::debug::StackTrace trace;
trace.Print();
// Avoid dumping duplicate stack trace on abort signal.
v8::base::debug::DisableSignalStackDump();
}
} // namespace
v8::Platform* CreateDefaultPlatform(int thread_pool_size,
IdleTaskSupport idle_task_support) {
v8::base::debug::EnableInProcessStackDumping();
DefaultPlatform* platform = new DefaultPlatform(idle_task_support);
platform->SetThreadPoolSize(thread_pool_size);
platform->EnsureInitialized();
@ -278,5 +291,9 @@ void DefaultPlatform::RemoveTraceStateObserver(TraceStateObserver* observer) {
tracing_controller_->RemoveTraceStateObserver(observer);
}
Platform::StackTracePrinter DefaultPlatform::GetStackTracePrinter() {
return PrintStackTrace;
}
} // namespace platform
} // namespace v8

View File

@ -72,6 +72,7 @@ class V8_PLATFORM_EXPORT DefaultPlatform : public NON_EXPORTED_BASE(Platform) {
void AddTraceStateObserver(TraceStateObserver* observer) override;
void RemoveTraceStateObserver(TraceStateObserver* observer) override;
StackTracePrinter GetStackTracePrinter() override;
private:
static const int kMaxThreadPoolSize;

View File

@ -95,6 +95,7 @@ void V8::InitializePlatform(v8::Platform* platform) {
CHECK(!platform_);
CHECK(platform);
platform_ = platform;
v8::base::SetPrintStackTrace(platform_->GetStackTracePrinter());
v8::tracing::TracingCategoryObserver::SetUp();
}
@ -102,6 +103,7 @@ void V8::InitializePlatform(v8::Platform* platform) {
void V8::ShutdownPlatform() {
CHECK(platform_);
v8::tracing::TracingCategoryObserver::TearDown();
v8::base::SetPrintStackTrace(nullptr);
platform_ = NULL;
}