-
Notifications
You must be signed in to change notification settings - Fork 285
Refactoring Bytes to check double free and code cleanup #22251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
11c4296
984687f
e0b8452
b6bd15b
d9e6785
48cb9a1
a0b6ec3
a1cc5a2
f86c0eb
f9cce27
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,16 +25,17 @@ import ( | |
type Bytes struct { | ||
bytes []byte | ||
deallocator malloc.Deallocator | ||
deallocated uint32 | ||
_refs atomic.Int32 | ||
refs *atomic.Int32 | ||
refs atomic.Int32 | ||
} | ||
|
||
func (b *Bytes) Size() int64 { | ||
return int64(len(b.bytes)) | ||
} | ||
|
||
func (b *Bytes) Bytes() []byte { | ||
if b.refs.Load() <= 0 { | ||
panic("Bytes.Bytes: memory was already deallocated.") | ||
} | ||
return b.bytes | ||
} | ||
|
||
|
@@ -44,25 +45,29 @@ func (b *Bytes) Slice(length int) fscache.Data { | |
} | ||
|
||
func (b *Bytes) Retain() { | ||
if b.refs != nil { | ||
b.refs.Add(1) | ||
} | ||
b.refs.Add(1) | ||
} | ||
|
||
func (b *Bytes) Release() { | ||
if b.refs != nil { | ||
if n := b.refs.Add(-1); n == 0 { | ||
if b.deallocator != nil && | ||
atomic.CompareAndSwapUint32(&b.deallocated, 0, 1) { | ||
b.deallocator.Deallocate(malloc.NoHints) | ||
} | ||
} | ||
} else { | ||
if b.deallocator != nil && | ||
atomic.CompareAndSwapUint32(&b.deallocated, 0, 1) { | ||
n := b.refs.Add(-1) | ||
if n == 0 { | ||
// set bytes to nil | ||
b.bytes = nil | ||
if b.deallocator != nil { | ||
b.deallocator.Deallocate(malloc.NoHints) | ||
b.deallocator = nil | ||
} | ||
} else if n < 0 { | ||
panic("Bytes.Release: double free") | ||
} | ||
} | ||
|
||
func NewBytes(data []byte) *Bytes { | ||
bytes := &Bytes{ | ||
bytes: data, | ||
} | ||
bytes.refs.Store(1) | ||
return bytes | ||
} | ||
|
||
type bytesAllocator struct { | ||
|
@@ -80,8 +85,7 @@ func (b *bytesAllocator) allocateCacheData(size int, hints malloc.Hints) fscache | |
bytes: slice, | ||
deallocator: dec, | ||
} | ||
bytes._refs.Store(1) | ||
bytes.refs = &bytes._refs | ||
bytes.refs.Store(1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor, you can do a NewBytes here, so that we can restrict all the Store(1) to one single place. |
||
return bytes | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -130,7 +130,7 @@ func (r *RemoteCache) Read(ctx context.Context, vector *IOVector) error { | |
idx := int(cacheData.Index) | ||
if cacheData.Hit { | ||
vector.Entries[idx].done = true | ||
vector.Entries[idx].CachedData = &Bytes{bytes: cacheData.Data} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @reusee can you please check this line? This is significant. I will be surprised if the old code works, and the new code also works without a leak. Are we fixing a real bug here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 旧的代码不带引用计数,所以就只是对 []byte 的包装。新的代码改成了引用计数,只要使用方的计数正确,就不会有问题。如果真的有问题,可以另外增加一个 GoBytes 类型,实现 fscache.Data 接口,但不实现引用计数机制。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. Cannot have another type; the ref counting MUST be correct. So great, let's go with this and see if we will hit panic. Thank you. |
||
vector.Entries[idx].CachedData = NewBytes(cacheData.Data) | ||
vector.Entries[idx].fromCache = r | ||
numHit++ | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.