org.chromium.sdk/src/org/chromium/sdk/internal/tools/v8/processor/BacktraceProcessor.java
changeset 2 e4420d2515f1
child 52 f577ea64429e
equal deleted inserted replaced
1:ef76fc2ac88c 2:e4420d2515f1
       
     1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
       
     2 // Use of this source code is governed by a BSD-style license that can be
       
     3 // found in the LICENSE file.
       
     4 
       
     5 package org.chromium.sdk.internal.tools.v8.processor;
       
     6 
       
     7 import java.util.Collection;
       
     8 import java.util.List;
       
     9 import java.util.regex.Matcher;
       
    10 import java.util.regex.Pattern;
       
    11 
       
    12 import org.chromium.sdk.DebugContext;
       
    13 import org.chromium.sdk.JavascriptVm;
       
    14 import org.chromium.sdk.Script;
       
    15 import org.chromium.sdk.internal.ContextBuilder;
       
    16 import org.chromium.sdk.internal.DebugSession;
       
    17 import org.chromium.sdk.internal.FrameMirror;
       
    18 import org.chromium.sdk.internal.HandleManager;
       
    19 import org.chromium.sdk.internal.protocol.BacktraceCommandBody;
       
    20 import org.chromium.sdk.internal.protocol.CommandResponse;
       
    21 import org.chromium.sdk.internal.protocol.FrameObject;
       
    22 import org.chromium.sdk.internal.protocol.SuccessCommandResponse;
       
    23 import org.chromium.sdk.internal.protocol.data.ScriptHandle;
       
    24 import org.chromium.sdk.internal.protocol.data.SomeHandle;
       
    25 import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException;
       
    26 import org.chromium.sdk.internal.tools.v8.DebuggerCommand;
       
    27 import org.chromium.sdk.internal.tools.v8.V8ProtocolUtil;
       
    28 import org.json.simple.JSONObject;
       
    29 
       
    30 /**
       
    31  * Handles the "backtrace" V8 command replies.
       
    32  */
       
    33 class BacktraceProcessor implements org.chromium.sdk.internal.tools.v8.V8CommandProcessor.V8HandlerCallback {
       
    34 
       
    35   private final ContextBuilder.ExpectingBacktraceStep step2;
       
    36 
       
    37   BacktraceProcessor(ContextBuilder.ExpectingBacktraceStep step2) {
       
    38     this.step2 = step2;
       
    39  }
       
    40 
       
    41   public void messageReceived(CommandResponse response) {
       
    42     String commandString = response.getCommand();
       
    43 
       
    44     DebuggerCommand command = DebuggerCommand.forString(commandString);
       
    45     if (command != DebuggerCommand.BACKTRACE) {
       
    46       handleWrongStacktrace();
       
    47     }
       
    48     SuccessCommandResponse successResponse = response.asSuccess();
       
    49     if (successResponse == null) {
       
    50       handleWrongStacktrace();
       
    51     }
       
    52 
       
    53     final DebugContext debugContext = setFrames(successResponse);
       
    54     final DebugSession debugSession = step2.getInternalContext().getDebugSession();
       
    55 
       
    56     JavascriptVm.ScriptsCallback afterScriptsAreLoaded = new JavascriptVm.ScriptsCallback() {
       
    57       public void failure(String errorMessage) {
       
    58         handleWrongStacktrace();
       
    59       }
       
    60 
       
    61       public void success(Collection<Script> scripts) {
       
    62         debugSession.getDebugEventListener().suspended(debugContext);
       
    63       }
       
    64     };
       
    65 
       
    66     debugSession.getScriptLoader().loadAllScripts(afterScriptsAreLoaded, null);
       
    67   }
       
    68 
       
    69   private DebugContext setFrames(SuccessCommandResponse response) {
       
    70     BacktraceCommandBody body;
       
    71     try {
       
    72       body = response.getBody().asBacktraceCommandBody();
       
    73     } catch (JsonProtocolParseException e) {
       
    74       throw new RuntimeException(e);
       
    75     }
       
    76     List<FrameObject> jsonFrames = body.getFrames();
       
    77     int frameCnt = jsonFrames.size();
       
    78     FrameMirror[] frameMirrors = new FrameMirror[frameCnt];
       
    79 
       
    80     HandleManager handleManager = step2.getInternalContext().getHandleManager();
       
    81 
       
    82     List<SomeHandle> refs = response.getRefs();
       
    83     handleManager.putAll(refs);
       
    84     for (int frameIdx = 0; frameIdx < frameCnt; frameIdx++) {
       
    85       FrameObject frameObject = jsonFrames.get(frameIdx);
       
    86       int index = (int) frameObject.getIndex();
       
    87       FrameObject frame = jsonFrames.get(frameIdx);
       
    88       JSONObject func = frame.getFunc();
       
    89 
       
    90       String text = frame.getText().replace('\r', ' ').replace('\n', ' ');
       
    91       Matcher m = FRAME_TEXT_PATTERN.matcher(text);
       
    92       m.matches();
       
    93       String url = m.group(1);
       
    94 
       
    95       int currentLine = (int) frame.getLine();
       
    96 
       
    97       // If we stopped because of the debuggerword then we're on the next
       
    98       // line.
       
    99       // TODO(apavlov): Terry says: we need to use the [e.g. Rhino] AST to
       
   100       // decide if line is debuggerword. If so, find the next sequential line.
       
   101       // The below works for simple scripts but doesn't take into account
       
   102       // comments, etc.
       
   103       String srcLine = frame.getSourceLineText();
       
   104       if (srcLine.trim().startsWith(DEBUGGER_RESERVED)) {
       
   105         currentLine++;
       
   106       }
       
   107       Long scriptRef = V8ProtocolUtil.getObjectRef(frame.getScript());
       
   108 
       
   109       Long scriptId = -1L;
       
   110       if (scriptRef != null) {
       
   111         SomeHandle handle = handleManager.getHandle(scriptRef);
       
   112         ScriptHandle scriptHandle;
       
   113         try {
       
   114           scriptHandle = handle.asScriptHandle();
       
   115         } catch (JsonProtocolParseException e) {
       
   116           throw new RuntimeException(e);
       
   117         }
       
   118         if (handle != null) {
       
   119           scriptId = scriptHandle.id();
       
   120         }
       
   121       }
       
   122       frameMirrors[index] =
       
   123           new FrameMirror(frameObject, url, currentLine, scriptId,
       
   124               V8ProtocolUtil.getFunctionName(func));
       
   125     }
       
   126 
       
   127 
       
   128     return step2.setFrames(frameMirrors);
       
   129   }
       
   130 
       
   131   public void failure(String message) {
       
   132     handleWrongStacktrace();
       
   133   }
       
   134 
       
   135   private void handleWrongStacktrace() {
       
   136     step2.getInternalContext().getContextBuilder().buildSequenceFailure();
       
   137   }
       
   138 
       
   139   private static final String DEBUGGER_RESERVED = "debugger";
       
   140 
       
   141   /** Regex for the "text" field of the "backtrace" element response. */
       
   142   private static final String FRAME_TEXT_REGEX =
       
   143       "^(?:.+) ([^\\s]+) line (.+) column (.+)" + " (?:\\(position (.+)\\))?";
       
   144 
       
   145   /** A pattern for the frame "text" regex. */
       
   146   private static final Pattern FRAME_TEXT_PATTERN = Pattern.compile(FRAME_TEXT_REGEX);
       
   147 
       
   148 }