Attach debugger to worker from chrome devtools extension
Asked Answered
S

2

2

I was trying to intercept ws messages in my chrome devtools extension.

This question helped me. This is exactly what I need, but the only problem is that it this works only if websocket messeages are sent from the page context (I guess because the debugger is attached to that tab specifically?) but in the page i'm trying to intercept the messages the ws connection is stablished in a web worker.

My main question, is there a way in a chrome devtools extensions to "attach" a debugger to a web-worker? Or maybe I am missing something here?

Thanks for you help.

Swain answered 22/3, 2021 at 11:0 Comment(2)
I've created a bug report here: bugs.chromium.org/p/chromium/issues/…Infestation
I've been inspecting CDP commands using protocol monitor and it seems that Debugger has to be attached to workers separately. They are treated as separate targets. DevTools are using Target domain (such as Target.setAutoAttach for example)Infestation
S
2

Found the reason.

I won't be able to intercept the WebSockets frames in the page I needed with the chrome.debugger API.

Apparently, it seems extensions lack access to contexts loaded via about:, data: and blob: schemes and I wanted to intercept the WebSocket frames establishes the connection in a worker that is loaded via a blob url.

See related Chrome bugs:
https://bugs.chromium.org/p/chromium/issues/detail?id=55084 https://bugs.chromium.org/p/chromium/issues/detail?id=388972

It's also a bug in FF:
https://bugzilla.mozilla.org/show_bug.cgi?id=1475831

Swain answered 24/3, 2021 at 8:45 Comment(0)
I
1

Workers are treated as different targets related to the tabId target in this case: https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-setAutoAttach

To receive WebSocket events from Workers, one should first send 'Target.setAutoAttach' command, and then listen to 'Target.attachedToTarget' events, and then attach debugger to Workers like this:

const version = '1.3';

async function onAttach(debuggeeId) {
  /** Enable receiving 'Target.attachedToTarget' events */
  await chrome.debugger.sendCommand(debuggeeId, 'Target.setAutoAttach', {
    autoAttach: true,
    waitForDebuggerOnStart: true,
    flatten: true,
  }); //
  /** Enable Network events for the current tab */
  chrome.debugger.sendCommand(debuggeeId, 'Network.enable');
}

function allEventHandler(debuggeeId, message, params) {
  /** When workers are created, 'Target.attachedToTarget' events are fired */
  if (message === 'Target.attachedToTarget') {
    /** Attach debugger to workers */
    chrome.debugger.attach(
      { targetId: params.targetInfo.targetId },
      version,
      () => {
        /** Enable Network for workers to receive WebSocket events */
        chrome.debugger.sendCommand(
          { targetId: params.targetInfo.targetId },
          'Network.enable'
        );
      }
    );
  } else {
    console.log(message, params);
  }
}

chrome.debugger.onEvent.addListener(allEventHandler);

/** Click extension icon to attach debugger to the current tab */
chrome.action.onClicked.addListener(function (tab) {
  const tabId = tab.id;
  const debuggeeId = { tabId };
  chrome.debugger.attach(debuggeeId, version, onAttach.bind(null, debuggeeId));
});

Infestation answered 8/1, 2022 at 20:30 Comment(1)
Thanks! This was exactly what I needed. However my code has changed a bit since I made this question and now my worker code is not loaded anymore through a blob url, now the worker code comes form an ordinary http request. But I guess this probably would work in my previous situation too.Swain

© 2022 - 2024 — McMap. All rights reserved.