Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 } | 662 } |
| 663 } | 663 } |
| 664 } | 664 } |
| 665 | 665 |
| 666 | 666 |
| 667 // Debug event handler which counts a number of events and collects the stack | 667 // Debug event handler which counts a number of events and collects the stack |
| 668 // height if there is a function compiled for that. | 668 // height if there is a function compiled for that. |
| 669 int exception_hit_count = 0; | 669 int exception_hit_count = 0; |
| 670 int uncaught_exception_hit_count = 0; | 670 int uncaught_exception_hit_count = 0; |
| 671 int last_js_stack_height = -1; | 671 int last_js_stack_height = -1; |
| 672 v8::Handle<v8::Function> debug_event_listener_callback; | |
| 673 int debug_event_listener_callback_result; | |
| 672 | 674 |
| 673 static void DebugEventCounterClear() { | 675 static void DebugEventCounterClear() { |
| 674 break_point_hit_count = 0; | 676 break_point_hit_count = 0; |
| 675 exception_hit_count = 0; | 677 exception_hit_count = 0; |
| 676 uncaught_exception_hit_count = 0; | 678 uncaught_exception_hit_count = 0; |
| 677 } | 679 } |
| 678 | 680 |
| 679 static void DebugEventCounter( | 681 static void DebugEventCounter( |
| 680 const v8::Debug::EventDetails& event_details) { | 682 const v8::Debug::EventDetails& event_details) { |
| 681 v8::DebugEvent event = event_details.GetEvent(); | 683 v8::DebugEvent event = event_details.GetEvent(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 702 uncaught_exception_hit_count++; | 704 uncaught_exception_hit_count++; |
| 703 } | 705 } |
| 704 } | 706 } |
| 705 | 707 |
| 706 // Collect the JavsScript stack height if the function frame_count is | 708 // Collect the JavsScript stack height if the function frame_count is |
| 707 // compiled. | 709 // compiled. |
| 708 if (!frame_count.IsEmpty()) { | 710 if (!frame_count.IsEmpty()) { |
| 709 static const int kArgc = 1; | 711 static const int kArgc = 1; |
| 710 v8::Handle<v8::Value> argv[kArgc] = { exec_state }; | 712 v8::Handle<v8::Value> argv[kArgc] = { exec_state }; |
| 711 // Using exec_state as receiver is just to have a receiver. | 713 // Using exec_state as receiver is just to have a receiver. |
| 712 v8::Handle<v8::Value> result = frame_count->Call(exec_state, kArgc, argv); | 714 v8::Handle<v8::Value> result = frame_count->Call(exec_state, kArgc, argv); |
| 713 last_js_stack_height = result->Int32Value(); | 715 last_js_stack_height = result->Int32Value(); |
| 714 } | 716 } |
| 717 | |
| 718 // Run callback from DebugEventListener and check the result. | |
| 719 if (!debug_event_listener_callback.IsEmpty()) { | |
| 720 v8::Handle<v8::Value> result = | |
| 721 debug_event_listener_callback->Call(event_data, 0, NULL); | |
| 722 CHECK(!result.IsEmpty()); | |
| 723 CHECK_EQ(debug_event_listener_callback_result, result->Int32Value()); | |
| 724 } | |
| 715 } | 725 } |
| 716 | 726 |
| 717 | 727 |
| 718 // Debug event handler which evaluates a number of expressions when a break | 728 // Debug event handler which evaluates a number of expressions when a break |
| 719 // point is hit. Each evaluated expression is compared with an expected value. | 729 // point is hit. Each evaluated expression is compared with an expected value. |
| 720 // For this debug event handler to work the following two global varaibles | 730 // For this debug event handler to work the following two global varaibles |
| 721 // must be initialized. | 731 // must be initialized. |
| 722 // checks: An array of expressions and expected results | 732 // checks: An array of expressions and expected results |
| 723 // evaluate_check_function: A JavaScript function (see below) | 733 // evaluate_check_function: A JavaScript function (see below) |
| 724 | 734 |
| (...skipping 3235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3960 CHECK_EQ(2, exception_hit_count); | 3970 CHECK_EQ(2, exception_hit_count); |
| 3961 CHECK_EQ(1, uncaught_exception_hit_count); | 3971 CHECK_EQ(1, uncaught_exception_hit_count); |
| 3962 CHECK_EQ(1, message_callback_count); | 3972 CHECK_EQ(1, message_callback_count); |
| 3963 | 3973 |
| 3964 v8::Debug::SetDebugEventListener(NULL); | 3974 v8::Debug::SetDebugEventListener(NULL); |
| 3965 CheckDebuggerUnloaded(); | 3975 CheckDebuggerUnloaded(); |
| 3966 v8::V8::RemoveMessageListeners(MessageCallbackCount); | 3976 v8::V8::RemoveMessageListeners(MessageCallbackCount); |
| 3967 } | 3977 } |
| 3968 | 3978 |
| 3969 | 3979 |
| 3980 TEST(EvalJSInDebugEventListenerOnNativeReThrownException) { | |
| 3981 DebugLocalContext env; | |
| 3982 v8::HandleScope scope(env->GetIsolate()); | |
| 3983 env.ExposeDebug(); | |
| 3984 | |
| 3985 // Create functions for testing break on exception. | |
| 3986 v8::Local<v8::Function> reThrowJS = CompileFunction( | |
| 3987 &env, "function reThrowJS(){try {throw 1;} finally {};}", "reThrowJS"); | |
| 3988 v8::Local<v8::Function> noThrowJS = CompileFunction( | |
| 3989 &env, "function noThrowJS(){var a=[1]; a.push(2); return a.length;}", | |
| 3990 "noThrowJS"); | |
| 3991 | |
| 3992 debug_event_listener_callback = noThrowJS; | |
| 3993 debug_event_listener_callback_result = 2; | |
| 3994 | |
| 3995 v8::V8::AddMessageListener(MessageCallbackCount); | |
| 3996 v8::Debug::SetDebugEventListener(DebugEventCounter); | |
| 3997 // Break on uncaught exception | |
| 3998 ChangeBreakOnException(false, true); | |
| 3999 DebugEventCounterClear(); | |
| 4000 MessageCallbackCountClear(); | |
| 4001 | |
| 4002 // ReThrow error from JavaScript | |
| 4003 reThrowJS->Call(env->Global(), 0, NULL); | |
| 4004 CHECK_EQ(1, exception_hit_count); | |
| 4005 CHECK_EQ(1, uncaught_exception_hit_count); | |
| 4006 CHECK_EQ(1, message_callback_count); | |
| 4007 CHECK(!debug_event_listener_callback.IsEmpty()); | |
| 4008 | |
| 4009 // ReThrow native error | |
| 4010 { | |
| 4011 v8::TryCatch tryCatch; | |
| 4012 env->GetIsolate()->ThrowException(v8::Exception::TypeError( | |
| 4013 v8::String::NewFromUtf8(env->GetIsolate(), "Type error"))); | |
| 4014 CHECK(tryCatch.HasCaught()); | |
| 4015 tryCatch.ReThrow(); | |
| 4016 } | |
| 4017 CHECK_EQ(2, exception_hit_count); | |
| 4018 CHECK_EQ(2, uncaught_exception_hit_count); | |
| 4019 CHECK_EQ(1, message_callback_count); // FIXME: Should it be 2 ? | |
|
Yang
2014/09/10 14:46:13
I think 1 is correct.
aandrey
2014/09/10 14:51:19
hm... why? the native version of JS's try-finally
Yang
2014/09/10 14:56:29
If I understood correctly, the exception thrown in
aandrey
2014/09/10 15:01:53
Right, but destructor should be already executed b
aandrey
2014/09/11 05:48:29
Note, that if I remove the v8::TryCatch and call j
| |
| 4020 CHECK(!debug_event_listener_callback.IsEmpty()); | |
| 4021 | |
| 4022 debug_event_listener_callback.Clear(); | |
| 4023 } | |
| 4024 | |
| 4025 | |
| 3970 // Test break on exception from compiler errors. When compiling using | 4026 // Test break on exception from compiler errors. When compiling using |
| 3971 // v8::Script::Compile there is no JavaScript stack whereas when compiling using | 4027 // v8::Script::Compile there is no JavaScript stack whereas when compiling using |
| 3972 // eval there are JavaScript frames. | 4028 // eval there are JavaScript frames. |
| 3973 TEST(BreakOnCompileException) { | 4029 TEST(BreakOnCompileException) { |
| 3974 DebugLocalContext env; | 4030 DebugLocalContext env; |
| 3975 v8::HandleScope scope(env->GetIsolate()); | 4031 v8::HandleScope scope(env->GetIsolate()); |
| 3976 | 4032 |
| 3977 // For this test, we want to break on uncaught exceptions: | 4033 // For this test, we want to break on uncaught exceptions: |
| 3978 ChangeBreakOnException(false, true); | 4034 ChangeBreakOnException(false, true); |
| 3979 | 4035 |
| (...skipping 3420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7400 v8::Isolate* isolate = env->GetIsolate(); | 7456 v8::Isolate* isolate = env->GetIsolate(); |
| 7401 v8::HandleScope scope(isolate); | 7457 v8::HandleScope scope(isolate); |
| 7402 v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate); | 7458 v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate); |
| 7403 TerminationThread terminator(isolate); | 7459 TerminationThread terminator(isolate); |
| 7404 terminator.Start(); | 7460 terminator.Start(); |
| 7405 v8::TryCatch try_catch; | 7461 v8::TryCatch try_catch; |
| 7406 v8::Debug::DebugBreak(isolate); | 7462 v8::Debug::DebugBreak(isolate); |
| 7407 CompileRun("while (true);"); | 7463 CompileRun("while (true);"); |
| 7408 CHECK(try_catch.HasTerminated()); | 7464 CHECK(try_catch.HasTerminated()); |
| 7409 } | 7465 } |
| OLD | NEW |