dongzhijing8202 2017-11-20 14:33
浏览 144
已采纳

HTTP.Server关闭导致运行时错误

I have a goroutine written in Go 1.9.2 on darwin/amd64 that causes a runtime error: invalid memory address or nil pointer dereference. I think it's because of a race condition of some kind related to the order of routines exiting, but I'm not sure.

There are several things the main application is doing, so I launched the webserver as a goroutine which then listens for an exit signal from the parent process and tries to shut everything down cleanly before returning.

Here's the function:

// 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
}

The panic states:

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

The line 45 in webhandling.go is:

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

While it's not consistent in being triggered, it does seem to only happen if I launch the program and use a web client to pull localhost:8080/version a few times, leading me to wonder if srv.Shutdown(nil) is trying to close a connection that has a reference but has exited already?

1) Is it possible to get the server to shut down web server processes safely and completely before returning from the goroutine?

2) What is causing the inconsistent runtime error to be triggered?

  • 写回答

1条回答 默认 最新

  • dougu2036 2017-11-20 14:52
    关注

    Never use a nil context. Use either context.Background() or context.TODO().

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog