使用Chrome扩展程序调试源代码文件

9

我正在尝试使用Chrome扩展来控制调试器。

我正在使用devtools-protocolchrome extension文档,但我不知道如何实现它们,因为我没有看到使用方法的示例。我使用了此处提供的示例扩展程序,该示例程序只显示了如何暂停和恢复调试器,但对我毫无用处。我尝试在示例中实现一些方法,但没有反应。

function onDebuggerEnabled(debuggeeId) {
  chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
        lineNumber: 45825,
        url: 'full https link to the js file from source tab'
  });
}

问题在于我正在尝试调试的js文件是从网站内部加载到源选项卡中的,而且它很大,经过格式化后有150k+行,需要一些时间来加载。现在有人能告诉我如何在源代码(使用Chrome扩展)中简单地添加断点,以便在触发操作时停止调试器,这样我就可以更改值等吗?

1
你尝试过在 JavaScript 中使用“调试器(debugger)”这个词吗? - Red Devil
首先,您需要附加调试器。至于命令,请参阅文档中的协议嗅探部分。此外,您可以检查使用chrome.debugger的扩展程序。 - wOxxOm
调试器已附加,此函数仅从整个js文件中提取。我不知道如何在网站内加载的源代码中设置断点到js文件。 - AlwaysConfused
你能提供更多的背景信息吗?你是想调试一个内容脚本文件吗?你所说的“已在源标签页中加载”是什么意思?它只是常规加载的js文件还是某种动态获取的脚本?如果可以的话,是否可以提供源文件的网址(如果不受保密协议限制)? - Karen Grigoryan
我尝试了一个基本的例子,使用一个简单的脚本,但是无法使其工作。chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", { lineNumber: 0 });总是返回null,什么也没有发生。我尝试了不同的URL和scriptId,但还是没有用。 - Dávid Molnár
显示剩余3条评论
5个回答

2
也许您正在放置错误的断点位置(格式化源代码),尝试使用原始源代码并添加columnNumber: integer 这里是工作版本JavaScript pause/resume -> background.js:
- 安装此扩展程序 - 打开https://ewwink.github.io/demo/Debugger.setBreakpointByUrl.html - 单击调试器暂停按钮 - 单击“Debug Me!”按钮 - 它将在第10行的https://ewwink.github.io/demo/script.js处触发断点 - 单击调试器继续按钮,您将看到消息变量“hijacked…”
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// mod by ewwink

var attachedTabs = {};
var version = "1.1";

chrome.debugger.onEvent.addListener(onEvent);
chrome.debugger.onDetach.addListener(onDetach);

chrome.browserAction.onClicked.addListener(function(tab) {
  var tabId = tab.id;
  var debuggeeId = {
    tabId: tabId
  };

  if (attachedTabs[tabId] == "pausing")
    return;

  if (!attachedTabs[tabId])
    chrome.debugger.attach(debuggeeId, version, onAttach.bind(null, debuggeeId));
  else if (attachedTabs[tabId])
    chrome.debugger.detach(debuggeeId, onDetach.bind(null, debuggeeId));
});

function onAttach(debuggeeId) {
  if (chrome.runtime.lastError) {
    alert(chrome.runtime.lastError.message);
    return;
  }

  var tabId = debuggeeId.tabId;
  chrome.browserAction.setIcon({
    tabId: tabId,
    path: "debuggerPausing.png"
  });
  chrome.browserAction.setTitle({
    tabId: tabId,
    title: "Pausing JavaScript"
  });
  attachedTabs[tabId] = "pausing";
  chrome.debugger.sendCommand(
    debuggeeId, "Debugger.enable", {},
    onDebuggerEnabled.bind(null, debuggeeId));
}

function onDebuggerEnabled(debuggeeId) {
  chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
    lineNumber: 10,
    url: 'https://ewwink.github.io/demo/script.js'
  });
}

function onEvent(debuggeeId, method, params) {
  var tabId = debuggeeId.tabId;
  if (method == "Debugger.paused") {
    attachedTabs[tabId] = "paused";
    var frameId = params.callFrames[0].callFrameId;
    chrome.browserAction.setIcon({
      tabId: tabId,
      path: "debuggerContinue.png"
    });
    chrome.browserAction.setTitle({
      tabId: tabId,
      title: "Resume JavaScript"
    });
    chrome.debugger.sendCommand(debuggeeId, "Debugger.setVariableValue", {
      scopeNumber: 0,
      variableName: "changeMe",
      newValue: {
        value: 'hijacked by Extension'
      },
      callFrameId: frameId
    });
  }
}

function onDetach(debuggeeId) {
  var tabId = debuggeeId.tabId;
  delete attachedTabs[tabId];
  chrome.browserAction.setIcon({
    tabId: tabId,
    path: "debuggerPause.png"
  });
  chrome.browserAction.setTitle({
    tabId: tabId,
    title: "Pause JavaScript"
  });
}

