Skip to content
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

encoding/gob: TestFuzz can use a lot of memory #3225

Closed
mikioh opened this issue Mar 7, 2012 · 21 comments
Closed

encoding/gob: TestFuzz can use a lot of memory #3225

mikioh opened this issue Mar 7, 2012 · 21 comments
Milestone

Comments

@mikioh
Copy link
Contributor

@mikioh mikioh commented Mar 7, 2012

What steps will reproduce the problem?
1. run go test -v std
2.
3.

What is the expected output? What do you see instead?
all tests pass

Please use labels and text to provide additional information.
--- PASS: TestDebugStruct (0.00 seconds)
=== RUN TestFuzz
runtime: out of memory: cannot allocate 268500992-byte block (269549568 in use)
throw: out of memory

goroutine 23 [running]:
encoding/gob.(*Decoder).readMessage(0x98298140, 0x10000766, 0x98262200)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:92 +0x5a
encoding/gob.(*Decoder).recvMessage(0x98298140, 0x0, 0x1)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:84 +0xaa
encoding/gob.(*Decoder).decodeTypeSequence(0x98298140, 0x98267d00, 0x160, 0x0)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:142 +0x57
encoding/gob.(*Decoder).DecodeValue(0x98298140, 0x80f98f0, 0x98267dc0, 0x160, 0x0, ...)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:206 +0xe4
encoding/gob.(*Decoder).Decode(0x98298140, 0x80f98e8, 0x98267dc0, 0x98267dc0,
0x98296de0, ...)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:185 +0x168
encoding/gob.encFuzzDec(0x98261cc8, 0x80f9640, 0x98278bf8, 0x982373e0, 0x982021a0, ...)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1429 +0x287
encoding/gob.testFuzz(0x98263440, 0x383acc68, 0x1278f820, 0x64, 0xb8244f68, ...)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1468 +0x1a4
encoding/gob.TestFuzz(0x98263440, 0xe)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1452 +0x2fa
testing.tRunner(0x98263440, 0x82113d0, 0x0)
    /tmp/bindist445861990/go/src/pkg/testing/testing.go:271 +0x6e
created by testing.RunTests
    /tmp/bindist445861990/go/src/pkg/testing/testing.go:346 +0x687

goroutine 1 [chan receive]:
testing.RunTests(0x8048c00, 0x82112e0, 0x49, 0x49, 0x8202101, ...)
    /tmp/bindist445861990/go/src/pkg/testing/testing.go:347 +0x6a7
testing.Main(0x8048c00, 0x82112e0, 0x49, 0x49, 0x820dd58, ...)
    /tmp/bindist445861990/go/src/pkg/testing/testing.go:282 +0x46
main.main()
    /tmp/go-build055329031/encoding/gob/_test/_testmain.go:191 +0x4e

goroutine 2 [syscall]:
created by runtime.main
    /tmp/bindist445861990/go/src/pkg/runtime/proc.c:219
FAIL    encoding/gob    0.012s
@mikioh
Copy link
Contributor Author

@mikioh mikioh commented Mar 7, 2012

Comment 1:

% ulimit -a
socket buffer size       (bytes, -b) unlimited
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) 2097152
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 7207
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 65536
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3603
virtual memory          (kbytes, -v) unlimited
swap size               (kbytes, -w) unlimited
@mikioh
Copy link
Contributor Author

@mikioh mikioh commented Mar 7, 2012

Comment 2:

% go version
go version weekly.2012-03-04 +f4470a54e6db
@rsc
Copy link
Contributor

@rsc rsc commented Mar 7, 2012

Comment 3:

There is a separate bug about not being able to use
more than 512 MB on 32-bit.  Do you believe that
the fuzz input should not be causing gob to try to
allocate that much memory?
If the allocation is appropriate for the input, then this
is not a bug in gob but a dup of the runtime bug, which
Remy has a CL pending for.
Russ
@mikioh
Copy link
Contributor Author

@mikioh mikioh commented Mar 7, 2012

Comment 4:

