{/* Trang này được tạo tự động từ SKILL.md của kỹ năng bởi website/scripts/generate-skill-docs.py. Chỉnh sửa nguồn SKILL.md, không phải trang này. */}
Trình gỡ lỗi kiểm tra nút
Gỡ lỗi Node.js thông qua --inspect + Chrome DevTools Protocol CLI.
Siêu dữ liệu kỹ năng
| Nguồn | Đi kèm (được cài đặt theo mặc định) |
| Đường dẫn |
skills/software-development/node-inspect-debugger ` | | Phiên bản |
1.0.0 ` | | Tác giả | Đại lý Hermes | | Giấy phép | MIT | | Nền tảng | Linux, macOS, Windows | | Thẻ |
debugging
, `nodejs
, `node-inspect
, `cdp
, `breakpoints
,
ui-TUI |
| Kỹ năng liên quan | XPROTECTX26XPROTECTX, XPROTECTX27XPROTECTX, XPROTECTX28XPROTECTX |
Tham khảo: đầy đủ SKILL.md
Sau đây là định nghĩa kỹ năng đầy đủ mà Hermes tải khi kỹ năng này được kích hoạt. Đây là những gì tác nhân coi là hướng dẫn khi kỹ năng được kích hoạt.
Node.js Kiểm tra trình gỡ lỗi
Tổng quan
Khi
console.log không đủ, hãy điều khiển trình kiểm tra V8 tích hợp của Node theo chương trình từ terminal. Bạn nhận được các điểm dừng thực sự, bước vào/qua/ra, di chuyển trong ngăn xếp lệnh gọi, kết xuất phạm vi cục bộ/đóng và đánh giá biểu thức tùy ý trong khung bị tạm dừng.
Hai công cụ, chọn một:
- ** `node inspect
** — tích hợp sẵn, không cần cài đặt, CLI REPL. Tốt nhất để chọc nhanh.
- **
ndb/ CDP qua `chrome-remote-interface
** — có thể viết tập lệnh từ Node/Python; tốt nhất khi bạn muốn tự động hóa nhiều điểm dừng, thu thập trạng thái trên các lần chạy hoặc gỡ lỗi không tương tác từ vòng lặp tác nhân.
Ưu tiên
node inspect trước. Nó luôn có sẵn và REPL nhanh chóng.
Khi nào nên sử dụng
- Kiểm tra nút không thành công và bạn cần xem trạng thái trung gian
- ui-TUI gặp sự cố hoặc hoạt động sai và bạn muốn kiểm tra kết xuất trước trạng thái React/Ink
- các tiến trình con của tôi_gateway ( `_SlashWorker
, PTY bridge Workers) hoạt động sai
- Bạn cần kiểm tra một giá trị trong một bao đóng mà
console.logkhông thể tiếp cận nếu không vá lỗi - Perf: gắn vào một tiến trình đang chạy để ghi lại cấu hình CPU hoặc ảnh chụp nhanh đống
**Không sử dụng cho:** những việcconsole.log ` giải quyết trong vòng chưa đầy một phút. Việc gỡ lỗi theo hướng điểm dừng nặng hơn; sử dụng nó khi phần thưởng là có thật.
Tham khảo nhanh:
node inspect REPL
Khởi chạy bị tạm dừng ở dòng đầu tiên:
node inspect path/to/script.js
# or with tsx
node --inspect-brk $(which tsx) path/to/script.ts
`
``Lời nhắc
`debug>
` chấp nhận:
| Lệnh | Hành động |
|---|---|
|
`c
` hoặc
`cont
` | tiếp tục |
|
`n
` hoặc
`next
` | bước qua |
|
`s
` hoặc
`step
` | bước vào |
|
`o
` hoặc
`out
` | bước ra |
|
`pause
` | tạm dừng chạy mã |
|
`sb('file.js', 42)
` | đặt điểm dừng tại dòng file.js 42 |
|
`sb(42)
` | đặt điểm dừng ở dòng 42 của tệp hiện tại |
|
`sb('functionName')
` | ngắt khi hàm được gọi |
|
`cb('file.js', 42)
` | điểm dừng rõ ràng |
|
`breakpoints
` | liệt kê tất cả các điểm dừng |
|
`bt
` | backtrace (ngăn xếp cuộc gọi) |
|
`list(5)
` | hiển thị 5 dòng nguồn xung quanh vị trí hiện tại |
|
`watch('expr')
` | đánh giá exp mỗi lần tạm dừng |
|
`watchers
` | hiển thị các biểu thức đã xem |
|
`repl
` | thả vào REPL trong phạm vi hiện tại (Ctrl+C để thoát REPL) |
|
`exec expr
` | đánh giá biểu thức một lần |
|
`restart
` | khởi động lại tập lệnh |
|
`kill
` | giết kịch bản |
|
.exit
` | thoát khỏi trình gỡ lỗi |
**Trong chế độ phụ
`repl
:** nhập bất kỳ biểu thức JS nào, bao gồm quyền truy cập vào các biến cục bộ/biến đóng.
`Ctrl+C
` thoát trở lại
`debug>
.
## Đính kèm vào một tiến trình đang chạy
Khi quy trình đang chạy (ví dụ: máy chủ nhà phát triển tồn tại lâu dài hoặc cổng TUI):
``` bash
# 1. Send SIGUSR1 to enable the inspector on an existing process
kill -SIGUSR1 <pid
# Node prints: Debugger listening on ws://127.0.0.1:9229/<uuid
# 2. Attach the debugger CLI
node inspect -p <pid
# or by URL
node inspect ws://127.0.0.1:9229/<uuid
`
``Để bắt đầu một quy trình với thanh tra viên ngay từ đầu:
``` bash
node --inspect script.js # listen on 127.0.0.1:9229, keep running
node --inspect-brk script.js # listen AND pause on first line
node --inspect=0.0.0.0:9230 script.js # custom host:port
`
``Đối với TypeScript qua tsx:
`bash
node --inspect-brk --import tsx script.ts
# or older tsx
node --inspect-brk -r tsx/cjs script.ts
`
## CDP có lập trình (kịch bản từ terminal)
Khi bạn muốn tự động hóa - đặt nhiều điểm dừng, nắm bắt trạng thái phạm vi, viết lại tập lệnh - hãy sử dụng
`chrome-remote-interface
:
``` bash
npm i -g chrome-remote-interface # or project-local
# Start your target:
node --inspect-brk=9229 target.js &
`
``Tập lệnh trình điều khiển (lưu dưới dạng
/tmp/cdp-debug.js
):
`JavaScript
const CDP = require('chrome-remote-interface');`(async () => {
const CLIent = await CDP({ port: 9229 });
const { Debugger, Runtime } = CLIent;
Debugger.paused(async ({ callFrames, reason }) => {
const top = callFrames[0];
console.log(
`PAUSED: $\{reason} @ $\{top.url}:$\{top.location.lineNumber + 1}
);`// Walk scopes for locals
for (const scope of top.scopeChain) {
if (scope.type === 'local' || scope.type === 'closure') {
const { result } = await Runtime.getProperties({
objectId: scope.object.objectId,
ownProperties: true,
});
for (const p of result) {
console.log(
` $\{scope.type}.$\{p.name} =
, p.value?.value ?? p.value?.description);
}
}
}`// Evaluate an expression in the paused frame
const { result } = await Debugger.evaluateOnCallFrame({
callFrameId: top.callFrameId,
expression: 'typeof state !== "undefined" ? JSON.stringify(state) : "n/a"',
});
console.log('state =', result.value ?? result.description);`await Debugger.resume();
});`await Runtime.enable();
await Debugger.enable();`// Set a breakpoint by URL regex + line
await Debugger.setBreakpointByUrl({
urlRegex: '.*app\\.tsx$',
lineNumber: 119, // 0-indexed
columnNumber: 0,
});`await Runtime.runIfWaitingForDebugger();
})();
`
``Chạy nó:
``` bash
node /tmp/cdp-debug.js
`
``Lưu ý dành riêng cho Hermes:
`chrome-remote-interface
` KHÔNG có trong
`ui-TUI/package.JSON
. Cài đặt nó vào một vị trí vứt đi nếu bạn không muốn làm hỏng dự án:
`bash
mkdir -p /tmp/cdp-tools && cd /tmp/cdp-tools && npm i chrome-remote-interface
NODE_PATH=/tmp/cdp-tools/node_modules node /tmp/cdp-debug.js
`
## Gỡ lỗi Hermes ui-TUI
TUI được xây dựng Ink + tsx. Hai tình huống phổ biến:
### Gỡ lỗi một thành phần Ink trong nhà phát triển
`ui-TUI/package.JSON
` có
`npm run dev
` (tsx --watch). Thêm
`
--inspect-brk
` bằng cách chạy trực tiếp tsx:
``` bash
cd /home/bb/Hermes-agent/ui-TUI
npm run build # produce dist/ once so transpile isn't needed on first load
node --inspect-brk dist/entry.js
# In another terminal:
node inspect -p <node pid
`
``Sau đó bên trong
`debug>
:
`
sb('dist/app.js', 220) # or wherever the suspect render is
cont
`
``Khi nó tạm dừng,
`repl
` → kiểm tra
`props
, tham chiếu trạng thái, giá trị trình xử lý
`useInput
, v.v.
### Gỡ lỗi
`Hermes --TUI
` đang chạy
TUI sinh ra Nút từ Python CLI. Con đường dễ nhất:
``` bash
# 1. Launch TUI
Hermes --TUI &
TUI_PID=$(pgrep -f 'ui-TUI/dist/entry' | head -1)
# 2. Enable inspector on that Node PID
kill -SIGUSR1 "$TUI_PID"
# 3. Find the WS URL
curl -s http://127.0.0.1:9229/JSON/list | jq -r '.[0].webSocketDebuggerUrl'
# 4. Attach
node inspect ws://127.0.0.1:9229/<uuid
`
``Tương tác với TUI (nhập vào cửa sổ của nó) tiếp tục thúc đẩy quá trình thực thi; trình gỡ lỗi của bạn có thể tạm dừng nó trên điểm dừng tại bất kỳ
`sb(...)
` nào.
### Gỡ lỗi các tiến trình con
`_SlashWorker
` / PTY
Đó là Python, không phải Node - hãy sử dụng kỹ năng
`Python-debugpy
` cho chúng. Chỉ các phần Nút (Ink UI, ứng dụng khách tôi_gateway, các bài kiểm tra chạy tsx trong
`ui-TUI/
) mới sử dụng kỹ năng này.
## Chạy thử nghiệm Vitest trong trình gỡ lỗi
``` bash
cd /home/bb/Hermes-agent/ui-TUI
# Run a single test file paused on entry
node --inspect-brk ./node_modules/vitest/vitest.mjs run --no-file-parallelism src/app/foo.test.tsx
`
``Trong một terminal khác:
`node inspect -p <pid
, sau đó là
`sb('src/app/foo.tsx', 42)
,
`cont
.
Sử dụng
--no-file-parallelism
` (vitest) hoặc
--runInBand
` (jest) để chỉ tồn tại một công nhân — việc gỡ lỗi một nhóm rất khó khăn.
## Ảnh chụp nhanh đống & Cấu hình CPU (Không tương tác)
Từ trình điều khiển CDP ở trên, đổi Debugger lấy
`HeapProfiler
` /
`Profiler
:
`JavaScript
// CPU profile for 5 seconds
await CLIent.Profiler.enable();
await CLIent.Profiler.start();
await new Promise(r => setTimeout(r, 5000));
const { profile } = await CLIent.Profiler.stop();
require('fs').writeFileSync('/tmp/cpu.cpuprofile', JSON.stringify(profile));
// Open /tmp/cpu.cpuprofile in Chrome DevTools → Performance tab
`
`
`JavaScript
// Heap snapshot
await CLIent.HeapProfiler.enable();
const chunks = [];
CLIent.HeapProfiler.addHeapSnapshotChunk(({ chunk }) => chunks.push(chunk));
await CLIent.HeapProfiler.takeHeapSnapshot({ reportProgress: false });
require('fs').writeFileSync('/tmp/heap.heapsnapshot', chunks.join(''));
`
## Những cạm bẫy thường gặp
1. **Số dòng sai trong nguồn TS.** Điểm dừng chạm vào JS được phát ra, không phải
.ts
. (a) phá vỡ
`dist/*.js
` được xây dựng hoặc (b) kích hoạt sơ đồ nguồn (
`node --enable-source-maps
) và sử dụng
`sb('src/app.tsx', N)
- nhưng chỉ với các máy khách CDP tuân theo sơ đồ nguồn.
`node inspect
` CLI thì không.
2. **
--inspect
` so với
--inspect-brk
.**
--inspect
` khởi động trình kiểm tra nhưng không tạm dừng; tập lệnh của bạn sẽ vượt qua điểm dừng đầu tiên nếu bạn đính kèm quá muộn. Sử dụng
--inspect-brk
` khi bạn cần đặt điểm dừng trước khi chạy bất kỳ mã nào.
3. **Xung đột cổng.** Mặc định là
`9229
. Nếu có nhiều quy trình Nút đang kiểm tra, hãy chuyển
--inspect=0
` (cổng ngẫu nhiên) và đọc URL thực tế từ
/JSON/list
:
``` bash
curl -s http://127.0.0.1:9229/JSON/list # lists all inspectable targets on the host
4. **Quy trình con.**
`
--inspect
` trên cha mẹ KHÔNG kiểm tra con của nó. Sử dụng
`NODE_OPTIONS='--inspect-brk' node parent.js
` để tuyên truyền đến từng trẻ em; lưu ý rằng tất cả chúng đều cần các cổng duy nhất (Nút tự động tăng khi
`NODE_OPTIONS='--inspect'
` được kế thừa).
5. **Tiêu diệt trong nền.** Nếu bạn
`Ctrl+C
` trong tổng số
`node inspect
` trong khi mục tiêu bị tạm dừng thì mục tiêu đó vẫn bị tạm dừng. Trước tiên là
`cont
` hoặc
`kill
` mục tiêu một cách rõ ràng.
6. **Chạy
`node inspect
` thông qua terminal đại lý.** Đó là REPL thân thiện với PTY. Ở Hermes, hãy khởi chạy nó với
`terminal(pty=true)
` hoặc
`background=true
+
`process(action='submit', data='...')
. Chế độ nền trước không phải PTY sẽ hoạt động đối với các lệnh một lần nhưng không hoạt động đối với bước tương tác.
7. **Bảo mật.**
--inspect=0.0.0.0:9229
` hiển thị việc thực thi mã tùy ý. Luôn liên kết với
`127.0.0.1
` (mặc định) trừ khi bạn có mạng bị cô lập.
## Danh sách kiểm tra xác minh
Sau khi thiết lập phiên gỡ lỗi, hãy xác minh:
- [ ]
`curl -s http://127.0.0.1:9229/JSON/list
` trả về chính xác mục tiêu mà bạn mong đợi
- [ ] Điểm dừng đầu tiên thực sự đạt đến (nếu không, bạn có thể đã bỏ lỡ
--inspect-brk
` hoặc được đính kèm sau khi thực hiện xong)
- [ ] Danh sách nguồn khi tạm dừng hiển thị đúng tệp (không khớp = vấn đề về sơ đồ nguồn, xem cạm bẫy 1)
- [ ]
`exec process.pid
` trong
`repl
` trả về PID mà bạn muốn đính kèm vào
## Bí quyết một lần`**"Tại sao biến này không được xác định ở dòng X?"**
`
``` bash
node --inspect-brk script.js &
node inspect -p $!
# debug>
sb('script.js', X)
cont
# paused. Now:
repl
> myVariable
> Object.keys(this)
`
``**"Đường dẫn vào hàm này là gì?"**
`
debug> sb('suspectFn')
debug> cont
# paused on entry
debug> bt
`
``**"Chuỗi không đồng bộ này bị treo — ở đâu?"**
`
# Start with --inspect (no -brk), let it run to the hang, then:
debug> pause
debug> bt
# Now you see the stuck frame
`
`