-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add doc: Debugging with vscode (#142)
- Loading branch information
Showing
1 changed file
with
139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
# Debugging Contracts with VSCode | ||
|
||
The `ckb-debugger` provides a gdb-server mode for contract debugging. In VSCode, this requires the [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug) extension to connect to `ckb-debugger`'s gdb-server for debugging. | ||
* **Note:** While CodeLLDB supports remote debugging, it does not work well in this case due to its use of `LLDB` version 17. | ||
|
||
## Compile | ||
|
||
The compiled contract must include the appropriate symbol files for debugging. For C, add `-g`; for Rust, set `strip = false` and `debug = true` in the `profile` section. After compiling, since binaries with symbol files tend to be large, you need to process them with `llvm-objcopy`: | ||
|
||
```shell | ||
cp build/ckb-debug/<Contract-Name> build/ckb-debug/<Contract-Name>.debug | ||
llvm-objcopy --strip-debug --strip-all build/ckb-debug/<Contract-Name> | ||
``` | ||
|
||
To configure `tasks.json` in VSCode (using the `c1` contract as an example): | ||
|
||
```json | ||
{ | ||
"label": "Build Debug", | ||
"type": "shell", | ||
"command": "make build && cp build/ckb-debug/c1 build/ckb-debug/c1.debug && llvm-objcopy --strip-debug --strip-all build/ckb-debug/c1" | ||
} | ||
``` | ||
|
||
### Running `ckb-debugger` | ||
|
||
(Skip this section if the contract you're debugging doesn't require transaction information.) | ||
|
||
Typically, contracts require transaction data, which can be extracted from unit tests using the [dump_tx](https://github.com/nervosnetwork/ckb-testtool/blob/41c76ed2aef128fdf6e7e73b61d1bfa45e02b005/src/context.rs#L573) function. Add the following code before `context.verify_tx(&tx, MAX_CYCLES)` in your unit tests: | ||
|
||
```rust | ||
let tx_data = context.dump_tx(&tx).expect("dump tx info"); | ||
std::fs::write( | ||
"tx.json", | ||
serde_json::to_string_pretty(&tx_data).expect("json"), | ||
).expect("write tx"); | ||
``` | ||
|
||
Then start `ckb-debugger` with: | ||
|
||
```shell | ||
ckb-debugger \ | ||
--bin=build/ckb-debug/c1 \ | ||
--mode=gdb_gdbstub \ | ||
--gdb-listen=0.0.0.0:8000 \ | ||
--tx-file=tests/tx.json \ | ||
-s=lock \ | ||
-i=0 | ||
``` | ||
|
||
* This example uses port 8000, but feel free to change it if needed. | ||
* Adjust `-s` and `-i` according to your contract’s requirements. | ||
|
||
You can configure `tasks.json` in VSCode to automatically start `ckb-debugger`: | ||
|
||
```json | ||
{ | ||
"label": "Debug c1", | ||
"isBackground": true, | ||
"type": "process", | ||
"command": "ckb-debugger", | ||
"args": [ | ||
"--bin=build/ckb-debug/c1", | ||
"--mode=gdb_gdbstub", | ||
"--gdb-listen=0.0.0.0:8000", | ||
"--tx-file=tests/tx.json", | ||
"-s=lock", | ||
"-i=0" | ||
], | ||
"options": { | ||
"cwd": "${workspaceRoot}" | ||
} | ||
} | ||
``` | ||
* The `isBackground` setting ensures the task runs in the background and stays active during debugging. | ||
|
||
Since `ckb-debugger` doesn’t automatically exit after debugging, you'll need a task to stop it: | ||
|
||
```json | ||
{ | ||
"label": "stop-ckb-debugger", | ||
"type": "shell", | ||
"command": "killall ckb-debugger || true" | ||
} | ||
``` | ||
|
||
### GDB Debugging | ||
|
||
```shell | ||
gdb build/ckb-debug/c1.debug | ||
``` | ||
|
||
Then connect to `ckb-debugger`'s GDB server: | ||
|
||
```shell | ||
target remote 127.0.0.1:8000 | ||
``` | ||
|
||
Once connected, you can debug using standard GDB commands. | ||
|
||
### LLDB Debugging | ||
|
||
* Ensure you are using LLDB version 18 or later. | ||
|
||
```shell | ||
lldb build/ckb-debugger/c1.debug | ||
``` | ||
|
||
Then connect to `ckb-debugger`'s GDB server (you can omit the local address and just use the port): | ||
|
||
```shell | ||
gdb-remote 8000 | ||
``` | ||
|
||
After connecting, use standard LLDB commands for debugging. | ||
|
||
### VSCode Debugging | ||
|
||
* GDB must be installed. | ||
* The Native Debug extension is required for debugging in VSCode. | ||
|
||
First, configure `tasks.json` as described above. Then set up your `launch.json` for debugging: | ||
|
||
```json | ||
{ | ||
"name": "GDB", | ||
"type": "gdb", | ||
"request": "attach", | ||
"executable": "build/ckb-debug/c1.debug", | ||
"debugger_args": [], | ||
"cwd": "${workspaceRoot}", | ||
"remote": true, | ||
"target": "127.0.0.1:8000", | ||
"preLaunchTask": "Debug c1", | ||
"postDebugTask": "stop-ckb-debugger" | ||
} | ||
``` | ||
|
||
After launching the debugger, you can set breakpoints and inspect variables as usual. |