I agree with you, that supposed root cause would be runtime.
I just filed for the record of first binary distribution trial. ;)
By the way, unfortunately CL 5725045 doesn't fix the issue
for 32-bit memory allocator.
http://golang.org/cl/5725045/
% go test -v encoding/gob
(snip)
=== RUN TestFuzz
runtime: out of memory: cannot allocate 806223872-byte block (1048576 in use)
throw: out of memory
goroutine 23 [running]:
encoding/gob.(*Decoder).readMessage(0x9828a820, 0x300d0369, 0x98269b40)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:92 +0x5a
encoding/gob.(*Decoder).recvMessage(0x9828a820, 0x0, 0x1)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:84 +0xaa
encoding/gob.(*Decoder).decodeTypeSequence(0x9828a820, 0x98289400, 0x160, 0x0)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:142 +0x57
encoding/gob.(*Decoder).DecodeValue(0x9828a820, 0x80f9c70, 0x98289410, 0x160, 0x0, ...)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:206 +0xe4
encoding/gob.(*Decoder).Decode(0x9828a820, 0x80f9c68, 0x98289410, 0x98289410,
0x9828d4e0, ...)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:185 +0x168
encoding/gob.encFuzzDec(0x9827bcc8, 0x80f9ba0, 0x9827bc70, 0x982373e0, 0x982381a0, ...)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1429 +0x287
encoding/gob.testFuzz(0x98281d00, 0xf9d05b78, 0x1278fce3, 0x64, 0xb8245f68, ...)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1468 +0x1a4
encoding/gob.TestFuzz(0x98281d00, 0xe)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1452 +0x2fa
testing.tRunner(0x98281d00, 0x8212bf8, 0x0)
    /home/mikioh/go/src/pkg/testing/testing.go:271 +0x6e
created by testing.RunTests
    /home/mikioh/go/src/pkg/testing/testing.go:346 +0x687
goroutine 1 [chan receive]:
testing.RunTests(0x8048c00, 0x8212b08, 0x49, 0x49, 0x8203101, ...)
    /home/mikioh/go/src/pkg/testing/testing.go:347 +0x6a7
testing.Main(0x8048c00, 0x8212b08, 0x49, 0x49, 0x820f570, ...)
    /home/mikioh/go/src/pkg/testing/testing.go:282 +0x46
main.main()
    /tmp/go-build357021947/encoding/gob/_test/_testmain.go:191 +0x4e
goroutine 2 [syscall]:
created by runtime.main
    /home/mikioh/go/src/pkg/runtime/proc.c:221
exit status 2
FAIL    encoding/gob    0.034s
% hg id
99a66fff2af2+ tip
% hg p
5725045:
    runtime: try extending arena size in 32-bit allocator.
@rsc
Copy link
Contributor

@rsc rsc commented Mar 7, 2012

Comment 5:

Well, asking for 800 MB on a 32-bit system is probably
too much anyway.
@mikioh
Copy link
Contributor Author

@mikioh mikioh commented Mar 7, 2012

Comment 6:

What about making TestFuzz run w/ a flag that default is false,
at least on 386 runtime environment?
@mikioh
Copy link
Contributor Author

@mikioh mikioh commented Mar 7, 2012

Comment 7:

Also on linux/386.
=== RUN TestFuzz
runtime: memory allocated by OS not in usable range
runtime: out of memory: cannot allocate 268500992-byte block (272695296 in use)
throw: out of memory
@remyoudompheng
Copy link
Contributor

@remyoudompheng remyoudompheng commented Mar 7, 2012

Comment 8:

mikioh: can you retry with latest version of my CL? Here 
  GOARCH=386 go test encoding/gob
works. I tested it with a program that takes up to 1.8GB and it didn't die (but I have
3GB physical RAM)
@mikioh
Copy link
Contributor Author

@mikioh mikioh commented Mar 7, 2012

Comment 9:

Sure -- Mikio
@mikioh
Copy link
Contributor Author

@mikioh mikioh commented Mar 7, 2012

Comment 10:

vm5% dmesg | grep memory
real memory  = 2147483648 (2048 MB)
avail memory = 2091053056 (1994 MB)
// with CL 5725045
vm5% go test -v encoding/gob -run=TestFuzz
=== RUN TestFuzz
--- PASS: TestFuzz (0.01 seconds)
    codec_test.go:1465: seed=1331108516916737000 n=100 e=*int
    codec_test.go:1465: seed=1331108516916737000 n=100 e=*float32
    codec_test.go:1465: seed=1331108516916737000 n=100 e=*float64
    codec_test.go:1465: seed=1331108516916737000 n=100 e=*complex128
    codec_test.go:1465: seed=1331108516916737000 n=100 e=*gob.ByteStruct
    codec_test.go:1465: seed=1331108516916737000 n=100 e=*gob.ArrayStruct
    codec_test.go:1465: seed=1331108516916737000 n=100 e=*gob.StringStruct
    codec_test.go:1465: seed=1331108516916737000 n=100 e=*gob.GobTest1
