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`).