大部分情况
问题:
在使用go语法的时候,由于并发情况,只能调试一个goroutine,但存在随机性,难指定
找到你所需的线程直接切换即可跳转。没有找到同时调试多个的办法,理论上是不行的,不然就不叫并发了。
特殊情况:此线程监控某事件,执行一半
首先断点打到用go修饰的函数,在go修饰的函数里面打个断点
执行debug的时候,在到了go修饰函数的时候使用resume program直接进入修饰函数里面(step into 进不去,run to cursor也可以,鼠标放在所需位置即可)
此时,线程会切换到你的go函数线程
多次尝试都能进入此断点
测试代码
go黑皮书《The Go Programming Language》回声案例
reverb.go模拟服务端,即山谷
netcat.go模拟客户端,即人
如果要测试并发,先跑起来reverb.go,然后netcat执行go build netcat.go打包二进制文件,然后.netcat执行,执行两个以上测试
使用
reverb.go
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
// See page 224.
// Reverb2 is a TCP server that simulates an echo.
package main
import (
"bufio"
"fmt"
"log"
"net"
"strings"
"time"
)
func echo(c net.Conn, shout string, delay time.Duration) {
fmt.Fprintln(c, "\t", strings.ToUpper(shout))
time.Sleep(delay)
fmt.Fprintln(c, "\t", shout)
time.Sleep(delay)
fmt.Fprintln(c, "\t", strings.ToLower(shout))
}
// !+
func handleConn(c net.Conn) {
input := bufio.NewScanner(c)
for input.Scan() {
go echo(c, input.Text(), 3*time.Second)
}
// NOTE: ignoring potential errors from input.Err()
c.Close()
}
//!-
func main() {
l, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := l.Accept()
if err != nil {
log.Print(err) // e.g., connection aborted
continue
}
go handleConn(conn)
}
}
netcat.go
package main
import (
"io"
"log"
"net"
"os"
)
func main() {
conn, err := net.Dial("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
done := make(chan struct{})
go readFromConn(conn, done)
mustCopy(conn, os.Stdin)
go mygoroutine()
conn.Close()
<-done // wait for background goroutine to finish
log.Println("end")
}
func mustCopy(dst io.Writer, src io.Reader) {
if _, err := io.Copy(dst, src); err != nil {
log.Fatal(err)
}
}
func mygoroutine() {
log.Println("okkk")
}
func readFromConn(conn net.Conn, done chan struct{}) {
log.Println("done1")
io.Copy(os.Stdout, conn) // NOTE: ignoring errors
log.Println("done")
done <- struct{}{} // signal the main goroutine
}