=== RUN TestFuzzRegressions
runtime: out of memory: cannot allocate 268500992-byte block (271712256 in use)
throw: out of memory
goroutine 4 [running]:
encoding/gob.(*Decoder).readMessage(0xa8481be0, 0x1000cf66, 0xa847b620)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:92 +0x5a
encoding/gob.(*Decoder).recvMessage(0xa8481be0, 0x0, 0x1)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:84 +0xaa
encoding/gob.(*Decoder).decodeTypeSequence(0xa8481be0, 0xa8479c00, 0x160, 0x0)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:142 +0x57
encoding/gob.(*Decoder).DecodeValue(0xa8481be0, 0x80fd260, 0xa8479c68, 0x160, 0x0, ...)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:206 +0xe4
encoding/gob.(*Decoder).Decode(0xa8481be0, 0x80fd258, 0xa8479c68, 0xa8479c68,
0xa8484f00, ...)
    /home/mikioh/go/src/pkg/encoding/gob/decoder.go:185 +0x168
encoding/gob.encFuzzDec(0xa84654b0, 0x80fcf88, 0xa8465488, 0x982333e0, 0x9823e1b0, ...)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1429 +0x287
encoding/gob.testFuzz(0xa8468380, 0x994c53f0, 0x126fc084, 0x64, 0xb824cfa4, ...)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1468 +0x1a4
encoding/gob.TestFuzzRegressions(0xa8468380, 0xe)
    /home/mikioh/go/src/pkg/encoding/gob/codec_test.go:1457 +0x99
testing.tRunner(0xa8468380, 0x8219c44, 0x0)
    /home/mikioh/go/src/pkg/testing/testing.go:271 +0x6e
created by testing.RunTests
    /home/mikioh/go/src/pkg/testing/testing.go:346 +0x687
goroutine 1 [chan receive]:
testing.RunTests(0x8048c00, 0x8219b48, 0x49, 0x49, 0x820a101, ...)
    /home/mikioh/go/src/pkg/testing/testing.go:347 +0x6a7
testing.Main(0x8048c00, 0x8219b48, 0x49, 0x49, 0x82165b0, ...)
    /home/mikioh/go/src/pkg/testing/testing.go:282 +0x46
main.main()
    /tmp/go-build628245346/encoding/gob/_test/_testmain.go:191 +0x4e
goroutine 2 [syscall]:
created by runtime.main
    /home/mikioh/go/src/pkg/runtime/proc.c:221
exit status 2
FAIL    encoding/gob    0.040s
@rsc
Copy link
Contributor

@rsc rsc commented Mar 7, 2012

Comment 11:

How big is the input being passed to gob?
@rsc
Copy link
Contributor

@rsc rsc commented Mar 7, 2012

Comment 12:

Labels changed: added priority-go1, removed priority-triage.

@alberts
Copy link
Contributor

@alberts alberts commented Mar 7, 2012

Comment 13:

It shouldn't ever be more than a few bytes:
http://code.google.com/p/go/source/browse/src/pkg/encoding/gob/codec_test.go#1436
the fuzz test just corrupts the bytes for a single encoded object at this point.
@rsc
Copy link
Contributor

@rsc rsc commented Mar 7, 2012

Comment 14:

This test is already skipped for -short.
It is true that the fuzzer can create gobs that happen
to describe very large data structures.
Sometimes they don't fit completely in memory.
I think this is nearly unavoidable.

Labels changed: added priority-later, removed priority-go1.

Status changed to LongTerm.

@davecheney
Copy link
Contributor

@davecheney davecheney commented Jul 16, 2012

@rsc
Copy link
Contributor

@rsc rsc commented Sep 12, 2012

Comment 16:

Labels changed: added go1.1maybe.

@robpike
Copy link
Contributor

@robpike robpike commented Mar 7, 2013

Comment 17:

Labels changed: removed go1.1maybe.

@rsc
Copy link
Contributor

@rsc rsc commented Nov 27, 2013

Comment 18:

Labels changed: added go1.3maybe.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 19:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

@rsc rsc commented Dec 4, 2013

Comment 20:

Labels changed: added repo-main.

@agnivade
Copy link
Contributor

@agnivade agnivade commented Dec 2, 2017

Just tested this on tip.

It takes around 400MB now.

