mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
- runsc/debug.go: the SIGUSR2 stack dumper never exited its loop, so one signal pinned a core for the life of the shim. - proc/init_state.go: the start-failure path closed p.io unconditionally, but Init.Create leaves it nil for terminal containers. The nil deref killed the shim, and with it the pod. - proc/utils.go: getLastRuntimeError leaked the log file it opened, on every failed runsc command. - utils/volumes.go: configureShm wrote into a nil annotation map, which IsSandbox permits. - runsc/epoll.go: the cgroups v1 OOM watcher panicked on the first publish failure, which is normal under CRI-O. Reuse forward's leniency check; the panic under containerd is kept. - runsccmd/runsc.go: cmdOutput returned slices aliasing sync.Pool buffers that putBuf immediately recycled.
56 lines
1.6 KiB
Go
56 lines
1.6 KiB
Go
// Copyright 2026 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package runsc
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// TestDumpStacksTerminates verifies that a stack dump returns rather than
|
|
// looping forever, which would spin a core and flood the log on every SIGUSR2.
|
|
func TestDumpStacksTerminates(t *testing.T) {
|
|
done := make(chan []byte, 1)
|
|
go func() {
|
|
done <- dumpStacks()
|
|
}()
|
|
|
|
select {
|
|
case buf := <-done:
|
|
if len(buf) == 0 {
|
|
t.Fatal("dumpStacks() returned no data")
|
|
}
|
|
if got := string(buf); !strings.Contains(got, "goroutine ") {
|
|
t.Errorf("dumpStacks() = %q, want a goroutine dump", got)
|
|
}
|
|
case <-time.After(30 * time.Second):
|
|
t.Fatal("dumpStacks() did not return; it is looping")
|
|
}
|
|
}
|
|
|
|
// TestDumpStacksRepeatable verifies that consecutive dumps do not share a
|
|
// buffer.
|
|
func TestDumpStacksRepeatable(t *testing.T) {
|
|
first := dumpStacks()
|
|
second := dumpStacks()
|
|
if len(first) == 0 || len(second) == 0 {
|
|
t.Fatalf("dumpStacks() returned empty: %d, %d bytes", len(first), len(second))
|
|
}
|
|
if &first[0] == &second[0] {
|
|
t.Error("consecutive dumpStacks() calls returned aliasing buffers")
|
|
}
|
|
}
|