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().

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

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度