root@agniva-ubuntu:/home/agniva/play/gosource/go/src# ulimit -v 400000
root@agniva-ubuntu:/home/agniva/play/gosource/go/src# ../bin/go test -v encoding/gob -run=Fuzz -gob.fuzz
=== RUN   TestFuzz
--- PASS: TestFuzz (0.01s)
	codec_test.go:1457: seed=1512208589752279997 n=100 e=*int
	codec_test.go:1457: seed=1512208589752279997 n=100 e=*float32
	codec_test.go:1457: seed=1512208589752279997 n=100 e=*float64
	codec_test.go:1457: seed=1512208589752279997 n=100 e=*complex128
	codec_test.go:1457: seed=1512208589752279997 n=100 e=*gob.ByteStruct
	codec_test.go:1457: seed=1512208589752279997 n=100 e=*gob.ArrayStruct
	codec_test.go:1457: seed=1512208589752279997 n=100 e=*gob.StringStruct
	codec_test.go:1457: seed=1512208589752279997 n=100 e=*gob.GobTest1
=== RUN   TestFuzzRegressions
--- PASS: TestFuzzRegressions (0.11s)
	codec_test.go:1457: seed=1328492090837718000 n=100 e=*float32
	codec_test.go:1457: seed=1330522872628565000 n=100 e=*int
=== RUN   TestFuzzOneByte
--- PASS: TestFuzzOneByte (0.87s)
PASS
ok  	encoding/gob	0.996s

When I try 300MB, it always fails.

root@agniva-ubuntu:/home/agniva/play/gosource/go/src# ulimit -v 300000
root@agniva-ubuntu:/home/agniva/play/gosource/go/src# ../bin/go test -v encoding/gob -run=Fuzz -gob.fuzz
=== RUN   TestFuzz
--- PASS: TestFuzz (0.00s)
	codec_test.go:1457: seed=1512208580484615295 n=100 e=*int
	codec_test.go:1457: seed=1512208580484615295 n=100 e=*float32
	codec_test.go:1457: seed=1512208580484615295 n=100 e=*float64
	codec_test.go:1457: seed=1512208580484615295 n=100 e=*complex128
	codec_test.go:1457: seed=1512208580484615295 n=100 e=*gob.ByteStruct
	codec_test.go:1457: seed=1512208580484615295 n=100 e=*gob.ArrayStruct
	codec_test.go:1457: seed=1512208580484615295 n=100 e=*gob.StringStruct
	codec_test.go:1457: seed=1512208580484615295 n=100 e=*gob.GobTest1
=== RUN   TestFuzzRegressions
fatal error: runtime: out of memory

runtime stack:
runtime.throw(0x5b121c, 0x16)
	/home/agniva/play/gosource/go/src/runtime/panic.go:616 +0x81
runtime.sysMap(0xc420300000, 0x10010000, 0x50ac00, 0x6b36f8)
	/home/agniva/play/gosource/go/src/runtime/mem_linux.go:216 +0x20a
runtime.(*mheap).sysAlloc(0x699800, 0x10010000, 0x7f22c1bcb738)
	/home/agniva/play/gosource/go/src/runtime/malloc.go:470 +0xd4
runtime.(*mheap).grow(0x699800, 0x8007, 0x0)
	/home/agniva/play/gosource/go/src/runtime/mheap.go:907 +0x60
runtime.(*mheap).allocSpanLocked(0x699800, 0x8007, 0x6b3708, 0x7fffcc1bd870)
	/home/agniva/play/gosource/go/src/runtime/mheap.go:820 +0x301
runtime.(*mheap).alloc_m(0x699800, 0x8007, 0x410101, 0xc41ffee9ff)
	/home/agniva/play/gosource/go/src/runtime/mheap.go:686 +0x118
runtime.(*mheap).alloc.func1()
	/home/agniva/play/gosource/go/src/runtime/mheap.go:753 +0x43
runtime.(*mheap).alloc(0x699800, 0x8007, 0x7fffcc010101, 0x41412c)
	/home/agniva/play/gosource/go/src/runtime/mheap.go:752 +0x8a
runtime.largeAlloc(0x1000cf66, 0xc420050101, 0x7f22c1c12000)
	/home/agniva/play/gosource/go/src/runtime/malloc.go:826 +0x94
runtime.mallocgc.func1()
	/home/agniva/play/gosource/go/src/runtime/malloc.go:721 +0x46
runtime.systemstack(0x0)
	/home/agniva/play/gosource/go/src/runtime/asm_amd64.s:409 +0x79
runtime.mstart()
	/home/agniva/play/gosource/go/src/runtime/proc.go:1170

goroutine 6 [running]:
runtime.systemstack_switch()
	/home/agniva/play/gosource/go/src/runtime/asm_amd64.s:363 fp=0xc420057bb8 sp=0xc420057bb0 pc=0x4538c0
runtime.mallocgc(0x1000cf66, 0x56a9c0, 0x1, 0xc420057cd8)
	/home/agniva/play/gosource/go/src/runtime/malloc.go:720 +0x8a2 fp=0xc420057c58 sp=0xc420057bb8 pc=0x410812
