douao3636 2015-02-23 09:13
浏览 127
已采纳

atomic.AddInt64导致无效的内存地址或nil指针取消引用

Calling atomic.AddInt64 on field of a struct panics invalid memory address or nil pointer dereference, but not when we re-arrange fields order; why?

Using this type:

type CountHandler struct {
    c     *RequestContext
    count int64
}

And calling atomic.AddInt64(&countHandler.count, 1) (field c is nil at this point) panics. But not when we rewrite it as:

type CountHandler struct {
    count int64
    c     *RequestContext
}

Error goes away.

I guess it should be so, because Go keeps data in memory in a sequential manner and reaching a nil value breaks this sequence (of bytes); yet I wonder why is that so again because a pointer should have a fixed size nil or other value.

This is Go x86 1.4.2 on Windows & complete error message is:

2015/02/23 12:56:44 http: panic serving [::1]:51886: runtime error: invalid memory address or nil pointer dereference
goroutine 5 [running]:
net/http.func·011()
        c:/go/src/net/http/server.go:1130 +0xa8
sync/atomic.AddUint64(0x731144, 0x1, 0x0, 0x0, 0x263168)
        c:/go/src/sync/atomic/asm_386.s:118 +0xc
main.(*CountHandler).ServeHTTP(0x731140, 0x263180, 0x122f6380, 0x122f62a0)
        C:/Workshop/Devox/Workshop-Go/src/geoho/web/app/app.go:62 +0x42
github.com/julienschmidt/httprouter.func·001(0x263180, 0x122f6380, 0x122f62a0, 0x0, 0x0, 0x0)
        C:/Workshop/Devox/Workshop-Go/src/github.com/julienschmidt/httprouter/router.go:232 +0x4c
github.com/julienschmidt/httprouter.(*Router).ServeHTTP(0x122d5d20, 0x263180, 0x122f6380, 0x122f62a0)
        C:/Workshop/Devox/Workshop-Go/src/github.com/julienschmidt/httprouter/router.go:298 +0x141
net/http.serverHandler.ServeHTTP(0x122d2280, 0x263180, 0x122f6380, 0x122f62a0)
        c:/go/src/net/http/server.go:1703 +0x145
net/http.(*conn).serve(0x122e01e0)
        c:/go/src/net/http/server.go:1204 +0x9d8
created by net/http.(*Server).Serve
        c:/go/src/net/http/server.go:1751 +0x2ce

Whole source code is (this code is wrong, I was just about studying alice):

package main

import (
    "fmt"
    "github.com/julienschmidt/httprouter"
    "github.com/justinas/alice"
    "net/http"

    "os"
    "sync/atomic"
)

// play with alice
func main() {
    c1 := alice.New(Counter, Texter).Then(nil)

    router := httprouter.New()
    router.Handler("GET", "/", c1)
    router.GET("/kill", kill)

    http.ListenAndServe(":27007", router)
}

func kill(rw http.ResponseWriter, rq *http.Request, pl httprouter.Params) {
    os.Exit(0)
}

var ch CountHandler

// constructors:

func Counter(h http.Handler) http.Handler {
    return &ch
}

func Texter(h http.Handler) http.Handler {
    var t TextHandler
    switch x := h.(type) {
    case *CountHandler:
        t.c = x.c
        t.text = fmt.Sprintf("called so far %d", atomic.LoadInt64(&x.count))
    }
    return &t
}

// handlers:

type RequestContext struct {
    val int
}

type CountHandler struct {
    c     *RequestContext
    count int64
}

func (c *CountHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
    atomic.AddInt64(&c.count, 1)
}

type TextHandler struct {
    c    *RequestContext
    text string
}

func (t *TextHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
    rw.Write([]byte(t.text))
}
  • 写回答

2条回答 默认 最新

  • dongyun7571 2015-02-23 09:27
    关注

    The fault is caused in the first case by the atomically updated field not being properly aligned.

    On both ARM and x86-32, it is the caller's responsibility to arrange for 64-bit alignment of 64-bit words accessed atomically. The first word in a global variable or in an allocated struct or slice can be relied upon to be 64-bit aligned.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)