文章归档

go语言TCPConn.Close()方法处理不当引发的bug

今天服务器引发了一个很罕见的bug。原因是因为TCPConn在Close的时候,把fd给清空掉了,如下:

// Close closes the TCP connection.
func (c *TCPConn) Close() error {
	if !c.ok() {
		return syscall.EINVAL
	}
	err := c.fd.Close()
	c.fd = nil
	return err
}

而TCPConn是经常在多个goroutine里同时使用的。

// Read implements the Conn Read method.
func (c *TCPConn) Read(b []byte) (n int, err error) {
	if !c.ok() {
		return 0, syscall.EINVAL
	}
	return c.fd.Read(b)
}

这样就很有可能当某个goroutine,判断!c.ok(),为真,然后尝试读取数据时。注意,这个过程,中间,if语句之后和Read()数据之前,很可能TCPConn已经被关闭,fd被置为nil了,引发panic

go1版本有这个问题。新版已经fix了。不过我还觉得蛮奇怪的,想不清楚为什么作者要这么写。。。

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>