Skip to content

Commit 0f56e33

Browse files
eeriimrobinson
andauthored
Document how to develop DevTools tooling (#159)
* Use 'DevTools' spelling everywhere Signed-off-by: eri <[email protected]> * Document how to develop DevTools tooling Signed-off-by: eri <[email protected]> * Apply suggestions from code review Co-authored-by: Martin Robinson <[email protected]> Signed-off-by: eri <[email protected]> * Add information on how to install Wireshark Signed-off-by: eri <[email protected]> --------- Signed-off-by: eri <[email protected]> Co-authored-by: Martin Robinson <[email protected]>
1 parent 52dd13a commit 0f56e33

File tree

5 files changed

+180
-29
lines changed

5 files changed

+180
-29
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
- [Editor support](hacking/editor-support.md)
2525
- [Debugging](hacking/debugging.md)
2626
- [Using DevTools](hacking/using-devtools.md)
27+
- [Developing DevTools\*](hacking/developing-devtools.md)
2728
- [Debugging on OpenHarmony](hacking/debugging-on-openharmony.md)
2829
- [Automated testing\*](hacking/testing.md)
2930
- [Profiling\*](hacking/profiling.md)

src/hacking/debugging-on-openharmony.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ If you encounter this issue when viewing C/C++ logs, you can temporarily turn of
7979
hdc shell hilog -p off
8080
```
8181

82-
### Devtools and port forwards
82+
### DevTools and port forwards
8383

84-
You can enable the devtools and connect to them remotely with Firefox. It is easiest to do this with the command line via
85-
`hdc shell aa start -a EntryAbility -b org.servo.servo --psn=--devtools=1234`
84+
You can enable the DevTools server and connect to it remotely with Firefox. It is easiest to do this with the command line via
85+
`hdc shell aa start -a EntryAbility -b org.servo.servo --psn=--devtools=6080`
8686
To connect to an instance of Servo you have to forward the port with
87-
`hdc fport tcp:1234 tcp:1234`. You should see a message that the forward succeeded. Now you can
88-
connect to the devtools using `localhost:1234`.
87+
`hdc fport tcp:6080 tcp:6080`. You should see a message that the forward succeeded. Now you can
88+
connect to the DevTools server using `localhost:6080`.

src/hacking/developing-devtools.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Developing DevTools
2+
3+
## Concepts
4+
5+
Read the complete [protocol description](https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html) for an in-depth look at all of the important concepts.
6+
7+
- **Client:** Frontend that contains different tooling panels (Inspector, Debugger, Console, ...) and sends requests to the server.
8+
At the moment this is the `about:debugging` page in Firefox.
9+
- **Server:** Browser that is being inspected by the client. Receives messages and delivers them to the appropiate actor so it can reply.
10+
- **Actor:** Code on the server that can exchange messages with the client.
11+
- **Message:** JSON packet that is exchanged between the server and the client.
12+
- Messages from the client must include a `to` field with the name of the actor they are directed to, and a `type` field specifying what sort of packet it is.
13+
- Messages from the server must include a `from` field with the name of the actor that sends them.
14+
15+
```mermaid
16+
sequenceDiagram
17+
participant Client
18+
participant Server
19+
actor Actor1
20+
Client->>Server: {"to": "Actor1", "type": "SayHi"}
21+
Server-->>Actor1: {"to": "Actor1", "type": "SayHi"}
22+
Actor1-->>Server: {"from": "Actor1", "content": "hi!"}
23+
Server->>Client: {"from": "Actor1", "content": "hi!"}
24+
```
25+
26+
## Displaying protocol traffic
27+
28+
<div class="warning _note">
29+
30+
Jump to the [Capturing and processing protocol traffic](#capturing-and-processing-protocol-traffic) section for a more useful tool for log analysis.
31+
</div>
32+
33+
### Servo ↔ Firefox
34+
35+
Servo can show the messages sent and received from the DevTools server.
36+
Enable the correct loging level for `devtools` and you are set:
37+
38+
```sh
39+
RUST_LOG="error,devtools=debug" ./mach run --devtools=6080
40+
```
41+
42+
The output has messages sent (prefixed by `<-`) and messages received (no prefix).
43+
Here we can see how Servo sends the initial connection information and Firefox replies with a request to connect and its version number.
44+
45+
```
46+
[2025-11-07T11:37:35Z INFO devtools] Connection established to 127.0.0.1:47496
47+
[2025-11-07T11:37:35Z DEBUG devtools::protocol] <- {"from":"root","applicationType":"browser","traits":{"sources":false,"highlightable":true,"customHighlighters":true,"networkMonitor":true}}
48+
[2025-11-07T11:37:35Z DEBUG devtools::protocol] {"type":"connect","frontendVersion":"144.0.2","to":"root"}
49+
[2025-11-07T11:37:35Z DEBUG devtools::protocol] <- {"from":"root"}
50+
```
51+
52+
### Firefox ↔ Firefox
53+
54+
A lot of work to improve developer tool support in Servo requires **reverse-engineering** the working implementation in Firefox.
55+
One of the most efficient ways to do this is to observe a successful session in Firefox and record the bidirectional protocol traffic between the server and the client.
56+
57+
<div class="warning _note">
58+
59+
#### On the first run
60+
61+
1. Create a new Firefox profile using `firefox --createprofile devtools-testing`.
62+
1. Launch Firefox with `firefox --new-instance -P devtools-testing`.
63+
1. Open about:config and click on "Accept the Risk and Continue".
64+
1. Change the following configuration:
65+
66+
```sh
67+
# To see logs in the terminal window
68+
browser.dom.window.dump.enabled = true
69+
devtools.debugger.log = true
70+
devtools.debugger.log.verbose = true
71+
# To enable debugging
72+
devtools.chrome.enabled = true
73+
devtools.debugger.remote-enabled = true
74+
# Optional, avoids having to confirm every time there is a connection
75+
devtools.debugger.prompt-connection = false
76+
```
77+
</div>
78+
79+
After Firefox is configured, it can be launched from the terminal starting the DevTools server:
80+
81+
```sh
82+
firefox --new-instance --start-debugger-server 6080 -P devtools-testing
83+
# (on macOS you may need `/Applications/Firefox.app/Contents/MacOS/firefox`)
84+
```
85+
86+
In this case it is possible to use the same Firefox instance as a client and a server. However, it is not recommended to use "This Firefox", as that doesn't give you access to tabs and messages could be different.
87+
Instead, whether you are using the same or a different instance, follow the steps outlined in the [Connecting to Servo](https://book.servo.org/hacking/using-devtools.html#connecting-to-servo) section, skipping the first one.
88+
89+
The terminal window now contains full debug server logs; copy them to somewhere for further analysis.
90+
91+
## Capturing and processing protocol traffic
92+
93+
We have seen a simple way of obtaining message logs from Servo and Firefox.
94+
However, this soon turns complex when wanting to compare logs between the two due to the different formats or performing queries on them.
95+
There is a small script to make this process easier: [`etc/devtools_parser.py`](https://github.com/servo/servo/blob/main/etc/devtools_parser.py).
96+
97+
It is based on [Wireshark](https://www.wireshark.org/), a powerful network packet analyzer; more specifically its cli, `tshark`.
98+
It is configured to log packets sent on your local network on the port that the DevTools server is running.
99+
It can read the payloads from these packets, which are small bits of the JSON DevTools protocol.
100+
101+
**`tshark` needs to be installed** for the script to work.
102+
Install it with your package manager or get the full Wireshark release from [the official website](https://www.wireshark.org/download.html).
103+
104+
```sh
105+
# Linux (Debian based)
106+
sudo apt install tshark
107+
# Linux (Arch based)
108+
sudo pacman -S wireshark-cli
109+
# Linux (Fedora)
110+
sudo dnf install wireshark-cli
111+
# MacOS (With homebrew):
112+
brew install --cask wireshark
113+
# Windows (With chocolatey):
114+
choco install wireshark
115+
```
116+
117+
You may need to add your user to the wireshark group to allow for rootless captures. Use `usermod -a -G wireshark $USER`.
118+
119+
Finally, make sure to [set up a Firefox profile for debugging](#on-the-first-run).
120+
121+
### Capture a session
122+
123+
1. Run either Servo or Firefox with the DevTools server enabled:
124+
125+
```sh
126+
./mach run --devtools 6080
127+
firefox --new-instance --start-debugger-server 6080 -P devtools-testing
128+
```
129+
130+
2. In another terminal, start the script in capture mode (`-w`), specifying the same port as before:
131+
132+
```
133+
./etc/devtools_parser.py -p 6080 -w capture.pcap
134+
```
135+
136+
3. Connect from `about:debugging` following [the same steps](using-devtools.md#connecting-to-servo).
137+
4. Perform any actions you want to record.
138+
5. Press `Ctrl-C` in the terminal running the parser to stop the recording. This will do two things:
139+
- Save the results to a `.pcap` file specified by the `-w` flag.
140+
This is a binary file format for Wireshark, but we can read it later with the same tool.
141+
- Print the message log.
142+
There are two modes: the regular one, where it prints the messages in a friendly way, and `--json`, which emits newline-separated JSON with each message.
143+
6. You can now close Servo or Firefox.
144+
145+
### Read a capture
146+
147+
It is useful to save multiple captures and compare them later.
148+
While `tshark` saves them by default in the `.pcap` format, we can use the same script to get better output from them.
149+
Here the `--json` option is very useful, as it makes it possible to use tools like [`jq`](https://jqlang.org/) or [`nushell`](https://www.nushell.sh/) to query and manipulate data from them.
150+
151+
```sh
152+
# Pretty print the messages
153+
./etc/devtools_parser.py -r capture.pcap
154+
# Save the capture in an NDJSON format
155+
./etc/devtools_parser.py -r capture.pcap --json > capture.json
156+
# Example of a query with jq to get unique message types
157+
./etc/devtools_parser.py -r capture.pcap --json | jq -cs 'map({actor: (.from//.to) | gsub("[0-9]";""), type: .type} | select(.type != null)) | .[]' | sort -u
158+
```
159+
160+
<div class="warning _note">
161+
162+
It is possible to save a JSON capture from the beginning using `./etc/devtools_parser.py -w capture.pcap --json > capture.json`.
163+
</div>
164+
165+
Here is an excerpt from the output of a capture:
166+
167+
```json
168+
{"to": "root", "type": "getRoot"}
169+
{"from": "root", "deviceActor": "device1", "performanceActor": "performance0", "preferenceActor": "preference2", "selected": 0}
170+
{"to": "device1", "type": "getDescription"}
171+
{"from": "device1", "value": {"apptype": "servo", "version": "0.0.1", "appbuildid": "20251106175140", "platformversion": "133.0", "brandName": "Servo"}}
172+
```

src/hacking/using-devtools.md

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,27 +56,5 @@ location.reload()
5656

5757
<div class="warning">
5858

59-
**Note:** support for DevTools features is still a work in progress, and it can break in future versions of Firefox if there are changes to the messaging protocol.
59+
Support for DevTools features is still a work in progress, and it can break in future versions of Firefox if there are changes to the messaging protocol.
6060
</div>
61-
62-
## Capturing protocol traffic from Firefox
63-
64-
A lot of work to improve developer tool support in Servo requires reverse-engineering the working implementation in Firefox.
65-
One of the most efficient ways to do this is to observe a successful session in Firefox and record the bidirectional protocol traffic between the server and the client.
66-
To capture a log of the traffic in a Firefox devtools session that does not involve Servo, follow these steps:
67-
68-
1. Open a terminal window. This window will eventually contain the protocol logs.
69-
1. Launch Firefox from the terminal: `firefox --new-instance -P devtools-testing` (on macOS you may need `/Applications/Firefox.app/Contents/MacOS/firefox`).
70-
1. On your first run:
71-
1. If the profile doesn't exist a window will open listing available profiles. Click on "Create Profile...".
72-
1. Follow the wizard steps to create a profile named `devtools-testing`.
73-
1. To avoid using the devtools profile as a default, select your current profile and click "Start Firefox". Then, close the browser and launch Firefox again with `firefox --new-instance -P devtools-testing`. The profile selection window should not show up again.
74-
1. Open about:config and click on "Accept the Risk and Continue".
75-
1. Set `browser.dom.window.dump.enabled` to true.
76-
1. Set `devtools.debugger.log` to true.
77-
1. Set `devtools.debugger.log.verbose` to true.
78-
1. Load a page that is relevant to your developer tools feature.
79-
1. Visit `about:debugging` and interact with the developer tools feature using the "This Firefox" tab.
80-
1. Close Firefox.
81-
82-
The terminal window now contains full debug server logs; copy them to somewhere for further analysis.

src/running-servoshell.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ For example, to run our [Conway’s Game of Life demo](https://demo.servo.org/ex
2222
$ ./servo --pref dom_webgpu_enabled https://demo.servo.org/experiments/webgpu-game-of-life/
2323
```
2424

25-
Use `--devtools=6080` to enable support for [debugging pages with Firefox devtools](hacking/using-devtools.md):
25+
Use `--devtools=6080` to enable support for [debugging pages with Firefox DevTools](hacking/using-devtools.md):
2626

2727
```sh
2828
$ ./servo --devtools=6080

0 commit comments

Comments
 (0)