Add CefV8ContextHandler::OnUncaughtException callback (issue #736).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@857 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
cd03d80623
commit
f51f171b43
|
@ -71,6 +71,17 @@ typedef struct _cef_v8context_handler_t {
|
||||||
void (CEF_CALLBACK *on_context_released)(
|
void (CEF_CALLBACK *on_context_released)(
|
||||||
struct _cef_v8context_handler_t* self, struct _cef_browser_t* browser,
|
struct _cef_v8context_handler_t* self, struct _cef_browser_t* browser,
|
||||||
struct _cef_frame_t* frame, struct _cef_v8context_t* context);
|
struct _cef_frame_t* frame, struct _cef_v8context_t* context);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Called for global uncaught exceptions. Execution of this callback is
|
||||||
|
// disabled by default. To enable set
|
||||||
|
// CefSettings.uncaught_exception_stack_size > 0.
|
||||||
|
///
|
||||||
|
void (CEF_CALLBACK *on_uncaught_exception)(
|
||||||
|
struct _cef_v8context_handler_t* self, struct _cef_browser_t* browser,
|
||||||
|
struct _cef_frame_t* frame, struct _cef_v8context_t* context,
|
||||||
|
struct _cef_v8exception_t* exception,
|
||||||
|
struct _cef_v8stack_trace_t* stackTrace);
|
||||||
} cef_v8context_handler_t;
|
} cef_v8context_handler_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,18 @@ class CefV8ContextHandler : public virtual CefBase {
|
||||||
virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
|
virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
|
||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
CefRefPtr<CefV8Context> context) {}
|
CefRefPtr<CefV8Context> context) {}
|
||||||
|
|
||||||
|
///
|
||||||
|
// Called for global uncaught exceptions. Execution of this callback is
|
||||||
|
// disabled by default. To enable set
|
||||||
|
// CefSettings.uncaught_exception_stack_size > 0.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual void OnUncaughtException(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefV8Context> context,
|
||||||
|
CefRefPtr<CefV8Exception> exception,
|
||||||
|
CefRefPtr<CefV8StackTrace> stackTrace) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_INCLUDE_CEF_V8CONTEXT_HANDLER_H_
|
#endif // CEF_INCLUDE_CEF_V8CONTEXT_HANDLER_H_
|
||||||
|
|
|
@ -210,6 +210,14 @@ typedef struct _cef_settings_t {
|
||||||
// is disabled.
|
// is disabled.
|
||||||
///
|
///
|
||||||
bool pack_loading_disabled;
|
bool pack_loading_disabled;
|
||||||
|
|
||||||
|
///
|
||||||
|
// The number of stack trace frames to capture for uncaught exceptions.
|
||||||
|
// Specify a positive value to enable the CefV8ContextHandler::
|
||||||
|
// OnUncaughtException() callback. Specify 0 (default value) and
|
||||||
|
// OnUncaughtException() will not be called.
|
||||||
|
///
|
||||||
|
int uncaught_exception_stack_size;
|
||||||
} cef_settings_t;
|
} cef_settings_t;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
|
@ -299,6 +299,7 @@ struct CefSettingsTraits {
|
||||||
cef_string_set(src->locales_dir_path.str, src->locales_dir_path.length,
|
cef_string_set(src->locales_dir_path.str, src->locales_dir_path.length,
|
||||||
&target->locales_dir_path, copy);
|
&target->locales_dir_path, copy);
|
||||||
target->pack_loading_disabled = src->pack_loading_disabled;
|
target->pack_loading_disabled = src->pack_loading_disabled;
|
||||||
|
target->uncaught_exception_stack_size = src->uncaught_exception_stack_size;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1621,6 +1621,7 @@ net::URLRequestContext* CefBrowserImpl::request_context_proxy() {
|
||||||
|
|
||||||
void CefBrowserImpl::UIT_CreateDevToolsClient(BrowserDevToolsAgent *agent) {
|
void CefBrowserImpl::UIT_CreateDevToolsClient(BrowserDevToolsAgent *agent) {
|
||||||
dev_tools_client_.reset(new BrowserDevToolsClient(this, agent));
|
dev_tools_client_.reset(new BrowserDevToolsClient(this, agent));
|
||||||
|
_Context->UIT_DevToolsClientCreated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserImpl::UIT_DestroyDevToolsClient() {
|
void CefBrowserImpl::UIT_DestroyDevToolsClient() {
|
||||||
|
@ -1628,6 +1629,7 @@ void CefBrowserImpl::UIT_DestroyDevToolsClient() {
|
||||||
// Free the client. This will cause the client to clear pending messages
|
// Free the client. This will cause the client to clear pending messages
|
||||||
// and detach from the agent.
|
// and detach from the agent.
|
||||||
dev_tools_client_.reset();
|
dev_tools_client_.reset();
|
||||||
|
_Context->UIT_DevToolsClientDestroyed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "libcef/browser_devtools_scheme_handler.h"
|
#include "libcef/browser_devtools_scheme_handler.h"
|
||||||
#include "libcef/browser_impl.h"
|
#include "libcef/browser_impl.h"
|
||||||
#include "libcef/browser_webkit_glue.h"
|
#include "libcef/browser_webkit_glue.h"
|
||||||
|
#include "libcef/v8_impl.h"
|
||||||
|
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/file_util.h"
|
#include "base/file_util.h"
|
||||||
|
@ -226,7 +227,8 @@ CefContext::CefContext()
|
||||||
shutting_down_(false),
|
shutting_down_(false),
|
||||||
request_context_(NULL),
|
request_context_(NULL),
|
||||||
next_browser_id_(kNextBrowserIdReset),
|
next_browser_id_(kNextBrowserIdReset),
|
||||||
current_webviewhost_(NULL) {
|
current_webviewhost_(NULL),
|
||||||
|
dev_tools_client_count_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CefContext::~CefContext() {
|
CefContext::~CefContext() {
|
||||||
|
@ -601,3 +603,20 @@ void CefContext::UIT_FinishShutdown(
|
||||||
browser_shutdown_event->Signal();
|
browser_shutdown_event->Signal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefContext::UIT_DevToolsClientCreated() {
|
||||||
|
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||||
|
++dev_tools_client_count_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefContext::UIT_DevToolsClientDestroyed() {
|
||||||
|
DCHECK(CefThread::CurrentlyOn(CefThread::UI));
|
||||||
|
--dev_tools_client_count_;
|
||||||
|
if (dev_tools_client_count_ == 0) {
|
||||||
|
if (settings_.uncaught_exception_stack_size > 0) {
|
||||||
|
v8::V8::SetCaptureStackTraceForUncaughtExceptions(true,
|
||||||
|
settings_.uncaught_exception_stack_size,
|
||||||
|
v8::StackTrace::kDetailed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -96,6 +96,11 @@ class CefContext : public CefBase {
|
||||||
|
|
||||||
static bool ImplementsThreadSafeReferenceCounting() { return true; }
|
static bool ImplementsThreadSafeReferenceCounting() { return true; }
|
||||||
|
|
||||||
|
// Keep count of DevTools windows, need to re-enable stack trace
|
||||||
|
// functionality for uncaught exceptions.
|
||||||
|
void UIT_DevToolsClientCreated();
|
||||||
|
void UIT_DevToolsClientDestroyed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Performs shutdown actions that need to occur on the UI thread before any
|
// Performs shutdown actions that need to occur on the UI thread before any
|
||||||
// threads are destroyed.
|
// threads are destroyed.
|
||||||
|
@ -132,6 +137,8 @@ class CefContext : public CefBase {
|
||||||
|
|
||||||
scoped_refptr<base::SequencedWorkerPool> blocking_pool_;
|
scoped_refptr<base::SequencedWorkerPool> blocking_pool_;
|
||||||
|
|
||||||
|
int dev_tools_client_count_;
|
||||||
|
|
||||||
IMPLEMENT_REFCOUNTING(CefContext);
|
IMPLEMENT_REFCOUNTING(CefContext);
|
||||||
IMPLEMENT_LOCKING(CefContext);
|
IMPLEMENT_LOCKING(CefContext);
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "libcef/browser_webkit_glue.h"
|
#include "libcef/browser_webkit_glue.h"
|
||||||
#include "libcef/browser_webkit_init.h"
|
#include "libcef/browser_webkit_init.h"
|
||||||
#include "libcef/cef_context.h"
|
#include "libcef/cef_context.h"
|
||||||
|
#include "libcef/v8_impl.h"
|
||||||
|
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
|
@ -127,6 +128,13 @@ void CefProcessUIThread::Init() {
|
||||||
webkit_glue::SetJavaScriptFlags(CefString(&settings.javascript_flags));
|
webkit_glue::SetJavaScriptFlags(CefString(&settings.javascript_flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.uncaught_exception_stack_size > 0) {
|
||||||
|
v8::V8::AddMessageListener(&CefV8MessageHandler);
|
||||||
|
v8::V8::SetCaptureStackTraceForUncaughtExceptions(true,
|
||||||
|
settings.uncaught_exception_stack_size,
|
||||||
|
v8::StackTrace::kDetailed);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
if (settings.graphics_implementation == ANGLE_IN_PROCESS ||
|
if (settings.graphics_implementation == ANGLE_IN_PROCESS ||
|
||||||
settings.graphics_implementation == ANGLE_IN_PROCESS_COMMAND_BUFFER) {
|
settings.graphics_implementation == ANGLE_IN_PROCESS_COMMAND_BUFFER) {
|
||||||
|
|
|
@ -1460,3 +1460,28 @@ bool CefV8StackFrameImpl::IsConstructor() {
|
||||||
v8::HandleScope handle_scope;
|
v8::HandleScope handle_scope;
|
||||||
return GetHandle()->IsConstructor();
|
return GetHandle()->IsConstructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefV8MessageHandler(v8::Handle<v8::Message> message,
|
||||||
|
v8::Handle<v8::Value> data) {
|
||||||
|
CEF_REQUIRE_VALID_CONTEXT(void());
|
||||||
|
CEF_REQUIRE_UI_THREAD(void());
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
|
||||||
|
CefRefPtr<CefBrowser> browser = context->GetBrowser();
|
||||||
|
CefRefPtr<CefFrame> frame = context->GetFrame();
|
||||||
|
|
||||||
|
v8::Handle<v8::StackTrace> v8Stack = message->GetStackTrace();
|
||||||
|
DCHECK(!v8Stack.IsEmpty());
|
||||||
|
CefRefPtr<CefV8StackTrace> stackTrace = new CefV8StackTraceImpl(v8Stack);
|
||||||
|
|
||||||
|
CefRefPtr<CefClient> client = browser->GetClient();
|
||||||
|
if (!client.get())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefRefPtr<CefV8ContextHandler> handler = client->GetV8ContextHandler();
|
||||||
|
if (!handler.get())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefRefPtr<CefV8Exception> exception = new CefV8ExceptionImpl(message);
|
||||||
|
handler->OnUncaughtException(browser, frame, context, exception, stackTrace);
|
||||||
|
}
|
||||||
|
|
|
@ -220,4 +220,8 @@ class CefV8StackFrameImpl : public CefV8StackFrame {
|
||||||
DISALLOW_COPY_AND_ASSIGN(CefV8StackFrameImpl);
|
DISALLOW_COPY_AND_ASSIGN(CefV8StackFrameImpl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used to catch global exceptions.
|
||||||
|
void CefV8MessageHandler(v8::Handle<v8::Message> message,
|
||||||
|
v8::Handle<v8::Value> data);
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_V8_IMPL_H_
|
#endif // CEF_LIBCEF_V8_IMPL_H_
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "libcef_dll/ctocpp/browser_ctocpp.h"
|
#include "libcef_dll/ctocpp/browser_ctocpp.h"
|
||||||
#include "libcef_dll/ctocpp/frame_ctocpp.h"
|
#include "libcef_dll/ctocpp/frame_ctocpp.h"
|
||||||
#include "libcef_dll/ctocpp/v8context_ctocpp.h"
|
#include "libcef_dll/ctocpp/v8context_ctocpp.h"
|
||||||
|
#include "libcef_dll/ctocpp/v8exception_ctocpp.h"
|
||||||
|
#include "libcef_dll/ctocpp/v8stack_trace_ctocpp.h"
|
||||||
|
|
||||||
|
|
||||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||||
|
@ -74,6 +76,45 @@ void CEF_CALLBACK v8context_handler_on_context_released(
|
||||||
CefV8ContextCToCpp::Wrap(context));
|
CefV8ContextCToCpp::Wrap(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEF_CALLBACK v8context_handler_on_uncaught_exception(
|
||||||
|
struct _cef_v8context_handler_t* self, cef_browser_t* browser,
|
||||||
|
cef_frame_t* frame, cef_v8context_t* context, cef_v8exception_t* exception,
|
||||||
|
cef_v8stack_trace_t* stackTrace) {
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
DCHECK(self);
|
||||||
|
if (!self)
|
||||||
|
return;
|
||||||
|
// Verify param: browser; type: refptr_diff
|
||||||
|
DCHECK(browser);
|
||||||
|
if (!browser)
|
||||||
|
return;
|
||||||
|
// Verify param: frame; type: refptr_diff
|
||||||
|
DCHECK(frame);
|
||||||
|
if (!frame)
|
||||||
|
return;
|
||||||
|
// Verify param: context; type: refptr_diff
|
||||||
|
DCHECK(context);
|
||||||
|
if (!context)
|
||||||
|
return;
|
||||||
|
// Verify param: exception; type: refptr_diff
|
||||||
|
DCHECK(exception);
|
||||||
|
if (!exception)
|
||||||
|
return;
|
||||||
|
// Verify param: stackTrace; type: refptr_diff
|
||||||
|
DCHECK(stackTrace);
|
||||||
|
if (!stackTrace)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
CefV8ContextHandlerCppToC::Get(self)->OnUncaughtException(
|
||||||
|
CefBrowserCToCpp::Wrap(browser),
|
||||||
|
CefFrameCToCpp::Wrap(frame),
|
||||||
|
CefV8ContextCToCpp::Wrap(context),
|
||||||
|
CefV8ExceptionCToCpp::Wrap(exception),
|
||||||
|
CefV8StackTraceCToCpp::Wrap(stackTrace));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// CONSTRUCTOR - Do not edit by hand.
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
|
@ -82,6 +123,8 @@ CefV8ContextHandlerCppToC::CefV8ContextHandlerCppToC(CefV8ContextHandler* cls)
|
||||||
cef_v8context_handler_t>(cls) {
|
cef_v8context_handler_t>(cls) {
|
||||||
struct_.struct_.on_context_created = v8context_handler_on_context_created;
|
struct_.struct_.on_context_created = v8context_handler_on_context_created;
|
||||||
struct_.struct_.on_context_released = v8context_handler_on_context_released;
|
struct_.struct_.on_context_released = v8context_handler_on_context_released;
|
||||||
|
struct_.struct_.on_uncaught_exception =
|
||||||
|
v8context_handler_on_uncaught_exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "libcef_dll/cpptoc/browser_cpptoc.h"
|
#include "libcef_dll/cpptoc/browser_cpptoc.h"
|
||||||
#include "libcef_dll/cpptoc/frame_cpptoc.h"
|
#include "libcef_dll/cpptoc/frame_cpptoc.h"
|
||||||
#include "libcef_dll/cpptoc/v8context_cpptoc.h"
|
#include "libcef_dll/cpptoc/v8context_cpptoc.h"
|
||||||
|
#include "libcef_dll/cpptoc/v8exception_cpptoc.h"
|
||||||
|
#include "libcef_dll/cpptoc/v8stack_trace_cpptoc.h"
|
||||||
#include "libcef_dll/ctocpp/v8context_handler_ctocpp.h"
|
#include "libcef_dll/ctocpp/v8context_handler_ctocpp.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +74,45 @@ void CefV8ContextHandlerCToCpp::OnContextReleased(CefRefPtr<CefBrowser> browser,
|
||||||
CefV8ContextCppToC::Wrap(context));
|
CefV8ContextCppToC::Wrap(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefV8ContextHandlerCToCpp::OnUncaughtException(
|
||||||
|
CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefV8Context> context, CefRefPtr<CefV8Exception> exception,
|
||||||
|
CefRefPtr<CefV8StackTrace> stackTrace) {
|
||||||
|
if (CEF_MEMBER_MISSING(struct_, on_uncaught_exception))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Verify param: browser; type: refptr_diff
|
||||||
|
DCHECK(browser.get());
|
||||||
|
if (!browser.get())
|
||||||
|
return;
|
||||||
|
// Verify param: frame; type: refptr_diff
|
||||||
|
DCHECK(frame.get());
|
||||||
|
if (!frame.get())
|
||||||
|
return;
|
||||||
|
// Verify param: context; type: refptr_diff
|
||||||
|
DCHECK(context.get());
|
||||||
|
if (!context.get())
|
||||||
|
return;
|
||||||
|
// Verify param: exception; type: refptr_diff
|
||||||
|
DCHECK(exception.get());
|
||||||
|
if (!exception.get())
|
||||||
|
return;
|
||||||
|
// Verify param: stackTrace; type: refptr_diff
|
||||||
|
DCHECK(stackTrace.get());
|
||||||
|
if (!stackTrace.get())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
struct_->on_uncaught_exception(struct_,
|
||||||
|
CefBrowserCppToC::Wrap(browser),
|
||||||
|
CefFrameCppToC::Wrap(frame),
|
||||||
|
CefV8ContextCppToC::Wrap(context),
|
||||||
|
CefV8ExceptionCppToC::Wrap(exception),
|
||||||
|
CefV8StackTraceCppToC::Wrap(stackTrace));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
template<> long CefCToCpp<CefV8ContextHandlerCToCpp, CefV8ContextHandler,
|
template<> long CefCToCpp<CefV8ContextHandlerCToCpp, CefV8ContextHandler,
|
||||||
|
|
|
@ -38,6 +38,10 @@ class CefV8ContextHandlerCToCpp
|
||||||
CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE;
|
CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE;
|
||||||
virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
|
virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
|
||||||
CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE;
|
CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE;
|
||||||
|
virtual void OnUncaughtException(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context,
|
||||||
|
CefRefPtr<CefV8Exception> exception,
|
||||||
|
CefRefPtr<CefV8StackTrace> stackTrace) OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BUILDING_CEF_SHARED
|
#endif // BUILDING_CEF_SHARED
|
||||||
|
|
|
@ -257,6 +257,8 @@ void AppGetSettings(CefSettings& settings, CefRefPtr<CefApp>& app) {
|
||||||
|
|
||||||
settings.pack_loading_disabled =
|
settings.pack_loading_disabled =
|
||||||
g_command_line->HasSwitch(cefclient::kPackLoadingDisabled);
|
g_command_line->HasSwitch(cefclient::kPackLoadingDisabled);
|
||||||
|
settings.uncaught_exception_stack_size = GetIntValue(
|
||||||
|
g_command_line->GetSwitchValue(cefclient::kUncaughtExceptionStackSize));
|
||||||
|
|
||||||
// Retrieve command-line proxy configuration, if any.
|
// Retrieve command-line proxy configuration, if any.
|
||||||
bool has_proxy = false;
|
bool has_proxy = false;
|
||||||
|
|
|
@ -35,6 +35,7 @@ const char kJavascriptFlags[] = "javascript-flags";
|
||||||
const char kResourcesDirPath[] = "resources-dir-path";
|
const char kResourcesDirPath[] = "resources-dir-path";
|
||||||
const char kLocalesDirPath[] = "locales-dir-path";
|
const char kLocalesDirPath[] = "locales-dir-path";
|
||||||
const char kPackLoadingDisabled[] = "pack-loading-disabled";
|
const char kPackLoadingDisabled[] = "pack-loading-disabled";
|
||||||
|
const char kUncaughtExceptionStackSize[] = "uncaught-exception-stack-size";
|
||||||
|
|
||||||
// CefBrowserSettings attributes.
|
// CefBrowserSettings attributes.
|
||||||
const char kDragDropDisabled[] = "drag-drop-disabled";
|
const char kDragDropDisabled[] = "drag-drop-disabled";
|
||||||
|
|
|
@ -37,6 +37,7 @@ extern const char kJavascriptFlags[];
|
||||||
extern const char kResourcesDirPath[];
|
extern const char kResourcesDirPath[];
|
||||||
extern const char kLocalesDirPath[];
|
extern const char kLocalesDirPath[];
|
||||||
extern const char kPackLoadingDisabled[];
|
extern const char kPackLoadingDisabled[];
|
||||||
|
extern const char kUncaughtExceptionStackSize[];
|
||||||
|
|
||||||
// CefBrowserSettings attributes.
|
// CefBrowserSettings attributes.
|
||||||
extern const char kDragDropDisabled[];
|
extern const char kDragDropDisabled[];
|
||||||
|
|
|
@ -87,7 +87,7 @@ class TestHandler : public CefClient,
|
||||||
protected:
|
protected:
|
||||||
// Destroy the browser window. Once the window is destroyed test completion
|
// Destroy the browser window. Once the window is destroyed test completion
|
||||||
// will be signaled.
|
// will be signaled.
|
||||||
void DestroyTest();
|
virtual void DestroyTest();
|
||||||
|
|
||||||
void CreateBrowser(const CefString& url);
|
void CreateBrowser(const CefString& url);
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,9 @@ void CefTestSuite::GetSettings(CefSettings& settings) {
|
||||||
|
|
||||||
settings.pack_loading_disabled =
|
settings.pack_loading_disabled =
|
||||||
commandline_->HasSwitch(cefclient::kPackLoadingDisabled);
|
commandline_->HasSwitch(cefclient::kPackLoadingDisabled);
|
||||||
|
|
||||||
|
// Necessary for V8Test.OnUncaughtException tests.
|
||||||
|
settings.uncaught_exception_stack_size = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "include/cef_runnable.h"
|
#include "include/cef_runnable.h"
|
||||||
#include "include/cef_v8.h"
|
#include "include/cef_v8.h"
|
||||||
#include "tests/unittests/test_handler.h"
|
#include "tests/unittests/test_handler.h"
|
||||||
|
#include "tests/unittests/test_suite.h"
|
||||||
#include "testing/gtest/include/gtest/gtest.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
// How to add a new test:
|
// How to add a new test:
|
||||||
|
@ -21,6 +22,8 @@ const char* kV8TestUrl = "http://tests/V8Test.Test";
|
||||||
const char* kV8BindingTestUrl = "http://tests/V8Test.BindingTest";
|
const char* kV8BindingTestUrl = "http://tests/V8Test.BindingTest";
|
||||||
const char* kV8ContextParentTestUrl = "http://tests/V8Test.ContextParentTest";
|
const char* kV8ContextParentTestUrl = "http://tests/V8Test.ContextParentTest";
|
||||||
const char* kV8ContextChildTestUrl = "http://tests/V8Test.ContextChildTest";
|
const char* kV8ContextChildTestUrl = "http://tests/V8Test.ContextChildTest";
|
||||||
|
const char* kV8OnUncaughtExceptionTestUrl =
|
||||||
|
"http://tests/V8Test.OnUncaughtException";
|
||||||
|
|
||||||
enum V8TestMode {
|
enum V8TestMode {
|
||||||
V8TEST_NULL_CREATE = 0,
|
V8TEST_NULL_CREATE = 0,
|
||||||
|
@ -56,6 +59,8 @@ enum V8TestMode {
|
||||||
V8TEST_CONTEXT_ENTERED,
|
V8TEST_CONTEXT_ENTERED,
|
||||||
V8TEST_BINDING,
|
V8TEST_BINDING,
|
||||||
V8TEST_STACK_TRACE,
|
V8TEST_STACK_TRACE,
|
||||||
|
V8TEST_ON_UNCAUGHT_EXCEPTION,
|
||||||
|
V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,6 +80,17 @@ class V8TestHandler : public TestHandler {
|
||||||
AddResource(kV8ContextChildTestUrl, "<html><body>CHILD</body></html>",
|
AddResource(kV8ContextChildTestUrl, "<html><body>CHILD</body></html>",
|
||||||
"text/html");
|
"text/html");
|
||||||
CreateBrowser(kV8ContextParentTestUrl);
|
CreateBrowser(kV8ContextParentTestUrl);
|
||||||
|
} else if (test_mode_ == V8TEST_ON_UNCAUGHT_EXCEPTION ||
|
||||||
|
test_mode_ == V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS) {
|
||||||
|
AddResource(kV8OnUncaughtExceptionTestUrl, "<html><body>"
|
||||||
|
"<h1>OnUncaughtException</h1>"
|
||||||
|
"<script>\n"
|
||||||
|
"function test(){ test2(); }\n"
|
||||||
|
"function test2(){ asd(); }\n"
|
||||||
|
"</script>\n"
|
||||||
|
"</body></html>\n",
|
||||||
|
"text/html");
|
||||||
|
CreateBrowser(kV8OnUncaughtExceptionTestUrl);
|
||||||
} else {
|
} else {
|
||||||
EXPECT_TRUE(test_url_ != NULL);
|
EXPECT_TRUE(test_url_ != NULL);
|
||||||
AddResource(test_url_, "<html><body>TEST</body></html>", "text/html");
|
AddResource(test_url_, "<html><body>TEST</body></html>", "text/html");
|
||||||
|
@ -184,6 +200,12 @@ class V8TestHandler : public TestHandler {
|
||||||
case V8TEST_STACK_TRACE:
|
case V8TEST_STACK_TRACE:
|
||||||
RunStackTraceTest();
|
RunStackTraceTest();
|
||||||
break;
|
break;
|
||||||
|
case V8TEST_ON_UNCAUGHT_EXCEPTION:
|
||||||
|
RunOnUncaughtExceptionTest();
|
||||||
|
break;
|
||||||
|
case V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS:
|
||||||
|
RunOnUncaughtExceptionDevToolsTest();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ADD_FAILURE();
|
ADD_FAILURE();
|
||||||
DestroyTest();
|
DestroyTest();
|
||||||
|
@ -1522,11 +1544,57 @@ class V8TestHandler : public TestHandler {
|
||||||
DestroyTest();
|
DestroyTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RunOnUncaughtExceptionTest() {
|
||||||
|
on_uncaught_exception_context_ =
|
||||||
|
GetBrowser()->GetMainFrame()->GetV8Context();
|
||||||
|
GetBrowser()->GetMainFrame()->ExecuteJavaScript("test()",
|
||||||
|
CefString(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunOnUncaughtExceptionDevToolsTest() {
|
||||||
|
on_uncaught_exception_context_ =
|
||||||
|
GetBrowser()->GetMainFrame()->GetV8Context();
|
||||||
|
GetBrowser()->ShowDevTools();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUncaughtException(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
CefRefPtr<CefV8Context> context,
|
||||||
|
CefRefPtr<CefV8Exception> exception,
|
||||||
|
CefRefPtr<CefV8StackTrace> stackTrace) OVERRIDE {
|
||||||
|
got_on_uncaught_exception_.yes();
|
||||||
|
|
||||||
|
if (test_mode_ == V8TEST_ON_UNCAUGHT_EXCEPTION ||
|
||||||
|
test_mode_ == V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS) {
|
||||||
|
EXPECT_TRUE(on_uncaught_exception_context_->IsSame(context));
|
||||||
|
EXPECT_STREQ("Uncaught ReferenceError: asd is not defined",
|
||||||
|
exception->GetMessage().ToString().c_str());
|
||||||
|
std::ostringstream stackFormatted;
|
||||||
|
for (int i = 0; i < stackTrace->GetFrameCount(); ++i)
|
||||||
|
stackFormatted << "at "
|
||||||
|
<< stackTrace->GetFrame(i)->GetFunctionName().ToString()
|
||||||
|
<< "() in " << stackTrace->GetFrame(i)->GetScriptName().ToString()
|
||||||
|
<< " on line " << stackTrace->GetFrame(i)->GetLineNumber() << "\n";
|
||||||
|
const char* stackFormattedShouldBe =
|
||||||
|
"at test2() in http://tests/V8Test.OnUncaughtException on line 3\n"
|
||||||
|
"at test() in http://tests/V8Test.OnUncaughtException on line 2\n"
|
||||||
|
"at () in on line 0\n";
|
||||||
|
EXPECT_STREQ(stackFormattedShouldBe, stackFormatted.str().c_str());
|
||||||
|
DestroyTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
int httpStatusCode) OVERRIDE {
|
int httpStatusCode) OVERRIDE {
|
||||||
if (frame->IsMain())
|
if (frame->IsMain())
|
||||||
RunTest(test_mode_);
|
RunTest(test_mode_);
|
||||||
|
if (test_mode_ == V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS &&
|
||||||
|
browser->IsPopup()) {
|
||||||
|
GetBrowser()->CloseDevTools();
|
||||||
|
GetBrowser()->GetMainFrame()->ExecuteJavaScript("test()",
|
||||||
|
CefString(), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
|
virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
|
||||||
|
@ -1586,6 +1654,16 @@ class V8TestHandler : public TestHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void DestroyTest() OVERRIDE {
|
||||||
|
if (test_mode_ == V8TEST_ON_UNCAUGHT_EXCEPTION ||
|
||||||
|
test_mode_ == V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS) {
|
||||||
|
EXPECT_TRUE(got_on_uncaught_exception_);
|
||||||
|
}
|
||||||
|
|
||||||
|
got_destroy_test_.yes();
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
// Return the V8 context.
|
// Return the V8 context.
|
||||||
CefRefPtr<CefV8Context> GetContext() {
|
CefRefPtr<CefV8Context> GetContext() {
|
||||||
CefRefPtr<CefV8Context> context =
|
CefRefPtr<CefV8Context> context =
|
||||||
|
@ -1596,6 +1674,10 @@ class V8TestHandler : public TestHandler {
|
||||||
|
|
||||||
V8TestMode test_mode_;
|
V8TestMode test_mode_;
|
||||||
const char* test_url_;
|
const char* test_url_;
|
||||||
|
CefRefPtr<CefV8Context> on_uncaught_exception_context_;
|
||||||
|
|
||||||
|
TrackCallback got_destroy_test_;
|
||||||
|
TrackCallback got_on_uncaught_exception_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -1607,6 +1689,7 @@ class V8TestHandler : public TestHandler {
|
||||||
CefRefPtr<V8TestHandler> handler = \
|
CefRefPtr<V8TestHandler> handler = \
|
||||||
new V8TestHandler(test_mode, test_url); \
|
new V8TestHandler(test_mode, test_url); \
|
||||||
handler->ExecuteTest(); \
|
handler->ExecuteTest(); \
|
||||||
|
EXPECT_TRUE(handler->got_destroy_test_); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define V8_TEST(name, test_mode) \
|
#define V8_TEST(name, test_mode) \
|
||||||
|
@ -1647,6 +1730,8 @@ V8_TEST(ContextEvalException, V8TEST_CONTEXT_EVAL_EXCEPTION);
|
||||||
V8_TEST_EX(ContextEntered, V8TEST_CONTEXT_ENTERED, NULL);
|
V8_TEST_EX(ContextEntered, V8TEST_CONTEXT_ENTERED, NULL);
|
||||||
V8_TEST_EX(Binding, V8TEST_BINDING, kV8BindingTestUrl);
|
V8_TEST_EX(Binding, V8TEST_BINDING, kV8BindingTestUrl);
|
||||||
V8_TEST(StackTrace, V8TEST_STACK_TRACE);
|
V8_TEST(StackTrace, V8TEST_STACK_TRACE);
|
||||||
|
V8_TEST(OnUncaughtException, V8TEST_ON_UNCAUGHT_EXCEPTION);
|
||||||
|
V8_TEST(OnUncaughtExceptionDevTools, V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS);
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -1737,7 +1822,8 @@ TEST(V8Test, ExternalMemoryAllocation) {
|
||||||
Test* test = new Test();
|
Test* test = new Test();
|
||||||
CefRegisterExtension("v8/externalMemory", test->GetExtensionCode(), test);
|
CefRegisterExtension("v8/externalMemory", test->GetExtensionCode(), test);
|
||||||
|
|
||||||
V8ExternalMemTestHandler* test_handler = new V8ExternalMemTestHandler(test->GetTestCode());
|
V8ExternalMemTestHandler* test_handler =
|
||||||
|
new V8ExternalMemTestHandler(test->GetTestCode());
|
||||||
test_handler->ExecuteTest();
|
test_handler->ExecuteTest();
|
||||||
|
|
||||||
ASSERT_TRUE(test->object_created_);
|
ASSERT_TRUE(test->object_created_);
|
||||||
|
|
Loading…
Reference in New Issue