Commit 6695290c authored by yangguo's avatar yangguo Committed by Commit bot

[debugger] add utility to print break location.

This is to help debugging missing break locations.

R=vogelheim@chromium.org

Review URL: https://codereview.chromium.org/1732253002

Cr-Commit-Position: refs/heads/master@{#34284}
parent c81bbda7
...@@ -1853,6 +1853,10 @@ void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) { ...@@ -1853,6 +1853,10 @@ void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) {
// Bail out if there is no listener for this event // Bail out if there is no listener for this event
if (ignore_events()) return; if (ignore_events()) return;
#ifdef DEBUG
PrintBreakLocation();
#endif // DEBUG
HandleScope scope(isolate_); HandleScope scope(isolate_);
// Create the event data object. // Create the event data object.
Handle<Object> event_data; Handle<Object> event_data;
...@@ -2314,6 +2318,44 @@ void Debug::ProcessDebugMessages(bool debug_command_only) { ...@@ -2314,6 +2318,44 @@ void Debug::ProcessDebugMessages(bool debug_command_only) {
OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only); OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
} }
#ifdef DEBUG
void Debug::PrintBreakLocation() {
if (!FLAG_print_break_location) return;
HandleScope scope(isolate_);
JavaScriptFrameIterator iterator(isolate_);
if (iterator.done()) return;
JavaScriptFrame* frame = iterator.frame();
FrameSummary summary = GetFirstFrameSummary(frame);
int source_position =
summary.abstract_code()->SourcePosition(summary.code_offset());
Handle<Object> script_obj(summary.function()->shared()->script(), isolate_);
PrintF("[debug] break in function '");
summary.function()->PrintName();
PrintF("'.\n");
if (script_obj->IsScript()) {
Handle<Script> script = Handle<Script>::cast(script_obj);
Handle<String> source(String::cast(script->source()));
Script::InitLineEnds(script);
int line = Script::GetLineNumber(script, source_position);
int column = Script::GetColumnNumber(script, source_position);
Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
int line_start =
line == 0 ? 0 : Smi::cast(line_ends->get(line - 1))->value();
int line_end = Smi::cast(line_ends->get(line))->value();
DisallowHeapAllocation no_gc;
String::FlatContent content = source->GetFlatContent();
if (content.IsOneByte()) {
PrintF("[debug] %.*s\n", line_end - line_start,
content.ToOneByteVector().start() + line_start);
PrintF("[debug] ");
for (int i = 0; i < column; i++) PrintF(" ");
PrintF("^\n");
} else {
PrintF("[debug] at line %d column %d\n", line, column);
}
}
}
#endif // DEBUG
DebugScope::DebugScope(Debug* debug) DebugScope::DebugScope(Debug* debug)
: debug_(debug), : debug_(debug),
......
...@@ -617,6 +617,8 @@ class Debug { ...@@ -617,6 +617,8 @@ class Debug {
void ThreadInit(); void ThreadInit();
void PrintBreakLocation();
// Global handles. // Global handles.
Handle<Context> debug_context_; Handle<Context> debug_context_;
Handle<Object> event_listener_; Handle<Object> event_listener_;
......
...@@ -991,6 +991,9 @@ DEFINE_BOOL(trace_regexp_assembler, false, ...@@ -991,6 +991,9 @@ DEFINE_BOOL(trace_regexp_assembler, false,
"trace regexp macro assembler calls.") "trace regexp macro assembler calls.")
DEFINE_BOOL(trace_regexp_parser, false, "trace regexp parsing") DEFINE_BOOL(trace_regexp_parser, false, "trace regexp parsing")
// Debugger
DEFINE_BOOL(print_break_location, false, "print source location on debug break")
// //
// Logging and profiling flags // Logging and profiling flags
// //
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment