Archive for the ‘Go’ category

golang ide环境配置

January 20th, 2018

最近golang和区块链火起来了,觉得自己有必要也跟一次风了。

golang的背景啊,优缺点啊就不讲了,网上大把资料,只要有C/C++的基础,这个golang程序猿就可以快速胜任。我就说一下配置过程和调试过程中的坑。golang的安装非常简单,只需要将其解压到制定目录,设置好GOROOT和GOPATH即可,GOROOT是golang的可执行文件,而GOPATH从我理解就是Go Project的所在目录,我们平时go get所下载的工程都会放到$GOPATH/src中。

由于刚开始接触,我手动设置了go编程环境,也使用go run 运行了hello world,但是一直无法调试go程序,在网上找了半天debugger,发现delver可以用来调试go程序,我习惯使用git+make install安装程序,安装完毕之后,我将其安装到go所在目录,方便直接命令行调用。

spider@ubuntu:/usr/lib/go-1.9.2$ ls
api  AUTHORS  bin  blog  CONTRIBUTING.md  CONTRIBUTORS  doc  favicon.ico  lib  LICENSE  misc  PATENTS  pkg  README.md  robots.txt  src  test  VERSION
spider@ubuntu:/usr/lib/go-1.9.2$ cd bin/
spider@ubuntu:/usr/lib/go-1.9.2/bin$ ls
dlv  go  godoc  gofmt

只要用过gdb的童靴,这个就非常简单了,比如break,continue,print 等,如下所示:

spider@ubuntu:/tmp$ dlv debug test.go
Type 'help' for list of commands.
(dlv) l
> _rt0_amd64_linux() /usr/lib/go-1.9.2/src/runtime/rt0_linux_amd64.s:8 (PC: 0x4571b0)
Warning: debugging optimized function
     3:	// license that can be found in the LICENSE file.
     4:	
     5:	#include "textflag.h"
     6:	
     7:	TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
=>   8:		LEAQ	8(SP), SI // argv
     9:		MOVQ	0(SP), DI // argc
    10:		MOVQ	$main(SB), AX
    11:		JMP	AX
    12:	
    13:	// When building with -buildmode=c-shared, this symbol is called when the shared
(dlv) b main.main
Breakpoint 1 set at 0x4a08d8 for main.main() ./test.go:12
(dlv) c
> main.main() ./test.go:12 (hits goroutine(1):1 total:1) (PC: 0x4a08d8)
Warning: debugging optimized function
     7:	   return n
     8:	  }
     9:	  return fibonacci(n-2) + fibonacci(n-1)
    10:	}
    11:	
=>  12:	func main() {
    13:	    var i int
    14:	    for i = 0; i < 10; i++ { 15: fmt.Printf("%d\t", fibonacci(i)) 16: } 17: } (dlv) n > main.main() ./test.go:13 (PC: 0x4a08ef)
Warning: debugging optimized function
     8:	  }
     9:	  return fibonacci(n-2) + fibonacci(n-1)
    10:	}
    11:	
    12:	func main() {
=>  13:	    var i int
    14:	    for i = 0; i < 10; i++ { 15: fmt.Printf("%d\t", fibonacci(i)) 16: } 17: } (dlv) > main.main() ./test.go:14 (PC: 0x4a08f8)
Warning: debugging optimized function
     9:	  return fibonacci(n-2) + fibonacci(n-1)
    10:	}
    11:	
    12:	func main() {
    13:	    var i int
=>  14:	    for i = 0; i < 10; i++ { 15: fmt.Printf("%d\t", fibonacci(i)) 16: } 17: } (dlv) > main.main() ./test.go:15 (PC: 0x4a0913)
Warning: debugging optimized function
    10:	}
    11:	
    12:	func main() {
    13:	    var i int
    14:	    for i = 0; i < 10; i++ { =>  15:	       fmt.Printf("%d\t", fibonacci(i))
    16:	    }
    17:	}
(dlv) p i
0
(dlv) n
0	> main.main() ./test.go:14 (PC: 0x4a0a02)
Warning: debugging optimized function
     9:	  return fibonacci(n-2) + fibonacci(n-1)
    10:	}
    11:	
    12:	func main() {
    13:	    var i int
=>  14:	    for i = 0; i < 10; i++ { 15: fmt.Printf("%d\t", fibonacci(i)) 16: } 17: } (dlv) > main.main() ./test.go:15 (PC: 0x4a0913)
Warning: debugging optimized function
    10:	}
    11:	
    12:	func main() {
    13:	    var i int
    14:	    for i = 0; i < 10; i++ { =>  15:	       fmt.Printf("%d\t", fibonacci(i))
    16:	    }
    17:	}
(dlv) p i
1

另外我们也可以使用dlv attach pid的方式进行调试,当然我们必须开启/proc/sys/kernel/yama/ptrace_scope to 0。然而我gdb、dlv再怎么强大,还是没有IDE方便,尤其是断点调试,经过调研VSCode、Gogland、Atom满足我们需求,由于之前我一直是用JetBrain系产品进行开发,毫无疑问,我是用Gogland作为IDE。我着重说一下他的调试,当debug某个程序时候,Gogland会打印信息:

GOROOT=/usr/lib/go-1.9.2 #gosetup
GOPATH=/home/spider/go #gosetup
/usr/lib/go-1.9.2/bin/go build -o /tmp/___go_build_main_go -gcflags "-N -l" -a /home/spider/go/src/awesomeProject/main.go #gosetup
/opt/GoLand/plugins/intellij-go-plugin/lib/dlv/linux/dlv --listen=localhost:41151 --headless=true --api-version=2 --backend=default exec /tmp/___go_build_main_go -- #gosetup

可以看到第一行、第二行是打印GOROOT和GOPATH,第三行是打印进行编译,添加-gcflags “-N -l”,是为了去掉编译优化,方便调试,这行执行完毕会把程序放到/tmp/___go_build_main_go中,第四行就是使用gogland中的dlv插件的debug server,后端就是我们编译的/tmp/___go_build_main_go程序。

 

参考

https://golang.org/doc/editors.html