diff --git a/11.2.md b/11.2.md index 3cf196b4..fcff22e4 100644 --- a/11.2.md +++ b/11.2.md @@ -127,10 +127,120 @@ GDB的一些常用命令如下所示 通过gdb命令启动调试: - gdb gdbfile - - + gdb gdbfile + +启动之后我们首先看看是不是可以运行起来,输入`run`命令之后程序就开始运行,我们可以看到程序输出如下,和我们在命令行直接执行程序输出是一样的: + + (gdb) run + Starting program: /home/xiemengjun/gdbfile + Starting main + count: 0 + count: 1 + count: 2 + count: 3 + count: 4 + count: 5 + count: 6 + count: 7 + count: 8 + count: 9 + [LWP 2771 exited] + [Inferior 1 (process 2771) exited normally] +好了,现在我们知道怎么让程序跑起来了,接下来我们开始设置断点: + + (gdb) b 23 + Breakpoint 1 at 0x400d8d: file /home/xiemengjun/gdbfile.go, line 23. + (gdb) run + Starting program: /home/xiemengjun/gdbfile + Starting main + [New LWP 3284] + [Switching to LWP 3284] + + Breakpoint 1, main.main () at /home/xiemengjun/gdbfile.go:23 + 23 fmt.Println("count:", count) +上面我们可以看到我们在第23行设置了断点,然后运行,我们可以看到在我们设置断点的地方程序停住了,我们可以查看相应的源码,我们可以看到显示的原始是当前停止行之前的五行开始显示: + + (gdb) list + 18 fmt.Println(msg) + 19 bus := make(chan int) + 20 msg = "starting a gofunc" + 21 go counting(bus) + 22 for count := range bus { + 23 fmt.Println("count:", count) + 24 } + 25 } + +现在我们可以查看所有的变量信息,然后打印相应的变量,查看相应变量的类型: + + (gdb) info locals + count = 0 + bus = 0xf840001a50 + (gdb) p count + $1 = 0 + (gdb) p bus + $2 = (chan int) 0xf840001a50 + (gdb) whatis bus + type = chan int + +接下来我们如何让程序继续往下执行呢?请看下面的命令 + + (gdb) c + Continuing. + count: 0 + [New LWP 3303] + [Switching to LWP 3303] + + Breakpoint 1, main.main () at /home/xiemengjun/gdbfile.go:23 + 23 fmt.Println("count:", count) + (gdb) c + Continuing. + count: 1 + [Switching to LWP 3302] + + Breakpoint 1, main.main () at /home/xiemengjun/gdbfile.go:23 + 23 fmt.Println("count:", count) + +我们可以看到每次输入c之后都会执行一次,执行到下一次for循环,打印出来相应的信息,接下来我们来改变变量的信息,然后继续执行到下一步,我们可以看到我们可以修改相应的变量值: + + (gdb) info locals + count = 2 + bus = 0xf840001a50 + (gdb) set variable count=9 + (gdb) info locals + count = 9 + bus = 0xf840001a50 + (gdb) c + Continuing. + count: 9 + [Switching to LWP 3302] + + Breakpoint 1, main.main () at /home/xiemengjun/gdbfile.go:23 + 23 fmt.Println("count:", count) + +最后我们来看一下,这整个的过程中起了多少个goroutine,每个goroutine都是在做什么: + + (gdb) info goroutines + * 1 running runtime.gosched + * 2 syscall runtime.entersyscall + 3 waiting runtime.gosched + 4 runnable runtime.gosched + (gdb) goroutine 1 bt + #0 0x000000000040e33b in runtime.gosched () at /home/xiemengjun/go/src/pkg/runtime/proc.c:927 + #1 0x0000000000403091 in runtime.chanrecv (c=void, ep=void, selected=void, received=void) + at /home/xiemengjun/go/src/pkg/runtime/chan.c:327 + #2 0x000000000040316f in runtime.chanrecv2 (t=void, c=void) + at /home/xiemengjun/go/src/pkg/runtime/chan.c:420 + #3 0x0000000000400d6f in main.main () at /home/xiemengjun/gdbfile.go:22 + #4 0x000000000040d0c7 in runtime.main () at /home/xiemengjun/go/src/pkg/runtime/proc.c:244 + #5 0x000000000040d16a in schedunlock () at /home/xiemengjun/go/src/pkg/runtime/proc.c:267 + #6 0x0000000000000000 in ?? () + +通过gotoutine的命令我们清楚的知道go内部是怎么执行的,每个函数的调用顺序都非常清楚的显示出来了。 + +## 小结 +本小节我们介绍了GDB调试Go程序的一些基本命令,包括`run`、`print`、`info`、`set variable`、`coutinue`、`list`、`break` 等一些经常用到的调试命令,通过上面的例子演示,我相信读者已经对于通过GDB调试Go程序有了基本的理解,如果你想获取更多的调试技巧请参考官方网站的GDB调试手册,还有GDB官方网站的手册。 + ## links * [目录]() * 上一节: [错误处理](<11.1.md>) diff --git a/11.3.md b/11.3.md index 92557aeb..5c7c56fb 100644 --- a/11.3.md +++ b/11.3.md @@ -1,5 +1,13 @@ # 11.3 Go怎么写测试用例 +## 如何编写测试用例 + + func TestXXX(t *testing.T) { ... } + +## 如何编写压力测试 + + func BenchmarkXXX(b *testing.B) { ... } + ## links * [目录]() * 上一节: [使用GDB调试](<11.2.md>)