code.vegaprotocol.io/vega@v0.79.0/DEBUG_WITH_DLV.md (about) 1 # Debugging with `dlv` 2 3 ## VSCode 4 5 There are two options: 6 1) You can start entire `V E G A` and `tendermint` and fire instructions at your node and debug the results. 7 2) You can attach the `dlv` debugger to the integration tests. 8 9 For both you'll need to 10 - Read and follow instructions in `GETTING_STARTED.md` first. 11 - Install `dlv` if you've not already done so. In `VSCode` you can do this by launching the "Command Palette" and running `Go: Install/Update Tools`, select `dlv`, press OK. 12 13 14 ### Entire V E G A with tendermint 15 16 Once you have successfully installed `V E G A` with `tendermint` these are the steps to let you debug. 17 18 - Build the debug version (with optimisations disabled) of all the binaries with: 19 20 ```bash 21 DEBUGVEGA=yes make build 22 ``` 23 If you're on a Mac `make build` will fail. This is because Mac OS isn't updating `bash` beyond version 3.x (something to do with GPL). The easiest solution is to install a recent `bash` e.g. with `https://brew.sh/` and then either run the above in the new `bash` instance or add your new bash to `/etc/shells` and then do `chsh` to change your default shell. 24 25 - Use "Command Palette" to run `Debug: Open launch.json`. If you didn't already have a `launch.json` file, this will create one with the below default configuration which can be used to debug the current package. Enter the following into `launch.json` (which will be by default created inside `vega/.vscode/`): 26 27 ```json 28 { 29 "version": "0.2.0", 30 "configurations": [ 31 { 32 "name": "Debug V E G A", 33 "type": "go", 34 "request": "attach", 35 "mode": "remote", 36 "remotePath": "/path/to/vega", // trading-core 37 "port": 2345, 38 "host": "127.0.0.1", 39 "showLog":true, 40 "trace":"log" 41 } 42 ] 43 } 44 ``` 45 Edit the `"remotePath"` appropriately to reflect where your trading-core source code lives. 46 47 - Now open ideally two terminal windows. In the first one launch `tendermint` as you normally would. To hard-reset the chain and start from scratch use 48 49 ```bash 50 tendermint unsafe_reset_all && tendermint init && tendermint node 2>./tendermint.stderr.out 1>./tendermint.stdout.out 51 ``` 52 Now launch the `dlv` debugger with `V E G A` by running 53 54 ```bash 55 dlv exec /path/to/vega/cmd/vega/vega-dbg --headless --listen=:2345 --log --api-version=2 -- node 56 ``` 57 again replacing the path to match where your git copy of trading core lives. If all went well you'll see something like: 58 59 ``` 60 API server listening at: [::]:2345 61 2019-10-13T20:37:41+01:00 info layer=debugger launching process with args: [/path/to/vega/cmd/vega/vega-dbg node] 62 debugserver-@(#)PROGRAM:LLDB PROJECT:lldb-1100.0.28..1 63 for x86_64. 64 Got a connection, launched process /path/to/vega/cmd/vega/vega (pid = 35671). 65 ``` 66 - Finally in `VSCode` open the Debug panel and run the `Debug V E G A` configuration created in the 2nd step above. At this point `V E G A` should be running. 67 - Test that `V E G A` is running as expected by e.g. visiting `http://localhost:3003/statistics` or trying something in the GraphQL playground at `http://localhost:3004/`. If all is well you should be able to create users, place orders etc. as normal. More to the point breakpoints, call stack and variables should be usable as normal in `VSCode`. 68 69 70 71 ### Debugging integration tests 72 73 - Build a debug version of the `godog` test harness: from the root of the `V E G A` core repository 74 75 ```bash 76 DEBUGVEGA=yes go test -c ./integration/... 77 ``` 78 79 - Use "Command Palette" to run `Debug: Open launch.json`. If you didn't already have a `launch.json` file, this will create one with the below default configuration which can be used to debug the current package. Enter the following into `launch.json` (which will be by default created inside `vega/.vscode/`): 80 81 ```json 82 { 83 "version": "0.2.0", 84 "configurations": [ 85 { 86 "name": "Debug Test", 87 "type": "go", 88 "request": "attach", 89 "mode": "remote", 90 "port": 2345, 91 "host": "127.0.0.1", 92 "showLog":true, 93 "trace":"log" 94 } 95 ] 96 } 97 ``` 98 99 - Stick a breakpoint somewhere in the code that you *know* will be triggered by your integration test (this clearly has to be in a `.go` file, not `.feature`). 100 101 102 - Launch the feature test you care about (in the example below it's `2668-price-monitoring.feature`) 103 ```bash 104 dlv exec ./integration.test --headless --listen=:2345 --log --api-version=2 -- -godog.format=pretty -- $(pwd)/integration/features/2668-price-monitoring.feature 105 ``` 106 The `godog` test harness is now running inside `dlv` and it has launched the integration test you chose. 107 108 - Finally in `VSCode` open the Debug panel and run the `Debug Test`. 109 110 ---- 111 112 ## Vim 113 114 Prerequisites: Vim version >= 8.0 and the [vim-go](https://github.com/fatih/vim-go) plug-in. 115 116 ### Build a debug binary for delve 117 118 A debug binary can be built using the `go test -c` command, which works in the same way `go build` would. Some compiler optimisations, however, can mess up the output when trying to print certain variables (e.g. slices being passed appearing empty, or containing seemingly garbage values). 119 To disable any and all compiler optimisations we might encounter, simply add the `gcflags="ALL=-N -l"` option. 120 121 To build the vega binary for debugging, then: 122 123 ```bash 124 go test -c -gcflags="ALL=-N -l" ./cmd/vega 125 ``` 126 127 To build a binary to step through integration tests, simply run 128 129 ```bash 130 go test -c -gcflags="ALL=-N -l" ./core/integration 131 ``` 132 133 The output will be a binary called either `vega.test` or `integration.test`. 134 135 ### Start delve in headless mode 136 137 As-is, you can use the compiled binary to step through the code in dlv. Setting breakpoints using things like `b core/execution/market.go:2107` is quite tedious, though, and only shows you a few lines of code around the breakpoint. Having the ability to set breakpoints and check out variables in our editor is what we're after. To do that, we need to start dlv as a debug server, so we can connect to it from inside Vim: 138 139 ```bash 140 dlv exec --headless --api-version=2 --listen 127.0.0.1:9876 ./integration.test -- ./core/integration/features 141 ``` 142 143 The address and port to listen to is arbitrary, but in this particular example, we'll use 9876. In this example we're starting a debug session on the integration test binary. To debug `vega.test`, just replace `integration.test` with `vega.test` (obviously). 144 145 ### Passing arguments to the test binary 146 147 Passing in additional arguments/parameters is as easy as just appending `--` to the command above and specifying the desired arguments and flags. To run integration tests with a specific tag, for example, the full command looks like this: 148 149 ```bash 150 dlv exec --headless --api-version=2 --listen 127.0.0.1:9876 ./integration.test -- --godog.tags=LPWrong -- ./core/integration/features 151 ``` 152 153 ### Connecting to delve from Vim 154 155 Now that dlv is running, we can open the code we want to step through in Vim, and connect to our debugger: 156 157 ```bash 158 vim core/execution/market.go 159 ``` 160 161 Once in our editor, just enter the command `:GoDebugConnect 127.0.0.1:9876` 162 163 Debugger buffers will load as you've configured (default is the call stack top left, call stack, arguments, and registers bottom left, runtime and routine info bottom buffer). Open any file, jump to any line where you want to set a breakpoint, and run the `:GoDebugBreakpoint` (or `:GoDebugBr`) command. 164 165 To start executing the code, run `:GoDebugContinue`, and the test binary will run until a breakpoint is encountered. From that point on, you can use standard debugger commands (like `:GoDebugStep`, `:GoDebugStepOut`, and of course `:GoDebugContinue`). A full list of commands, what they do can be found by running `:h :GoDebug`. 166 The `vim-go` plug-in documentation also contains a list of default bindings (e.g. F9 for toggling a breakpoint, F5 for `:GoDebugContinue`), and detailed instructions on how to create your own bindings, how to customise your setup (`:h go-debug-settings`). 167 168 To stop debugging, run `:GoDebugStop`. This will close the debug buffers, and the dlv process will return. 169 170 ### Inspecting and setting variables 171 172 Seeing what value a variable is set to is arguably the most common thing to do when debugging. Simply run `:GoDebugPrint foo` to see a full print-out of what a variable actually holds. Seeing as we're dealing with maps and arrays of objects quite a lot. It's important to note that dlv (and by extension vim-go debugging) does not restrict access to unexported fields, so things like `:GoDebugPrint order.Price.u[0]` work fine. `:GoDebugPrint` evaluates its argument as an expression, so things like `:GoDebugPrint foo == 10` is valid. 173 174 Setting a variable to a different value is equally possible, but just like delve itself, this is limited to types like `bool`, `float`, `int`, and `uint` variants, and pointers. This can be useful when debugging functions that have some boolean argument (e.g. `force` is set to `false`, change to true by running `:GoDebugSet force true`).