Debugging Go using LiteIDE on Ubuntu 14.04

So this weekend I decided to give the Go programming language (golang) a spin. Go is best described like this:

Go, also called golang, is a programming language initially developed at Google in 2007 by Robert Griesemer, Rob Pike, and Ken Thompson. It is a statically-typed language with syntax loosely derived from that of C, adding garbage collection, type safety, some dynamic-typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library. – Wikipedia

When you are stuck, don’t search the web for “Go”; it will not give relevant results. Use the word “golang” instead.

Installing golang on Ubuntu 14.04

ubuntu-go

I am using Ubuntu 14.04 (actually Xubuntu), but these instructions should also work on any other recent Debian-based Linux (like Mint 17). I tested using a clean install, so you should not run into unexpected dependencies. First we install the two prerequisites (Git and Mercurial):

sudo apt-get install mercurial git

Then we download the latest version of the Go language in which debugging is working: version 1.2.2. Debugging (gdb) is broken in golang 1.3 and hopefully gets fixed in 1.4. EDIT: Thank you ondrej for finding this issue. The following commands will download the software package and unpack it to the “go” directory in your home folder (in my case “/home/maurits/go”):

cd ~
wget http://golang.org/dl/go1.2.2.linux-amd64.tar.gz
tar -xf go1.2.2.linux-amd64.tar.gz
rm go1.2.2.linux-amd64.tar.gz

Go supports installing third party packages using the “go get” command. These are not installed in the same directory as the initial Go installation. This simplifies package management, because every project can have it’s own workspace if needed. So, we create a (first) workspace directory that will hold third party packages. We will name it “workspace-go” since it is still generic and it will be located in my home folder.

mkdir ~/workspace-go

We will use the directory later, when we “go get” some third party packages.

Setting up the command-line environment

To avoid adding the GO settings to my environment, I have made a file that holds my Go environment variables. You need to set three variables: GOROOT is the installation directory of GO, GOPATH is the workspace directory for “go get” and finally it can be convenient to add the “bin” directories from GOROOT and GOPATH to the (search) PATH. Using the following commands I make a “go.env” file that can be used to set the environment variables.

echo "export GOROOT=\$HOME/go" > ~/go.env
echo "export GOPATH=\$HOME/workspace-go" >> ~/go.env
echo "export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin" >> ~/go.env

To actually load the above file you have to type the following command in the Terminal:

. ~/go.env

Note that the environment variables are only set in the active terminal. When you open another Terminal you will have to run the “go.env” file before you can use the “go” command(s). When your Go environment is correctly set you can (for example) get some nice third party tools using:

go get code.google.com/p/go.tools/cmd/...
go get github.com/golang/lint/golint

Run a for loop example from the command-line

There is a very good website named “Go by Example“. It holds a large set of small Go files that clearly show how the various built-in functions of the Go language work. I chose the “for loop” example to show how compiling and running a golang file works. I make a directory “hello” (from “hello world”) to store my first Go programs in. Then I download the “for.go” example:

mkdir ~/hello
cd ~/hello
wget https://raw.githubusercontent.com/mmcgrana/gobyexample/master/examples/for/for.go

To run the code you need to open a Terminal and load the Go environment from the “go.env” file. Now the “go” command is available and you can execute “go run” as shown below:

. ~/go.env
cd ~/hello
go run for.go

You can also first “build” an executable file. The advantage is that you can distribute this file. It can be executed on any other Linux machine with the same architecture. Go also support cross-compiling for other architectures. It means that Go does not require anything (a VM or run-time) to be installed on the target machine. The downside to this is that the executable size is large. This simple “for.go” script has a compiled size of 2,2 MB (megabyte). This can be reduced to 1,2 MB by removing debug symbols using the “ldflags” like below:

. ~/go.env
cd ~/hello
go build -ldflags "-s" for.go
./for

Debug from the command-line

Golang has decent GDB support. This may help you a lot when you run bugs that you cannot effectively squash using “printf debugging”. Below I give an example of a run where I break on line 19 of the “for.go” script. Note that you expect the variables “i” and “j” to be “4” and “7”. They will not have these values, unless you disable compiler optimizations by adding the “gcflags” to the build command as shown below:

. ~/go.env
cd ~/hello
go build -gcflags "-N -l" for.go
gdb for
b for.go:19
r
l
i loc
q
y

LiteIDE: a Go IDE with debugging capabilities

liteide2

