}
+BreakLocation::BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo,
+ RelocInfo* original_rinfo, int position,
+ int statement_position)
+ : debug_info_(debug_info),
+ pc_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())),
+ original_pc_offset_(static_cast<int>(
+ original_rinfo->pc() - debug_info->original_code()->entry())),
+ rmode_(rinfo->rmode()),
+ original_rmode_(original_rinfo->rmode()),
+ data_(rinfo->data()),
+ original_data_(original_rinfo->data()),
+ position_(position),
+ statement_position_(statement_position) {
+ DCHECK(debug_info_->GetIsolate()->debug()->is_active());
+}
+
+
BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
BreakLocatorType type)
: debug_info_(debug_info),
Heap* heap = isolate_->heap();
HandleScope scope(isolate_);
+ DCHECK(isolate_->debug()->is_active());
+
// Perform a GC to get rid of all unreferenced scripts.
heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
void Debug::UpdateState() {
- is_active_ = message_handler_ != NULL || !event_listener_.is_null();
- if (is_active_ || in_debug_scope()) {
+ bool is_active = message_handler_ != NULL || !event_listener_.is_null();
+ if (is_active || in_debug_scope()) {
// Note that the debug context could have already been loaded to
// bootstrap test cases.
isolate_->compilation_cache()->Disable();
- is_active_ = Load();
+ is_active = Load();
} else if (is_loaded()) {
isolate_->compilation_cache()->Enable();
Unload();
}
+ is_active_ = is_active;
}
private:
BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo,
- RelocInfo* original_rinfo, int position, int statement_position)
- : debug_info_(debug_info),
- pc_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())),
- original_pc_offset_(static_cast<int>(
- original_rinfo->pc() - debug_info->original_code()->entry())),
- rmode_(rinfo->rmode()),
- original_rmode_(original_rinfo->rmode()),
- data_(rinfo->data()),
- original_data_(original_rinfo->data()),
- position_(position),
- statement_position_(statement_position) {}
+ RelocInfo* original_rinfo, int position,
+ int statement_position);
class Iterator {
public:
static void RecordEvalCaller(Handle<Script> script);
bool CheckExecutionState(int id) {
- return !debug_context().is_null() && break_id() != 0 && break_id() == id;
+ return is_active() && !debug_context().is_null() && break_id() != 0 &&
+ break_id() == id;
}
// Flags and states.
RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
-
+ RUNTIME_ASSERT(isolate->debug()->is_active());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
+ RUNTIME_ASSERT(isolate->debug()->is_active());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
HandleScope scope(isolate);
DCHECK(args.length() == 4);
+ RUNTIME_ASSERT(isolate->debug()->is_active());
CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
RUNTIME_ASSERT(source_position >= 0);
RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
+ RUNTIME_ASSERT(isolate->debug()->is_active());
CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
// Clear break point.
RUNTIME_FUNCTION(Runtime_ClearStepping) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
+ RUNTIME_ASSERT(isolate->debug()->is_active());
isolate->debug()->ClearStepping();
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
+ RUNTIME_ASSERT(isolate->debug()->is_active());
Handle<FixedArray> instances;
{
HandleScope scope(isolate);
CHECK(isolate->debug()->live_edit_enabled());
DCHECK(args.length() == 2);
+ RUNTIME_ASSERT(isolate->debug()->is_active());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
// built-in function such as Array.forEach to enable stepping into the callback.
RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
DCHECK(args.length() == 1);
+ RUNTIME_ASSERT(isolate->debug()->is_active());
+
Debug* debug = isolate->debug();
if (!debug->IsStepping()) return isolate->heap()->undefined_value();
}
+static void DummyDebugEventListener(
+ const v8::Debug::EventDetails& event_details) {}
+
+
+static inline void EnableDebugger() {
+ v8::Debug::SetDebugEventListener(&DummyDebugEventListener);
+}
+
+
+static inline void DisableDebugger() { v8::Debug::SetDebugEventListener(NULL); }
+
+
// Helper class for new allocations tracking and checking.
// To use checking of JS allocations tracking in a test,
// just create an instance of this class.
CompileRun("function break_here() { }");
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*env->Global()->Get(v8_str("break_here"))));
+ EnableDebugger();
v8::internal::Debug* debug = CcTest::i_isolate()->debug();
int position = 0;
debug->SetBreakPoint(func, i::Handle<i::Object>(v8::internal::Smi::FromInt(1),
// Check that we got no cached data.
CHECK(source.GetCachedData() == NULL);
+ DisableDebugger();
}
const char* source, const char* name,
int position, v8::internal::RelocInfo::Mode mode,
Code* debug_break) {
+ EnableDebugger();
i::Debug* debug = CcTest::i_isolate()->debug();
// Create function and set the break point.
i::RelocInfo rinfo = location.rinfo();
CHECK(!rinfo.IsPatchedReturnSequence());
}
+
+ DisableDebugger();
}
v8::internal::RelocInfo::CODE_TARGET,
CcTest::i_isolate()->builtins()->builtin(
Builtins::kStoreIC_DebugBreak));
- CheckDebugBreakFunction(&env,
- "function f3(){var a=x;}", "f3",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kLoadIC_DebugBreak));
+ CheckDebugBreakFunction(
+ &env, "function f3(){x();}", "f3", 0,
+ v8::internal::RelocInfo::CODE_TARGET,
+ CcTest::i_isolate()->builtins()->builtin(Builtins::kLoadIC_DebugBreak));
// TODO(1240753): Make the test architecture independent or split
// parts of the debugger into architecture dependent files. This
CheckDebugBreakFunction(
&env,
"function f4(){var index='propertyName'; var a={}; a[index] = 'x';}",
- "f4",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
+ "f4", 39, v8::internal::RelocInfo::CODE_TARGET,
CcTest::i_isolate()->builtins()->builtin(
Builtins::kKeyedStoreIC_DebugBreak));
CheckDebugBreakFunction(
&env,
"function f5(){var index='propertyName'; var a={}; return a[index];}",
- "f5",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
+ "f5", 39, v8::internal::RelocInfo::CODE_TARGET,
CcTest::i_isolate()->builtins()->builtin(
Builtins::kKeyedLoadIC_DebugBreak));
#endif
- CheckDebugBreakFunction(
- &env,
- "function f6(a){return a==null;}",
- "f6",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kCompareNilIC_DebugBreak));
+ CheckDebugBreakFunction(&env, "function f6(){(0==null)()}", "f6", 0,
+ v8::internal::RelocInfo::CODE_TARGET,
+ CcTest::i_isolate()->builtins()->builtin(
+ Builtins::kCompareNilIC_DebugBreak));
// Check the debug break code stubs for call ICs with different number of
// parameters.
CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
CHECK(!HasDebugInfo(foo));
CHECK(!HasDebugInfo(bar));
+ EnableDebugger();
// One function (foo) is debugged.
int bp1 = SetBreakPoint(foo, 0);
CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
CHECK(HasDebugInfo(bar));
// No functions are debugged.
ClearBreakPoint(bp2);
+ DisableDebugger();
CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
CHECK(!HasDebugInfo(foo));
CHECK(!HasDebugInfo(bar));
v8::Local<v8::Function> foo =
CompileFunction(&env, "function foo(){a=1;}", "foo");
- debug_event_remove_break_point = SetBreakPoint(foo, 0);
// Register the debug event listener pasing the function
v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo);
+ debug_event_remove_break_point = SetBreakPoint(foo, 0);
+
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
// Run foo to allow it to get optimized.
CompileRun("a=0; b=0; c=0; foo();");
- SetBreakPoint(foo, 3);
-
// Register a debug event listener which steps and counts.
v8::Debug::SetDebugEventListener(DebugEventStep);
+ SetBreakPoint(foo, 3);
+
step_action = StepIn;
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
}
-static void DummyDebugEventListener(
- const v8::Debug::EventDetails& event_details) {
-}
-
-
TEST(SetDebugEventListenerOnUninitializedVM) {
v8::Debug::SetDebugEventListener(DummyDebugEventListener);
}
v8::String::NewExternal(env->GetIsolate(), &source_ext_str);
v8::Handle<v8::Script> evil_script(v8::Script::Compile(source));
// "use" evil_script to make the compiler happy.
- (void) evil_script;
+ USE(evil_script);
Handle<i::ExternalTwoByteString> i_source(
i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
// This situation can happen if source was an external string disposed
bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
i::FLAG_allow_natives_syntax = true;
+ EnableDebugger();
CompileRun(
"var scripts = %DebugGetLoadedScripts();"
"var count = scripts.length;"
"for (var i = 0; i < count; ++i) {"
" scripts[i].line_ends;"
"}");
+ DisableDebugger();
// Must not crash while accessing line_ends.
i::FLAG_allow_natives_syntax = allow_natives_syntax;
const char* script = "function f() {};";
const char* resource_name = "test_resource";
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
+
// Set a couple of provisional breakpoint on lines out of the script lines
// range.
int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name,
SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5);
after_compile_message_count = 0;
- v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::ScriptOrigin origin(
v8::String::NewFromUtf8(env->GetIsolate(), resource_name),
// disabled.
int position = 0;
Handle<Object> breakpoint_object(Smi::FromInt(0), isolate);
+ EnableDebugger();
isolate->debug()->SetBreakPoint(function, breakpoint_object, &position);
isolate->debug()->ClearAllBreakPoints();
+ DisableDebugger();
// Force optimization now that code flushing is disabled.
{ v8::HandleScope scope(CcTest::isolate());
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
+Debug.setListener(function(){});
var function_z_text =
" function Z() {\n"
}
assertEquals(0, Debug.scriptBreakPoints().length);
+Debug.setListener(null);
// corresponding byte-code PCs should coincide before change and after it.
Debug = debug.Debug
+Debug.setListener(function() {});
eval(
"function F1() { return 5; }\n" +
if (pcArray1 && pcArray2) {
assertArrayEquals(pcArray1, pcArray2);
}
+
+Debug.setListener(null);
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug;
+Debug.setListener(listener);
SlimFunction = eval(
"(function() {\n " +
}
}
-Debug.setListener(listener);
var animal = SlimFunction();
}
assertEquals("Capybara", animal);
+
+Debug.setListener(null);
// Flags: --expose-debug-as debug
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
+Debug.setListener(function(){});
// Set and remove a script break point for a named script.
var sbp = Debug.setScriptBreakPointByName("1", 2, 3);
assertEquals(1, Debug.scriptBreakPoints().length);
Debug.clearBreakPoint(sbp2);
assertEquals(0, Debug.scriptBreakPoints().length);
+
+Debug.setListener(null);
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug;
+Debug.setListener(function(){});
Date();
RegExp();
// Check a nonexistent script.
var dummy_script = Debug.findScript('dummy.js');
assertTrue(typeof dummy_script == 'undefined');
+
+Debug.setListener(null);
debugger; /*pause*/
}
-function TestCase(fun, frame_number) {
+function TestCase(fun, frame_number, line_number) {
var exception = false;
var codeSnippet = undefined;
var resultPositions = undefined;
Debug.setListener(listener);
+ var breakpointId;
+ if (line_number) breakpointId = Debug.setBreakPoint(fun, line_number);
+
fun();
+ if (line_number) Debug.clearBreakPoint(breakpointId);
+
Debug.setListener(null);
assertTrue(!exception, exception);
}
function TestCaseWithBreakpoint(fun, line_number, frame_number) {
- var breakpointId = Debug.setBreakPoint(fun, line_number);
- TestCase(fun, frame_number);
- Debug.clearBreakPoint(breakpointId);
+ TestCase(fun, frame_number, line_number);
}
function TestCaseWithException(fun, frame_number) {
// Flags: --allow-natives-syntax --cache=code
// Test that script ids are unique and we found the correct ones.
+var Debug = %GetDebugContext().Debug;
+Debug.setListener(function(){});
+
var scripts = %DebugGetLoadedScripts();
scripts.sort(function(a, b) { return a.id - b.id; });
var user_script_count = 0;
// Found mjsunit.js and this script.
assertEquals(2, user_script_count);
+
+Debug.setListener(null);
// Get the Debug object exposed from the debug context global object.
var Debug = debug.Debug
-// Set breakpoint on line 6.
-var bp = Debug.setBreakPoint(f, 6);
function listener(event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.Break) {
// Add the debug event listener.
Debug.setListener(listener);
+
+//Set breakpoint on line 6.
+var bp = Debug.setBreakPoint(f, 6);
+
result = -1;
f();
assertEquals(1, result);
exception = null;
f2();
assertEquals(null, exception, exception);
+
+Debug.setListener(null);
// Advance to the first yield.
assertIteratorResult(value1, false, obj.next());
- // Add a breakpoint on line 3 (the second yield).
- var bp = Debug.setBreakPoint(gen, 3);
-
// Enable the debugger, which should force recompilation of the generator
// function and relocation of the suspended generator activation.
Debug.setListener(listener);
+ // Add a breakpoint on line 3 (the second yield).
+ var bp = Debug.setBreakPoint(gen, 3);
+
// Check that the generator resumes and suspends properly.
assertIteratorResult(value2, false, obj.next());
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
-// Set breakpoint on line 6.
-var bp = Debug.setBreakPoint(f, 6);
function listener(event, exec_state, event_data, data) {
if (event == Debug.DebugEvent.Break) {
// Add the debug event listener.
Debug.setListener(listener);
+
+//Set breakpoint on line 6.
+var bp = Debug.setBreakPoint(f, 6);
+
result = -1;
f();
assertEquals(1, result);
};
Debug = debug.Debug;
-var bp = Debug.setBreakPoint(f, 0);
function listener(event, exec_state, event_data, data) {
result = exec_state.frame().evaluate("i").value();
};
Debug.setListener(listener);
+var bp = Debug.setBreakPoint(f, 0);
+
assertThrows(function() { f(); }, RangeError);
function sentinel() {}
Debug = debug.Debug;
+Debug.setListener(function(){});
var script = Debug.findScript(sentinel);
var line = 14;
// the break point.
assertTrue(line_start <= actual);
assertTrue(actual <= line_end);
+
+Debug.setListener(null);
// Flags: --gc-interval=33 --expose-gc --allow-natives-syntax
+var Debug = %GetDebugContext().Debug;
+Debug.setListener(function(){});
+
%DebugGetLoadedScripts();
+
+Debug.setListener(null);
// Flags: --expose-debug-as debug
Debug = debug.Debug
+Debug.setListener(function(){});
function f() {a=1;b=2};
function g() {
%OptimizeFunctionOnNextCall(Debug.setBreakPoint);
bp = Debug.setBreakPoint(f, 0, 0);
Debug.clearBreakPoint(bp);
+
+Debug.setListener(null);
// and (shared) unoptimized code on foo, and sets both to lazy-compile builtin.
// Clear the break point immediately after to deactivate the debugger.
// Do all of this after compile graph has been created.
+Debug.setListener(function(){});
Debug.setBreakPoint(bar, 0, 0);
Debug.clearAllBreakPoints();
+Debug.setListener(null);
// At this point, concurrent recompilation is still blocked.
assertUnoptimized(foo, "no sync");