I am testing on Go 1.21.0, Linux, amd64
On Friday, August 18, 2023 at 1:57:38 PM UTC+2 Tibor Halter wrote:
> Thanks Ian!
>
> I have managed to strip it down to its essence, see code below.
>
> *Summary of what I'm doing*
> - reserve memory with make([]byte)
> - get pointer to underlying array
> - cast it to type Num
> - write pointer #2 into it
> - force GC()
> - GC does not follow pointer #2, memory is freed
>
> *Notes*
> - If I run it with `go test` it passes.
> - If I run it with `GODEBUG=clobberfree=1 go test` it fails with:
> --- FAIL: Test (0.00s)
> debug_test.go:26: v[DEADBEEFDEADBEEF]
> - If I inline the variable `numMemSize` it passes.
>
>
> As per the rules in unsafe.Pointer docs I would understand the conversions
> I'm doing are valid.
> What do I miss?
>
> Thanks a lot,
> Tibor
>
>
> --
>
>
> package debug
>
> import (
> "testing"
> "runtime"
> "unsafe"
> )
>
> type Num struct {
> numData *uint64
> }
>
> func Test(t *testing.T) {
> n := uint64(123456789)
> numMemSize := 8
> b := make([]byte, numMemSize, numMemSize)
> sliceDataPtr := unsafe.Pointer(unsafe.SliceData(b))
> (*Num)(sliceDataPtr).numData = &n
>
>
> runtime.GC()
>
>
> act := (*Num)(sliceDataPtr).numData
> if *act != 123456789 {
> t.Fatalf("v[%X]", *act)
> }
> }
>
>
> On Friday, August 18, 2023 at 2:59:46 AM UTC+2 Ian Lance Taylor wrote:
>
>> On Thu, Aug 17, 2023 at 5:41 PM Tibor Halter <[email protected]> wrote:
>> >
>> > I get this crash when using the GODEBUG option gccheckmark=1:
>> >
>> > runtime: marking free object 0xc0016c5668 found at *(0xc0046ca8e0+0x8)
>> > base=0xc0046ca8e0 s.base()=0xc0046ca000 s.limit=0xc0046cc000
>> s.spanclass=8 s.elemsize=32 s.state=mSpanInUse
>> > *(base+0) = 0x15e11f0
>> > *(base+8) = 0xc0016c5668 <==
>> > *(base+16) = 0x28
>> > *(base+24) = 0xc004642030
>> > obj=0xc0016c5668 s.base()=0xc0016c4000 s.limit=0xc0016c5ff8
>> s.spanclass=6 s.elemsize=24 s.state=mSpanInUse
>> > *(obj+0) = 0x15e0e80
>> > *(obj+8) = 0xc00039c080
>> > *(obj+16) = 0xc0016c5650
>> > fatal error: marking free object
>> >
>> > runtime stack:
>> > runtime.throw({0x132362a?, 0x3?})
>> > /usr/local/go-1.21.0/src/runtime/panic.go:1077 +0x5c fp=0x7f9636366d48
>> sp=0x7f9636366d18 pc=0x43aa9c
>> > runtime.greyobject(0xc0016c5668, 0x1?, 0x7f9636366df8?, 0x6590?,
>> 0x7f9636366df8?, 0x7f9636366de0?)
>> > /usr/local/go-1.21.0/src/runtime/mgcmark.go:1476 +0x285
>> fp=0x7f9636366d98 sp=0x7f9636366d48 pc=0x424d85
>> > runtime.scanobject(0xc0046ca8e0, 0xc00004d240)
>> > /usr/local/go-1.21.0/src/runtime/mgcmark.go:1336 +0x171
>> fp=0x7f9636366e20 sp=0x7f9636366d98 pc=0x424711
>> > runtime.gcDrain(0xc00004d240, 0x7)
>> > /usr/local/go-1.21.0/src/runtime/mgcmark.go:1103 +0x1ba
>> fp=0x7f9636366e80 sp=0x7f9636366e20 pc=0x423fba
>> > runtime.gcBgMarkWorker.func2()
>> > /usr/local/go-1.21.0/src/runtime/mgc.go:1385 +0x6f fp=0x7f9636366ed0
>> sp=0x7f9636366e80 pc=0x4208af
>> > runtime.systemstack()
>> > /usr/local/go-1.21.0/src/runtime/asm_amd64.s:509 +0x4a
>> fp=0x7f9636366ee0 sp=0x7f9636366ed0 pc=0x46b1aa
>> >
>> >
>> > From the docs, I understand this 2nd pass stop-the-world verification
>> > guarantees the concurrent mark step did not follow the pointer, aka
>> this is a GC bug?
>> >
>> > A confirmation would be greatly appreciated to help me follow the right
>> trail.
>> >
>> > Context
>> > I'm building a type-system on top of Go for user-defined data
>> structures. For efficient implementation, I'm using unsafe.Pointer-s
>> heavily. I believe I understand pointer conversion rules, span classes,
>> that there is metadata on the side to differentiate ordinary values from
>> pointers and how it is used to follow pointer chains.
>> > Go vet detects no issues. I've been debugging this for 4 days.
>>
>> That error looks like the GC found a pointer to an object that was
>> already freed. This can happen, for example, if you convert a uintptr
>> to a pointer type, but the object to which the pointer points has been
>> freed. While it could be a GC bug, that would not be my first guess.
>> The contents of the block shown above are intended to help you
>> identify where the pointer came from.
>>
>> Ian
>>
>
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/5d0be612-39ec-48dd-a567-a8eb0172cfb1n%40googlegroups.com.