Skip to content

Commit 6c061fc

Browse files
committed
fix: Safe slice mutation during iteration
Mutating the slice while iterating leads to nasty side effects as the loop keeps evaluating the original slice header so removals don't shrink the loop bounds.
1 parent e9d8099 commit 6c061fc

2 files changed

Lines changed: 15 additions & 8 deletions

File tree

internal/etw/processors/fs_windows.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ package processors
2020

2121
import (
2222
"expvar"
23+
"sync"
24+
"time"
25+
2326
"github.com/rabbitstack/fibratus/pkg/config"
2427
"github.com/rabbitstack/fibratus/pkg/event"
2528
"github.com/rabbitstack/fibratus/pkg/event/params"
@@ -31,8 +34,6 @@ import (
3134
"github.com/rabbitstack/fibratus/pkg/util/va"
3235
"golang.org/x/sys/windows"
3336
"golang.org/x/time/rate"
34-
"sync"
35-
"time"
3637
)
3738

3839
var (
@@ -371,11 +372,13 @@ func (f *fsProcessor) purge() {
371372

372373
// evict unmatched stack traces
373374
for id, q := range f.buckets {
374-
for i, evt := range q {
375-
if time.Since(evt.Timestamp) > time.Second*30 {
376-
f.buckets[id] = append(q[:i], q[i+1:]...)
375+
s := q[:0]
376+
for _, evt := range q {
377+
if time.Since(evt.Timestamp) <= time.Second*30 {
378+
s = append(s, evt)
377379
}
378380
}
381+
f.buckets[id] = s
379382
}
380383

381384
f.mu.Unlock()

pkg/event/stackwalk.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ func (s *StackwalkDecorator) Pop(e *Event) *Event {
160160
if !proc.IsCreateProcess() && proc.Params.MustGetPid() != pid {
161161
continue
162162
}
163-
s.buckets[ev.StackID()] = append(qu[:i], qu[i+1:]...)
163+
qu = append(qu[:i], qu[i+1:]...)
164164
}
165+
s.buckets[ev.StackID()] = qu
165166
}
166167
}
167168

@@ -209,16 +210,18 @@ func (s *StackwalkDecorator) flush() []error {
209210
errs := make([]error, 0)
210211

211212
for id, q := range s.buckets {
212-
for i, evt := range q {
213+
n := q[:0]
214+
for _, evt := range q {
213215
if time.Since(evt.Timestamp) < maxQueueTTLPeriod {
216+
n = append(n, evt)
214217
continue
215218
}
219+
216220
stackwalkFlushes.Add(1)
217221
err := s.q.push(evt)
218222
if err != nil {
219223
errs = append(errs, err)
220224
}
221-
s.buckets[id] = append(q[:i], q[i+1:]...)
222225
if stackwalkEnqueued.Value() > 0 {
223226
stackwalkEnqueued.Add(-1)
224227
}
@@ -227,6 +230,7 @@ func (s *StackwalkDecorator) flush() []error {
227230
}
228231
stackwalkFlushesEvents.Add(evt.Name, 1)
229232
}
233+
s.buckets[id] = n
230234
}
231235

232236
return errs

0 commit comments

Comments
 (0)