runtime.makeslice(0x56a9c0, 0x1000cf66, 0x1000cf66, 0x9, 0x4, 0x0)
	/home/agniva/play/gosource/go/src/runtime/slice.go:61 +0x77 fp=0xc420057c88 sp=0xc420057c58 pc=0x43e237
encoding/gob.(*decBuffer).Size(...)
	/home/agniva/play/gosource/go/src/encoding/gob/decode.go:65
encoding/gob.(*Decoder).readMessage(0xc42022a480, 0x1000cf66)
	/home/agniva/play/gosource/go/src/encoding/gob/decoder.go:100 +0x17e fp=0xc420057ce8 sp=0xc420057c88 pc=0x50c00e
encoding/gob.(*Decoder).recvMessage(0xc42022a480, 0xc420057d68)
	/home/agniva/play/gosource/go/src/encoding/gob/decoder.go:89 +0xf0 fp=0xc420057d40 sp=0xc420057ce8 pc=0x50be60
encoding/gob.(*Decoder).decodeTypeSequence(0xc42022a480, 0x5ba600, 0xc42022a480)
	/home/agniva/play/gosource/go/src/encoding/gob/decoder.go:142 +0x136 fp=0xc420057d60 sp=0xc420057d40 pc=0x50c326
encoding/gob.(*Decoder).DecodeValue(0xc42022a480, 0x5619c0, 0xc420218ed0, 0x16, 0x0, 0x0)
	/home/agniva/play/gosource/go/src/encoding/gob/decoder.go:210 +0xdc fp=0xc420057d98 sp=0xc420057d60 pc=0x50c5ec
encoding/gob.(*Decoder).Decode(0xc42022a480, 0x5619c0, 0xc420218ed0, 0x0, 0x0)
	/home/agniva/play/gosource/go/src/encoding/gob/decoder.go:187 +0x14f fp=0xc420057df0 sp=0xc420057d98 pc=0x50c49f
encoding/gob.encFuzzDec(0xc420057ed8, 0x561480, 0xc420202378, 0x5d13c0, 0xc4200464c0)
	/home/agniva/play/gosource/go/src/encoding/gob/codec_test.go:1415 +0x1d1 fp=0xc420057e60 sp=0xc420057df0 pc=0x528f81
encoding/gob.testFuzz(0xc4200c61e0, 0x126fc084994c53f0, 0x64, 0xc420057f88, 0x1, 0x1)
	/home/agniva/play/gosource/go/src/encoding/gob/codec_test.go:1460 +0x7a fp=0xc420057f48 sp=0xc420057e60 pc=0x5295ba
encoding/gob.TestFuzzRegressions(0xc4200c61e0)
	/home/agniva/play/gosource/go/src/encoding/gob/codec_test.go:1449 +0xa3 fp=0xc420057fa8 sp=0xc420057f48 pc=0x529473
testing.tRunner(0xc4200c61e0, 0x5b9ad8)
	/home/agniva/play/gosource/go/src/testing/testing.go:774 +0xc4 fp=0xc420057fd0 sp=0xc420057fa8 pc=0x4bf314
runtime.goexit()
	/home/agniva/play/gosource/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc420057fd8 sp=0xc420057fd0 pc=0x456411
created by testing.(*T).Run
	/home/agniva/play/gosource/go/src/testing/testing.go:821 +0x2ca

goroutine 1 [chan receive]:
testing.(*T).Run(0xc4200c61e0, 0x5aff6e, 0x13, 0x5b9ad8, 0x46c001)
	/home/agniva/play/gosource/go/src/testing/testing.go:822 +0x2eb
testing.runTests.func1(0xc4200c6000)
	/home/agniva/play/gosource/go/src/testing/testing.go:1048 +0x64
testing.tRunner(0xc4200c6000, 0xc420055df8)
	/home/agniva/play/gosource/go/src/testing/testing.go:774 +0xc4
testing.runTests(0xc42000c780, 0x6926c0, 0x5b, 0x5b, 0x410269)
	/home/agniva/play/gosource/go/src/testing/testing.go:1046 +0x2bb
testing.(*M).Run(0xc4200ae150, 0x0)
	/home/agniva/play/gosource/go/src/testing/testing.go:963 +0x15c
main.main()
	_testmain.go:258 +0x151
FAIL	encoding/gob	0.022s

If there's nothing else to be done here, perhaps this can be closed.

@robpike robpike closed this Dec 2, 2017
@golang golang locked and limited conversation to collaborators Dec 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants
You can’t perform that action at this time.