添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

远程调试

Chrome的调试目标主要分两种:Chrome PC 浏览器和 Chrome Mobile

调试PC端chrome

除了使用“审查元素”外,还可以用一个进程的chrome调试另一个进程的chrome。利用命令行启动chrome,并开启调试端口即可:

1
sudo /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=2333

需要注意被调试端暴露的端口只接受来自127.0.0.1 或者localhost 的端口请求。

调试Android端chrome

调试Android端Chrome需要:

  • adb连接(USB线连接或adb网络调试)
  • 手机端webview需要打开调试模式
    1
    webview.setWebContentsDebuggingEnabled(true)

    满足上述2点后,在PC上的chrome中输入chrome://inspect或about://inspect,即可进入调试界面。

    调试实现

    Chrome的调试本质上通过端口来实现,PC端chrome在开启调试模式时会指定端口,Android端通过adb forward来实现:

    1
    adb forward tcp:2333 localabstract:webview_devtools_remote_6784

    被调试的webview在手机上创建一个Unix Domain Socket, 这个socket的名字为 webview_devtools remote ,其中pid为webview所处的进程号,执行adb forward命令后,adb将这个
    Unix Domain Socket转发到PC上一个本地端口,进而实现了调试。

    调试权限

    Google 为了限制调试端口的接入范围,对于 Chrome PC 浏览器,调试端口只接受来自 127.0.0.1 或者 localhost 的数据请求,所以,无法通过你的本地机器 IP 来调试 Chrome。

    对于 Android Chrome/WebView,调试端口只接受来自于 shell 这个用户数据请求,也就是说只能通过 USB 进行调试,或者通过adb网络连接调试。

    为了测试这一点,我们通过本地socket连接Unix Domain Socket进行了实验验证:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include <stdio.h>
    #include <string.h>
    #include <stddef.h>
    #include <sys/un.h>
    #include <sys/socket.h>
    void send_remote_request(char *msg)
    {
    int localsocket, len;
    struct sockaddr_un remote;

    if ((localsocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    exit(1);
    }

    char *name="webview_devtools_remote_6784";//与java上层相同哦

    remote.sun_path[0] = '\0'; /* abstract namespace */
    strcpy(remote.sun_path+1, name);
    remote.sun_family = AF_UNIX;
    int nameLen = strlen(name);
    len = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);

    if (connect(localsocket, (struct sockaddr *)&remote, len) == -1) {
    printf("connect error\n");
    return;
    }

    if (send(localsocket, msg, strlen(msg),0) == -1) {
    printf("send error\n");
    return;
    }

    char buf[1024];

    if (recv(localsocket,buf,1024, 0) == -1){
    printf("rece error\n");
    return;
    }

    printf("received: %s",buf);

    close(localsocket);
    }


    int main()
    {
    char *http="GET /json/version HTTP/1.1\r\nHost: 127.0.0.1\r\nUser-Agent: curl/7.54.0\r\nAccept: */*\r\n\r\n";
    send_remote_request(http);
    }

    上述代码编译的程序在uid=0(root权限)运行时,会受到返回socket数据:

    在其他权限执行时,socket会连接错误:

    请求调试端口

    通过以上的调试方式的接入以及调试端口的打开,这个时候在浏览器中请求127.0.0.1:2333,可以看到以下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [ {
    "description": "{\"attached\":true,\"empty\":false,\"height\":1055,\"screenX\":0,\"screenY\":210,\"visible\":true,\"width\":845}",
    "devtoolsFrontendUrl": "http://chrome-devtools-frontend.appspot.com/serve_rev/@8daf58f7f40d22013c59388236c8e71e1117cb2c/inspector.html?ws=127.0.0.1:2333/devtools/page/0F8BF00855E9F57A1D62802C1882DE05",
    "faviconUrl": "http://mat1.gtimg.com/www/icon/favicon2.ico",
    "id": "0F8BF00855E9F57A1D62802C1882DE05",
    "title": "腾讯首页",
    "type": "page",
    "url": "http://www.qq.com/",
    "webSocketDebuggerUrl": "ws://127.0.0.1:2333/devtools/page/0F8BF00855E9F57A1D62802C1882DE05"
    } ]

    其中,最重要的 2 个参数分别是 id 和 webSocketDebuggerUrl。

    Chrome 会为每个页面分配一个唯一的 id,作为该页面的唯一标识符。几乎对目标浏览器的所有操作都是需要带上这个 id。

    webSocketDebuggerUrl 则在调试该页面需要用到的一个 WebSocket 连接。chrome 的 devtool 的所有调试功能,都是基于 Remote Debugging Protocol 使用 WebSocket 来进行数据传输的。每一个页面都有自己不同的 webSocketDebuggerUrl。这个 webSocketDebuggerUrl是通过 url 的 query 参数传递给 chrome devtool 的。

    chrome 的 devtool 可以从 Chrome 浏览器中进行提取 devtool 源码或者从 blink 源码中获取。在部署好自己的 chrome devtool 代码之后,下面既可以开始对 Chrome 进行调试, 浏览器输入以下内容:

    1
    http://path_to_your_devtool/devtool.html?ws=127.0.0.1:2333/devtools/page/0F8BF00855E9F57A1D62802C1882DE05

    Chrome 提供了以下这些 http 接口控制目标浏览器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 获取当前所有可调式页面信息
    http://127.0.0.1:9222/json

    # 获取调试目标 WebView/blink 的版本号
    http://127.0.0.1:9222/json/version

    # 创建新的 tab,并加载 url
    http://127.0.0.1:9222/json/new?url

    # 关闭 id 对应的 tab
    http://127.0.0.1:9222/json/close/id

    Chrome Android远程调试诊断

    通过chrome://inspect调试webview出现404

    可能问题:
    PC端的chrome比手机端版本新,使用inspect feedback可解;
    如果没有inspect feedback,使用旧版本的Chrome调试;
    使用离线的第三方工具包调试,参考
    https://www.cnblogs.com/slmk/p/7591126.html

    其他参考链接:
    1. https://www.cnblogs.com/slmk/p/9832081.html
    2. https://stackoverflow.com/questions/51519636/google-chrome-developer-tools-android-debugging-returns-http-1-1-404-not-found
    3. https://bugs.chromium.org/p/chromium/issues/detail?id=853525&can=8&q=&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified

    是否开启了unix domain socket

    运行下列命令,如果查到abstract socket:@chrome_devtools_remote,则表明chrome for android 开启了unix domain socket。如果查到abstract socket@webview_devtools_remote_27594,则说明了AndroidWebView也开启了unix domain socket

    1
    cat /proc/net/unix | grep --text  _devtools_remote

    是否开启了websocket服务器

    可以通过ptyhon库websocket-client来测试.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ sudo pip install websocket-client
    python
    >>> import websocket
    >>> ws = websocket.create_connection("ws://localhost:4000/devtools/page/140")
    >>> ws.send("Hello,world")
    17
    >>> result = ws.recv()
    >>> print result
    {"error":{"code":-32700,"message":"Message must be in JSON format"},"id":null}

    参考资料:

  • 揭秘浏览器远程调试技术 http://taobaofed.org/blog/2016/10/19/chrome-remote-debugging-technics/
  • Chrome for Android Remote Inspector 原理 https://blog.csdn.net/xxhforest/article/details/52204197
  • LocalServerSocket https://developer.android.com/reference/android/net/LocalServerSocket
  • Linux下进程间通讯方式 - UNIX Domain Socket https://blog.csdn.net/z2066411585/article/details/78966434/
  •