-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Open
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
Description
What version of Go are you using (go version)?
$ go version go1.16.5 linux/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/test/.cache/go-build"
GOENV="/home/test/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/test/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/test/go"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/usr/lib/golang"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/golang/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.5"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1485272220=/tmp/go-build -gno-record-gcc-switches"
What did you do?
create.go:
package main
import (
"fmt"
"log"
"os"
"strings"
)
func main() {
path := os.Args[1]
os.Mkdir(path, 0755)
os.Chdir(path)
// 2^30 is big enough that the process will run out of memory before completing on most machines
// 2^10 (1024) is a good value to use for profiling memory usage
// n := 10
n := 30
for i := 0; i < (1 << n); i++ {
dirname := strings.Repeat("x", 255)
if i%128 == 0 {
fmt.Println(i)
}
err := os.Mkdir(dirname, 0755)
if err != nil {
log.Fatal(err)
}
os.Chdir(dirname)
}
}
remove.go:
package main
import (
"log"
"os"
)
func main() {
dir := os.Args[1]
err := os.RemoveAll(dir)
if err != nil {
log.Fatal(err)
}
}
Create a very deep directory tree (~2.5 million subdirectories)
$ go run create.go /tmp/deep
0
128
...
2473472
Killed
Attempt to remove them with os.RemoveAll()
$ go run remove.go /tmp/deep
Killed
Observe exhaustion of system memory, causing oom-killer to kill the process. Directory tree still remains:
$ ls -d /tmp/deep
/tmp/deep
What did you expect to see?
remove.go successfully remove the target deep directory tree, without exhausting system memory
What did you see instead?
remove.go causes a sharp increase in memory usage, causing OOM killer to kill remove.go before it can complete
Metadata
Metadata
Assignees
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.