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
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env)?go envOutput$ 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:
remove.go:
Create a very deep directory tree (~2.5 million subdirectories)
Attempt to remove them with os.RemoveAll()
Observe exhaustion of system memory, causing oom-killer to kill the process. Directory tree still remains:
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