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)(
|
||||
struct _cef_v8context_handler_t* self, struct _cef_browser_t* browser,
|
||||
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;
|
||||
|
||||
|
||||
|
|
|
@ -68,6 +68,18 @@ class CefV8ContextHandler : public virtual CefBase {
|
|||
virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
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_
|
||||
|
|
|
@ -210,6 +210,14 @@ typedef struct _cef_settings_t {
|
|||
// is 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;
|
||||
|
||||
///
|
||||
|
|
|
@ -299,6 +299,7 @@ struct CefSettingsTraits {
|
|||
cef_string_set(src->locales_dir_path.str, src->locales_dir_path.length,
|
||||
&target->locales_dir_path, copy);
|
||||
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) {
|
||||
dev_tools_client_.reset(new BrowserDevToolsClient(this, agent));
|
||||
_Context->UIT_DevToolsClientCreated();
|
||||
}
|
||||
|
||||
void CefBrowserImpl::UIT_DestroyDevToolsClient() {
|
||||
|
@ -1628,6 +1629,7 @@ void CefBrowserImpl::UIT_DestroyDevToolsClient() {
|
|||
// Free the client. This will cause the client to clear pending messages
|
||||
// and detach from the agent.
|
||||
dev_tools_client_.reset();
|
||||
_Context->UIT_DevToolsClientDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "libcef/browser_devtools_scheme_handler.h"
|
||||
#include "libcef/browser_impl.h"
|
||||
#include "libcef/browser_webkit_glue.h"
|
||||
#include "libcef/v8_impl.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/file_util.h"
|
||||
|
@ -226,7 +227,8 @@ CefContext::CefContext()
|
|||
shutting_down_(false),
|
||||
request_context_(NULL),
|
||||
next_browser_id_(kNextBrowserIdReset),
|
||||
current_webviewhost_(NULL) {
|
||||
current_webviewhost_(NULL),
|
||||
dev_tools_client_count_(0) {
|
||||
}
|
||||
|
||||
CefContext::~CefContext() {
|
||||
|
@ -601,3 +603,20 @@ void CefContext::UIT_FinishShutdown(
|
|||
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; }
|
||||
|
||||
// Keep count of DevTools windows, need to re-enable stack trace
|
||||
// functionality for uncaught exceptions.
|
||||
void UIT_DevToolsClientCreated();
|
||||
void UIT_DevToolsClientDestroyed();
|
||||
|
||||
private:
|
||||
// Performs shutdown actions that need to occur on the UI thread before any
|
||||
// threads are destroyed.
|
||||
|
@ -132,6 +137,8 @@ class CefContext : public CefBase {
|
|||
|
||||
scoped_refptr<base::SequencedWorkerPool> blocking_pool_;
|
||||
|
||||
int dev_tools_client_count_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefContext);
|
||||
IMPLEMENT_LOCKING(CefContext);
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "libcef/browser_webkit_glue.h"
|
||||
#include "libcef/browser_webkit_init.h"
|
||||
#include "libcef/cef_context.h"
|
||||
#include "libcef/v8_impl.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/command_line.h"
|
||||
|
@ -127,6 +128,13 @@ void CefProcessUIThread::Init() {
|
|||
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 (settings.graphics_implementation == ANGLE_IN_PROCESS ||
|
||||
settings.graphics_implementation == ANGLE_IN_PROCESS_COMMAND_BUFFER) {
|
||||
|
|
|
@ -1460,3 +1460,28 @@ bool CefV8StackFrameImpl::IsConstructor() {
|
|||
v8::HandleScope handle_scope;
|
||||
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);
|
||||
};
|
||||
|
||||
// Used to catch global exceptions.
|
||||
void CefV8MessageHandler(v8::Handle<v8::Message> message,
|
||||
v8::Handle<v8::Value> data);
|
||||
|
||||
#endif // CEF_LIBCEF_V8_IMPL_H_
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "libcef_dll/ctocpp/browser_ctocpp.h"
|
||||
#include "libcef_dll/ctocpp/frame_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.
|
||||
|
@ -74,6 +76,45 @@ void CEF_CALLBACK v8context_handler_on_context_released(
|
|||
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.
|
||||
|
||||
|
@ -82,6 +123,8 @@ CefV8ContextHandlerCppToC::CefV8ContextHandlerCppToC(CefV8ContextHandler* cls)
|
|||
cef_v8context_handler_t>(cls) {
|
||||
struct_.struct_.on_context_created = v8context_handler_on_context_created;
|
||||
struct_.struct_.on_context_released = v8context_handler_on_context_released;
|
||||
struct_.struct_.on_uncaught_exception =
|
||||
v8context_handler_on_uncaught_exception;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "libcef_dll/cpptoc/browser_cpptoc.h"
|
||||
#include "libcef_dll/cpptoc/frame_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"
|
||||
|
||||
|
||||
|
@ -72,6 +74,45 @@ void CefV8ContextHandlerCToCpp::OnContextReleased(CefRefPtr<CefBrowser> browser,
|
|||
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
|
||||
template<> long CefCToCpp<CefV8ContextHandlerCToCpp, CefV8ContextHandler,
|
||||
|
|
|
@ -38,6 +38,10 @@ class CefV8ContextHandlerCToCpp
|
|||
CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE;
|
||||
virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
|
||||
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
|
||||
|
|
|
@ -257,6 +257,8 @@ void AppGetSettings(CefSettings& settings, CefRefPtr<CefApp>& app) {
|
|||
|
||||
settings.pack_loading_disabled =
|
||||
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.
|
||||
bool has_proxy = false;
|
||||
|
|
|
@ -35,6 +35,7 @@ const char kJavascriptFlags[] = "javascript-flags";
|
|||
const char kResourcesDirPath[] = "resources-dir-path";
|
||||
const char kLocalesDirPath[] = "locales-dir-path";
|
||||
const char kPackLoadingDisabled[] = "pack-loading-disabled";
|
||||
const char kUncaughtExceptionStackSize[] = "uncaught-exception-stack-size";
|
||||
|
||||
// CefBrowserSettings attributes.
|
||||
const char kDragDropDisabled[] = "drag-drop-disabled";
|
||||
|
|
|
@ -37,6 +37,7 @@ extern const char kJavascriptFlags[];
|
|||
extern const char kResourcesDirPath[];
|
||||
extern const char kLocalesDirPath[];
|
||||
extern const char kPackLoadingDisabled[];
|
||||
extern const char kUncaughtExceptionStackSize[];
|
||||
|
||||
// CefBrowserSettings attributes.
|
||||
extern const char kDragDropDisabled[];
|
||||
|
|
|
@ -87,7 +87,7 @@ class TestHandler : public CefClient,
|
|||
protected:
|
||||
// Destroy the browser window. Once the window is destroyed test completion
|
||||
// will be signaled.
|
||||
void DestroyTest();
|
||||
virtual void DestroyTest();
|
||||
|
||||
void CreateBrowser(const CefString& url);
|
||||
|
||||
|
|
|
@ -124,6 +124,9 @@ void CefTestSuite::GetSettings(CefSettings& settings) {
|
|||
|
||||
settings.pack_loading_disabled =
|
||||
commandline_->HasSwitch(cefclient::kPackLoadingDisabled);
|
||||
|
||||
// Necessary for V8Test.OnUncaughtException tests.
|
||||
settings.uncaught_exception_stack_size = 10;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "include/cef_runnable.h"
|
||||
#include "include/cef_v8.h"
|
||||
#include "tests/unittests/test_handler.h"
|
||||
#include "tests/unittests/test_suite.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
// 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* kV8ContextParentTestUrl = "http://tests/V8Test.ContextParentTest";
|
||||
const char* kV8ContextChildTestUrl = "http://tests/V8Test.ContextChildTest";
|
||||
const char* kV8OnUncaughtExceptionTestUrl =
|
||||
"http://tests/V8Test.OnUncaughtException";
|
||||
|
||||
enum V8TestMode {
|
||||
V8TEST_NULL_CREATE = 0,
|
||||
|
@ -56,6 +59,8 @@ enum V8TestMode {
|
|||
V8TEST_CONTEXT_ENTERED,
|
||||
V8TEST_BINDING,
|
||||
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>",
|
||||
"text/html");
|
||||
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 {
|
||||
EXPECT_TRUE(test_url_ != NULL);
|
||||
AddResource(test_url_, "<html><body>TEST</body></html>", "text/html");
|
||||
|
@ -184,6 +200,12 @@ class V8TestHandler : public TestHandler {
|
|||
case V8TEST_STACK_TRACE:
|
||||
RunStackTraceTest();
|
||||
break;
|
||||
case V8TEST_ON_UNCAUGHT_EXCEPTION:
|
||||
RunOnUncaughtExceptionTest();
|
||||
break;
|
||||
case V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS:
|
||||
RunOnUncaughtExceptionDevToolsTest();
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE();
|
||||
DestroyTest();
|
||||
|
@ -1522,11 +1544,57 @@ class V8TestHandler : public TestHandler {
|
|||
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,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) OVERRIDE {
|
||||
if (frame->IsMain())
|
||||
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,
|
||||
|
@ -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.
|
||||
CefRefPtr<CefV8Context> GetContext() {
|
||||
CefRefPtr<CefV8Context> context =
|
||||
|
@ -1596,6 +1674,10 @@ class V8TestHandler : public TestHandler {
|
|||
|
||||
V8TestMode test_mode_;
|
||||
const char* test_url_;
|
||||
CefRefPtr<CefV8Context> on_uncaught_exception_context_;
|
||||
|
||||
TrackCallback got_destroy_test_;
|
||||
TrackCallback got_on_uncaught_exception_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -1607,6 +1689,7 @@ class V8TestHandler : public TestHandler {
|
|||
CefRefPtr<V8TestHandler> handler = \
|
||||
new V8TestHandler(test_mode, test_url); \
|
||||
handler->ExecuteTest(); \
|
||||
EXPECT_TRUE(handler->got_destroy_test_); \
|
||||
}
|
||||
|
||||
#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(Binding, V8TEST_BINDING, kV8BindingTestUrl);
|
||||
V8_TEST(StackTrace, V8TEST_STACK_TRACE);
|
||||
V8_TEST(OnUncaughtException, V8TEST_ON_UNCAUGHT_EXCEPTION);
|
||||
V8_TEST(OnUncaughtExceptionDevTools, V8TEST_ON_UNCAUGHT_EXCEPTION_DEV_TOOLS);
|
||||
|
||||
|
||||
namespace {
|
||||
|
@ -1737,7 +1822,8 @@ TEST(V8Test, ExternalMemoryAllocation) {
|
|||
Test* test = new Test();
|
||||
CefRegisterExtension("v8/externalMemory", test->GetExtensionCode(), test);
|
||||
|
||||
V8ExternalMemTestHandler* test_handler = new V8ExternalMemTestHandler(test->GetTestCode());
|
||||
V8ExternalMemTestHandler* test_handler =
|
||||
new V8ExternalMemTestHandler(test->GetTestCode());
|
||||
test_handler->ExecuteTest();
|
||||
|
||||
ASSERT_TRUE(test->object_created_);
|
||||
|
|
Loading…
Reference in New Issue