In the above section we have seen how to run, build and debug from the command line. Fortunately, there is also a nice IDE available that simplifies these things. It is called LiteIDE and it supports just one language: Go. The following commands download it from sourceforge and install it in the “liteide” directory in your home folder (in my case “/home/maurits/liteide”):

wget --content-disposition http://sourceforge.net/projects/liteide/files/X22/liteidex22.linux-64.tar.bz2/download
tar -xf liteidex22.linux-64.tar.bz2
rm liteidex22.linux-64.tar.bz2

In the menu you can create a launcher that executes the following:

~/liteide/bin/liteide

The following file can be used as an icon:

~/liteide/share/liteide/welcome/images/liteide400.png

When you have started the application there is one thing you must do:

View -> Manage GOPATH... -> Add Directory... -> Select: ~/workspace-go

This will make sure that any third party package that you install can be loaded.

Step-by-step debugger for Go

To make sure the (GDB based) step-by-step debugger works you need to do the following:

Build -> Build Configuration... -> Custom -> BUILDARGS -> Enter: -gcflags "-N -l"

Verify everything is working correctly by executing the following debug run:

File -> Open Folder -> Click: hello -> Choose
Double click "for.go" in the "Folders" pane
Build -> Build (Ctrl-B)
Put cursor on line 19
F9 (toggle breakpoint)
F5 (start debugging)
F5 (until green arrow is on line 19)
Debug pane should show "Variables" tab with "i=4" and "j=7"

Happy coding!

Share

12 thoughts on “Debugging Go using LiteIDE on Ubuntu 14.04”

  1. apt-get install golang-src golang mercurial git

    echo “export GOROOT=/usr/lib/go” > /etc/profile.d/golang.sh
    echo “export GOBIN=/usr/bin/go” >> /etc/profile.d/golang.sh
    echo “export GOPATH=/usr/share/go/” >> /etc/profile.d/golang.sh

    Logout & log back in

    echo $GOPATH

    go get github.com/golang/lint/golint

  2. @Arnoud: Thank you for those instructions. I tried them before writing the post, but they did not work. Ubuntu 14.04 is installing golang version 2:1.2.1-2ubuntu1 on which debugging is broken because the gdb Python script is in Python 2, while gdb is running Python 3. The following error occurs:

    File "/usr/share/go/src/pkg/runtime/runtime-gdb.py", line 358
    print s, ptr['goid'], "%8s" % sts[long((ptr['status']))], blk.function

    see: https://groups.google.com/forum/#!topic/golang-nuts/VcmSvq2mSm0

  3. Nice article!

    But I dont know what am I doing wrong, but when I hit breakpoint on line #19 and then inspect local variables i and j, I see odd numbers.

    j = 833357873504
    i = 0

    I think gdb debugger is not working well.

    Please, could you provide me version of your gdb installed?

    I am running on Ubuntu 14.04.

    Thanks a lot.

  4. @ondrej: Are you sure you set the BUILDARGS?

    My gdb version: GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7

  5. Yes, I have set BUILDARGS.

    I have the same version of gdb, but there is some problem somewhere.

    I’ve also tried install go and liteide in virtual machine with another ubuntu and windows and got same strange results when debugging.

    I will try it on another PC.

    Thx.

  6. @ondrej: Are you sure about the BUILDARGS? You must enter the following:
    -gcflags "-N -l"

  7. Yes, I have entered it 🙂

    For me, it’s not working neither debugging from command line – gives the same results.

    go build -gcflags “-N -l” for.go
    gdb for

    It’s strange.

  8. It looks like there is in golang version 1.3 some bug. Someone has already reported it here: https://code.google.com/p/go/issues/detail?id=8256

    I solved it by installing older version of golang (1.2) and now debugger is working properly.

    I have one question about watching string variables in LiteIDE. I see there struct string with str and len property, but value of string is not visible.

    Is there some way to inspect string variables from LiteIDE?

    From command line I can see value of string variable normally.

    Thanks for your reply.

  9. @ondrej: You are right, I tested on 1.2.2 and updated the article when 1.3 came out. But in 1.3 debugging is broken and it is not even sure it gets fixed in 1.4.

    Thank you very much for pointing this out and sorry for wasting your time on this. I updated the article to prevent others from running into this.

    Strings can be seen by expanding the variable and looking into the value of the str property. It is first displayed in hex and after that as a string.

    Kind regards, Maurits

Leave a Reply

Your email address will not be published. Required fields are marked *