首页 > runtime error: invalid memory address or nil pointer dereference

runtime error: invalid memory address or nil pointer dereference

agent.go文件


package db

import (
    "bytes"
    "fmt"
    "github.com/open-falcon/common/model"
    "github.com/open-falcon/hbs/g"
    "log"
    "net/http"
)

func UpdateAgent(agentInfo *model.AgentUpdateInfo) {
    sql := ""
    if g.Config().Hosts == "" {
        sql = fmt.Sprintf(
            "insert into host(hostname, ip, agent_version, plugin_version) values ('%s', '%s', '%s', '%s') on duplicate key update ip='%s', agent_version='%s', plugin_version='%s'",
            agentInfo.ReportRequest.Hostname,
            agentInfo.ReportRequest.IP,
            agentInfo.ReportRequest.AgentVersion,
            agentInfo.ReportRequest.PluginVersion,
            agentInfo.ReportRequest.IP,
            agentInfo.ReportRequest.AgentVersion,
            agentInfo.ReportRequest.PluginVersion,
        )
    } else {
        // sync, just update
        sql = fmt.Sprintf(
            "update host set ip='%s', agent_version='%s', plugin_version='%s' where hostname='%s'",
            agentInfo.ReportRequest.IP,
            agentInfo.ReportRequest.AgentVersion,
            agentInfo.ReportRequest.PluginVersion,
            agentInfo.ReportRequest.Hostname,
        )
    }

    defer func() {
        if err := recover(); err != nil {
            log.Panicln("出错了:", err)
        }
    }()
    _, err := DB.Exec(sql)
    if err != nil {
        log.Println("exec", sql, "fail", err)
    } else {
        url := g.Config().GroupHostAddUrl
        fmt.Println(url)
        var hosts, group_name string
        hosts = agentInfo.ReportRequest.Hostname
        group_name = g.Config().DefaultHostGroup
        var jsonStr = []byte(`{"hosts":"` + hosts + `","group_name":"` + group_name + `"}`)
        req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
        req.Header.Set("Content-Type", "application/json")
        client := &http.Client{}
        resp, err := client.Do(req)
        defer resp.Body.Close()
        if err != nil {
            log.Println("Post To Portal API Fail:", sql, err)
        }
    }
}

程序运行一段时间后报错:

panic: 出错了: runtime error: invalid memory address or nil pointer dereference

[signal 0xb code=0x1 addr=0x0 pc=0x462123]

goroutine 13174364 [running]:
log.Panicln(0xc208a11690, 0x2, 0x2)
        /usr/local/go/src/log/log.go:321 +0xb9
github.com/open-falcon/hbs/db.func·001()
        /home/work/workspace/src/github.com/open-falcon/hbs/db/agent.go:38 +0x12f
github.com/open-falcon/hbs/db.UpdateAgent(0xc2084aff50)
        /home/work/workspace/src/github.com/open-falcon/hbs/db/agent.go:55 +0xc73
github.com/open-falcon/hbs/cache.(*SafeAgents).Put(0xc20806a0a0, 0xc2085af5c0)
        /home/work/workspace/src/github.com/open-falcon/hbs/cache/agents.go:31 +0xa4
github.com/open-falcon/hbs/rpc.(*Agent).ReportStatus(0xc20813fa60, 0xc2085af5c0, 0xc209e3ede8, 0x0, 0x0)
        /home/work/workspace/src/github.com/open-falcon/hbs/rpc/agent.go:31 +0x73
reflect.Value.call(0x755320, 0x7b4500, 0x13, 0x7f8b50, 0x4, 0xc208a11f28, 0x3, 0x3, 0x0, 0x0, ...)
        /usr/local/go/src/reflect/value.go:419 +0x10e5
reflect.Value.Call(0x755320, 0x7b4500, 0x13, 0xc208a11f28, 0x3, 0x3, 0x0, 0x0, 0x0)
        /usr/local/go/src/reflect/value.go:296 +0xbc
net/rpc.(*service).call(0xc2080a0280, 0xc2080a0240, 0xc208109620, 0xc2080ae200, 0xc208917100, 0x769160, 0xc2085af5c0, 0x16, 0x769520, 0xc209e3ede8, ...)
        /usr/local/go/src/net/rpc/server.go:382 +0x1f7
created by net/rpc.(*Server).ServeCodec
        /usr/local/go/src/net/rpc/server.go:476 +0x44a

问题出在

        resp, err := client.Do(req)
        defer resp.Body.Close()

很简单,client.Do失败了,err不为nil,此时resp.Body为nil,但是又要强制调用它的close函数,于是报错。

只讨论代码的话,应该这样改:

        resp, err := client.Do(req)
        if err != nil {
            resp.Body.Close()
        }

但是,根本原因是,你的服务端出问题了。

去看一下是没启动还是怎么了……

另外,有可能不是“运行一段时间后报错”,
有可能是刚开始就会出错,只不过还没等到client.Do(req)的超时,于是刚开始“看上去是正常的”。

【热门文章】
【热门文章】