| Index: test/cctest/test-debug.cc
|
| diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
|
| index 4de243b6cc149097f8ddb497c0b3d1775ca980f0..89fdabb46a272aef30f5302bafa5a0a702279d4b 100644
|
| --- a/test/cctest/test-debug.cc
|
| +++ b/test/cctest/test-debug.cc
|
| @@ -3856,6 +3856,13 @@ TEST(PauseInScript) {
|
| }
|
|
|
|
|
| +static void DebugEventCounterCheck(int caught, int uncaught, int message) {
|
| + CHECK_EQ(caught, exception_hit_count);
|
| + CHECK_EQ(uncaught, uncaught_exception_hit_count);
|
| + CHECK_EQ(message, message_callback_count);
|
| +}
|
| +
|
| +
|
| // Test break on exceptions. For each exception break combination the number
|
| // of debug event exception callbacks and message callbacks are collected. The
|
| // number of debug event exception callbacks are used to check that the
|
| @@ -3875,6 +3882,15 @@ TEST(BreakOnException) {
|
| "caught");
|
| v8::Local<v8::Function> notCaught =
|
| CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
|
| + v8::Local<v8::Function> notCaughtFinally = CompileFunction(
|
| + &env, "function notCaughtFinally(){try{throws();}finally{}}",
|
| + "notCaughtFinally");
|
| + // In this edge case, even though this finally does not propagate the
|
| + // exception, the debugger considers this uncaught, since we want to break
|
| + // at the first throw for the general case where finally implicitly rethrows.
|
| + v8::Local<v8::Function> edgeCaseFinally = CompileFunction(
|
| + &env, "function caughtFinally(){L:try{throws();}finally{break L;}}",
|
| + "caughtFinally");
|
|
|
| v8::V8::AddMessageListener(MessageCallbackCount);
|
| v8::Debug::SetDebugEventListener(DebugEventCounter);
|
| @@ -3883,117 +3899,117 @@ TEST(BreakOnException) {
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(0, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| + DebugEventCounterCheck(0, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(0, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(0, 0, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(0, 0, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(0, 0, 2);
|
|
|
| // No break on exception
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| ChangeBreakOnException(false, false);
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(0, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| + DebugEventCounterCheck(0, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(0, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(0, 0, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(0, 0, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(0, 0, 2);
|
|
|
| // Break on uncaught exception
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| ChangeBreakOnException(false, true);
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(0, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| + DebugEventCounterCheck(0, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(1, exception_hit_count);
|
| - CHECK_EQ(1, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(1, 1, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(2, 2, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(3, 3, 2);
|
|
|
| // Break on exception and uncaught exception
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| ChangeBreakOnException(true, true);
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(1, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| + DebugEventCounterCheck(1, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(2, exception_hit_count);
|
| - CHECK_EQ(1, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(2, 1, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(3, 2, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(4, 3, 2);
|
|
|
| // Break on exception
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| ChangeBreakOnException(true, false);
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(1, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| + DebugEventCounterCheck(1, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(2, exception_hit_count);
|
| - CHECK_EQ(1, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(2, 1, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(3, 2, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(4, 3, 2);
|
|
|
| // No break on exception using JavaScript
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false);
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(0, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| + DebugEventCounterCheck(0, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(0, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(0, 0, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(0, 0, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(0, 0, 2);
|
|
|
| // Break on uncaught exception using JavaScript
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true);
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(0, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| + DebugEventCounterCheck(0, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(1, exception_hit_count);
|
| - CHECK_EQ(1, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(1, 1, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(2, 2, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(3, 3, 2);
|
|
|
| // Break on exception and uncaught exception using JavaScript
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true);
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(1, exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| + DebugEventCounterCheck(1, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(2, exception_hit_count);
|
| - CHECK_EQ(1, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(2, 1, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(3, 2, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(4, 3, 2);
|
|
|
| // Break on exception using JavaScript
|
| DebugEventCounterClear();
|
| MessageCallbackCountClear();
|
| ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false);
|
| caught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(1, exception_hit_count);
|
| - CHECK_EQ(0, uncaught_exception_hit_count);
|
| - CHECK_EQ(0, message_callback_count);
|
| + DebugEventCounterCheck(1, 0, 0);
|
| notCaught->Call(env->Global(), 0, NULL);
|
| - CHECK_EQ(2, exception_hit_count);
|
| - CHECK_EQ(1, uncaught_exception_hit_count);
|
| - CHECK_EQ(1, message_callback_count);
|
| + DebugEventCounterCheck(2, 1, 1);
|
| + notCaughtFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(3, 2, 2);
|
| + edgeCaseFinally->Call(env->Global(), 0, NULL);
|
| + DebugEventCounterCheck(4, 3, 2);
|
|
|
| v8::Debug::SetDebugEventListener(NULL);
|
| CheckDebuggerUnloaded();
|
| @@ -4001,6 +4017,35 @@ TEST(BreakOnException) {
|
| }
|
|
|
|
|
| +static void try_finally_original_message(v8::Handle<v8::Message> message,
|
| + v8::Handle<v8::Value> data) {
|
| + CHECK_EQ(2, message->GetLineNumber());
|
| + CHECK_EQ(2, message->GetStartColumn());
|
| + message_callback_count++;
|
| +}
|
| +
|
| +
|
| +TEST(TryFinallyOriginalMessage) {
|
| + // Test that the debugger plays nicely with the pending message.
|
| + message_callback_count = 0;
|
| + DebugEventCounterClear();
|
| + v8::V8::AddMessageListener(try_finally_original_message);
|
| + v8::Debug::SetDebugEventListener(DebugEventCounter);
|
| + ChangeBreakOnException(true, true);
|
| + DebugLocalContext env;
|
| + v8::Isolate* isolate = CcTest::isolate();
|
| + v8::HandleScope scope(isolate);
|
| + CompileRun(
|
| + "try {\n"
|
| + " throw 1;\n"
|
| + "} finally {\n"
|
| + "}\n");
|
| + DebugEventCounterCheck(1, 1, 1);
|
| + v8::Debug::SetDebugEventListener(NULL);
|
| + v8::V8::RemoveMessageListeners(try_finally_original_message);
|
| +}
|
| +
|
| +
|
| TEST(EvalJSInDebugEventListenerOnNativeReThrownException) {
|
| DebugLocalContext env;
|
| v8::HandleScope scope(env->GetIsolate());
|
|
|