如何在互斥锁保护的结构中找到数据竞争?

I have a struct containing a map that is accessed from different goroutines protected by mutex:

type Readings struct {
    sync.Mutex
    Timestamp time.Time
    values    map[meters.Measurement]float64
}

Still, it has a data race between Add (write) and MarshalJSON (read). The latter performs structure conversion:

func (r *Readings) Add(q QuerySnip) {
    r.Lock()
    defer r.Unlock()

    r.Timestamp = q.Timestamp
    if r.values == nil {
        r.values = make(map[meters.Measurement]float64)
    }

    r.values[q.Measurement] = q.Value
}

func (r *Readings) MarshalJSON() ([]byte, error) {
    r.Lock()
    defer r.Unlock()

    res := map[string]interface{}{
        "Timestamp": r.Timestamp,
        "Unix":      r.Timestamp.Unix(),
    }

    if r.values == nil {
        return json.Marshal(res)
    }

    for m, v := range r.values {
        res[m.String()] = v
    }

    return json.Marshal(res)
}

This is the race:

WARNING: DATA RACE
Write at 0x00c000294900 by goroutine 11:
runtime.mapassign_fast64()
    /usr/local/opt/go/libexec/src/runtime/map_fast64.go:92 +0x0
github.com/volkszaehler/mbmd/server.(*Readings).Add()
    ...

Previous read at 0x00c000294900 by goroutine 25:
runtime.mapiterinit()
    /usr/local/opt/go/libexec/src/runtime/map.go:804 +0x0
github.com/volkszaehler/mbmd/server.(*Readings).MarshalJSON()
    /Users/andig/htdocs/mbmd/server/datagram.go:126 +0x304
github.com/volkszaehler/mbmd/server.(*data).MarshalJSON()
    ...

I don't understand what might by racey here and I'm not able to replicate the race behaviour moving the code into a standalone test case.

It there any advise for further diagnosis?

Both comments are right. I had copied a readings, was calling Add on copy and MarshalJson on original. The values was shared, itself being not deep copied.