代码之家  ›  专栏  ›  技术社区  ›  Bart Silverstrim

HTTP。服务器关闭导致运行时错误

  •  -2
  • Bart Silverstrim  · 技术社区  · 8 年前

    我在darwin/amd64上的Go 1.9.2中编写了一个goroutine,它会导致运行时错误:无效的内存地址或零指针解引用。我认为这是因为某种与常规退出顺序相关的比赛条件,但我不确定。

    函数如下:

    // WebServer defines the handler endpoints and launches the web server listener
    func WebServer(wg *sync.WaitGroup) {
    
        // Make sure the exit is noted
        defer wg.Done()
    
        // Endpoint, handler function
        http.HandleFunc("/version", WebShowVersion)
    
        // Go forth and serve
        // Define the server struct
        srv := &http.Server{Addr: ":8080"}
    
        // Now go serve
        chnToLogger <- "Launching web server on port 8080"
        go func() {
            err := srv.ListenAndServe()
            if err != nil &&
                err.Error() != "http: Server closed" {
    
                // There...was an error
                chnToLoggerError <- "Error launching web server: " + err.Error()
            }
        }()
    
        // Listen for a shutdown
        for {
            select {
            case <-chnQuitNow:
    
                // Shut down the process
                chnToLogger <- "Shutting down web server process"
                if err := srv.Shutdown(nil); err != nil {
    
                    // There was a problem shutting down gracefully
                    chnToLoggerError <- "Error shutting down web server: " + err.Error()
                    return
                }
    
                // Done
                chnToLogger <- "Web server has shut down now"
                return
    
            default:
                continue
            }
        }
    
        // Done
        return
    }
    

    恐慌状态:

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x11f7e61]
    
    goroutine 10 [running]:
    net/http.(*Server).Shutdown(0xc420158000, 0x0, 0x0, 0x0, 0x0)
        /usr/local/go/src/net/http/server.go:2506 +0x1b1
    main.WebServer(0xc4200164a0)
        /Users/me/go/src/testproj/webhandling.go:45 +0x146
    created by main.main
        /Users/me/go/src/testproj/main.go:94 +0x3d6
    

    webhandling中的第45行。go是:

    if err := srv.Shutdown(nil); err != nil {
    

    虽然它在被触发时并不一致,但似乎只有在我启动程序并使用web客户端多次拉取localhost:8080/version时才会发生这种情况,这让我怀疑srv是否正确。Shutdown(nil)正在尝试关闭具有引用但已退出的连接?

    1) 在从goroutine返回之前,是否可以让服务器安全完整地关闭web服务器进程?

    2) 是什么导致触发不一致的运行时错误?

    1 回复  |  直到 8 年前
        1
  •  4
  •   Jonathan Hall    8 年前

    永远不要使用 nil context.Background() context.TODO() .