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.

Reply via email to