This section shows how to install a Go debugger (delve) and how to actually do some debugging from a terminal.

For somebody coming from a C/C++ background this should feed very familiar as the GNU Debugger or GDB command line interface has similar commands. The following table illustrates just a few of the similarities.

Table 1. Small comparison between GNU Debugger (gdb) and Go Debugger (dlv) commands
Function GNU Debugger Go debugger (dlv)

Connect to a running program

gdb attach <PID>

dlv attach <PID>

Set a breakpoint

gdb break <function>

dlv break <package>.<function>

Continue after hitting a breakpoint or attaching to a program

gdb continue

dlv continue

Show a backtrace for the current location

gdb bt

dlv bt

More commands can be found in the Delve documentation.

1. Install debugger

Install the delve debugger by running:

$ go get github.com/derekparker/delve/cmd/dlv

This will create the file $GOPATH/bin/dlv so in order to run the dlv executable from anywhere, make sure you have $GOPATH/bin in your $PATH.

Here are instructions to install delve on different platforms.

2. Example debugging

In this example we’ll debug a running Auth server using delve and set a breakpoint on the function WorkitemController.Show.

Note
To see other ways to run dlv, see the usage page.

Let’s assume the binary ./bin/auth is running.

2.1. Attach to program

To attach the debugger to your running fabric8-auth server,run:

$ dlv attach $(pidof ./bin/auth)

The will bring you into the delve shell which looks like this:

Type 'help' for list of commands.
(dlv)

The ./bin/auth program is paused right now. Once we’ve set a breakpoint we will let it run again.

2.2. Set breakpoint

Now, set the breakpoint on the on the WorkitemController.Show function that is defined in workitem.go:

(dlv) break WorkitemController.Show

As mentioned before the fabric8-auth server is paused and we need to bring it back into a run state. To do this, we let the program continue:

(dlv) continue

2.3. Trigger breakpoint

Open another shell and fetch an existing workitem using curl:

$ curl http://localhost:8080/api/workitems/1

(Replace the 1 with an existing workitem ID if needed)

Now, your debugger shell show something like this:

> main.(*WorkitemController).Show() /tmp/go/src/github.com/fabric8-services/fabric8-auth/workitem.go:30 (hits goroutine(11):1 total:3) (PC: 0x405633)
(dlv)

The program is paused again for you to inspect it and the curl command has not returned yet.

2.4. Backtrace

To show a backtrace of how we got here in terms of stack frames, run:

(dlv) bt

The output might look similar to this but it can change over time and as development goes on:

0  0x0000000000405633 in main.(*WorkitemController).Show
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/workitem.go:30
1  0x0000000000520014 in github.com/fabric8-services/fabric8-auth/app.MountWorkitemController.func3
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/app/controllers.go:222
2  0x00000000005202fe in github.com/fabric8-services/fabric8-auth/app.handleWorkitemOrigin.func1
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/app/controllers.go:257
3  0x0000000000540868 in github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa.(*Controller).MuxHandler.func1.1
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/service.go:250
4  0x00000000005d6d3e in github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/middleware.Recover.func1.1
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/middleware/recover.go:37
5  0x00000000005d3b9c in github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/middleware.ErrorHandler.func1.1
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/middleware/error_handler.go:19
6  0x00000000005d5649 in github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/middleware.LogRequest.func1.1
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/middleware/log_request.go:65
7  0x00000000005d7229 in github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/middleware.RequestIDWithHeaderAndLengthLimit.func1.1
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/middleware/request_id.go:63
8  0x000000000054192c in github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa.(*Controller).MuxHandler.func1
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/service.go:283
9  0x000000000053faf9 in github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa.(*mux).Handle.func1
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/vendor/github.com/goadesign/goa/mux.go:57
10  0x000000000076c3c2 in github.com/fabric8-services/fabric8-auth/vendor/github.com/dimfeld/httptreemux.(*TreeMux).ServeHTTP
   at /tmp/go/src/github.com/fabric8-services/fabric8-auth/vendor/github.com/dimfeld/httptreemux/router.go:247

The first incrementing number on every second line stands for the number of the stackframe. Stackframe 0 is one where we set the breakpoint earlier.

2.5. Continue with normal processing

While there are many interesting ways to inspect your program using the delve debugger, we will instead let our program continue to run and thereby proceed with delivering the workitem to the curl command.

(dlv) continue

Check the shell in which you ran the curl command to see if you have go a result.

2.6. Exit debugging

To exit the debugger you can use the exit command or press Ctrl+d, just like you would exit any Bash for example:

(dlv) exit
Would you like to kill the process? [Y/n] y

You are being asked if you want to kill the process and the answer to this question very much depends on the way you’ve started delve. If you’ve attached to a running process like we did, the answer to this question is probably no. And if you’ve just started the program under test for debugging purposes then you might as well answer y to stop it.