演示

调试器扩展演示


这个怎么处理?我已经测试过了,结果和我的原始脚本完全一样 - 没有结果。我检查了控制台等,根本没有任何反应。即使这个解决方案能够起作用,js文件也不是来自源选项卡...顺便说一下,我使用的是原始的js进行调试,而不是格式化版本,但非常感谢你的努力。 - AlwaysConfused
它可以在您的示例上运行,但在我的情况下不起作用,因为js是从资源内部的应用程序加载的,即使我有js的url,它也不会触发断点(我无法检测是否添加了断点),或者它根本不会添加一个。使用您的示例,js在扩展名下的源中加载,而出于某种原因,它不会加载我的js。这可能是因为js url已经在资源中..? - AlwaysConfused
好的,这些答案都没有让我接近我想要做的事情,但我认为你的答案非常清晰并且有效,唯一的问题是我需要弄清楚如何在blob js上附加break。 - AlwaysConfused

1

编辑:刚看到你的评论,说这是你正在编写的自定义扩展程序。我的回答对你没有帮助(抱歉!),但它可能会帮助那些在这里寻找在Chrome中设置常规断点方法的人。


也许你已经尝试过了,但是...你是否尝试过直接点击想要设置断点的行号呢?
就像这样:

你甚至可以在同一行中的几个不同调用中启用或禁用断点。
当页面加载时,使用F12打开Dev工具,然后导航到“Sources”面板中的JS文件,并添加所需的断点。然后,刷新页面以再次加载它 - Chrome将记住您设置断点的位置并停在那里。

1
但他想要通过扩展程序来完成这个操作,而不是使用开发者工具。 - Dávid Molnár
是的,但OP也说他在“Sources”选项卡中加载了JS文件,所以他们确实在使用Dev工具。无论如何,我刚刚看到了OP的评论,他说这是为了编写一个扩展程序,让人们在外部资源中设置断点 - 当然,上面的方法在这种情况下不起作用。但我想很多人会来到这个问题,寻找在Chrome中设置断点的方法,所以现在我会保留答案。 - walen

0

我在询问Chrome相关问题,但在调试器停止进程之前无法修改任何内容。我需要找到一种方法,通过URL或访问源选项卡并使用某种引用方式来加载JS到扩展程序中。我会查看您提供的信息,以确定是否可以使用Firefox解决我的问题。 - AlwaysConfused
哦,不行,那跟我能用的完全不一样。你必须修改代码,但我不能这样做,因为我必须在 Web 应用程序启动后访问其中加载的资源。 - AlwaysConfused

0
function breakhere() {
    debugger;
}

你能否在现有的JS源代码中注入“调试器”行? - AlwaysConfused

0

好的,首先你需要发送命令Debugger.enable,类似这样:

var tabId = parseInt(window.location.search.substring(1));

window.addEventListener("load", function() {
  chrome.debugger.sendCommand({tabId:tabId}, "Debugger.enable");
  chrome.debugger.attach( tabId, "0.1" );
  chrome.debugger.onEvent.addListener(onEvent);
});

然后在你的onEvent函数内,你可以设置断点

function onEvent(debuggeeId, message, params) {
  if (tabId != debuggeeId.tabId) return;
  var res = Debugger.setBreakpointByUrl( 2, 'url-of-the-script-file' );
}

我强烈建议您查看此页面上的嗅探部分:https://chromedevtools.github.io/devtools-protocol/,因为我能够通过WS协议看到返回的JSON,这将帮助您做任何您想做的事情。我不能为您构建完整的扩展程序,您需要自己动手。

我猜您需要添加一些DOM元素,其中包含从Network.getResponseBody解析出来的脚本列表,然后添加一些UX工具来选择这些脚本并让用户进行调试,这个过程可能需要花费一些时间 :(

希望我已经引导您走向了正确的方向,祝您好运!


调试器已启用,就像我说的那样,那只是整个示例中设置了调试器的一部分。你试图解释的内容对我来说太复杂了。所以你的意思是仅仅使用调试器API setBreakpointByUrl在这种情况下不起作用? - AlwaysConfused
不,我并不是说它不会工作,相反,我认为它应该可以工作,文档上也这么说。我知道你可以进行所有的调试,但只要用户打开“检查器”,你就会失去你的实例。用户在这里掌握主导权,所以从可用性的角度考虑,我不建议继续开发它。 - Kresimir Pendic
我指的是我面临的主要问题,为什么它不起作用,我猜想,这是因为JS太大了,当我设置断点时,文件还没有在后台加载?我不想使用扩展进行任何复杂的调试...我只需要在断点处停止进程就可以了。 - AlwaysConfused

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接