go-python / gpython

gpython is a python interpreter written in go "batteries not included"
BSD 3-Clause "New" or "Revised" License
870 stars 95 forks source link

Taking large arguments in functions crashes gpython #209

Open xiaxinmeng opened 1 year ago

xiaxinmeng commented 1 year ago

The following example takes large arguments and then crashes gpython.

test.py

def f(*args, **kwargs):
    return (len(args), len(kwargs))
f(*[0] * (2 ** 32 + 1))

Output on go/wasm(https://gpython.org/?wasm):

Gpython 3.4.0 running in your browser with gopherjs
>>> def f(*args, **kwargs):
...     return (len(args), len(kwargs))
... 
>>> f(*[0] * (2 ** 32 + 1))
[USER]: https://gpython.org/gpython.js: runtime error: invalid memory address or nil pointer dereference
$callDeferred@https://gpython.org/gpython.js:4:22511
$panic@https://gpython.org/gpython.js:4:22957
AK@https://gpython.org/gpython.js:10:2429
$throwNilPointerError@https://gpython.org/gpython.js:4:504
get@https://gpython.org/gpython.js:4:4514
BL.ptr.prototype.Exp@https://gpython.org/gpython.js:38:95685
BH.ptr.prototype.pow@https://gpython.org/gpython.js:41:102703
BH.ptr.prototype.M__pow__@https://gpython.org/gpython.js:41:103772
EQ.prototype.M__pow__@https://gpython.org/gpython.js:41:236439
AZ@https://gpython.org/gpython.js:41:73603
V@https://gpython.org/gpython.js:44:18787
DO@https://gpython.org/gpython.js:44:91592
DU@https://gpython.org/gpython.js:44:107450
DW@https://gpython.org/gpython.js:44:109015
G.ptr.prototype.Run@https://gpython.org/gpython.js:56:3575
$b@https://gpython.org/gpython.js:60:3908
$b@https://gpython.org/gpython.js:59:2625
r@https://gpython.org/gpython.js:4:23443
$runScheduled@https://gpython.org/gpython.js:4:24007
$schedule@https://gpython.org/gpython.js:4:24184
$go@https://gpython.org/gpython.js:4:23907
I/$packages["github.com/gopherjs/gopherwasm/js"]<@https://gpython.org/gpython.js:59:2240
$externalizeFunction/e.$externalizeWrapper@https://gpython.org/gpython.js:4:28925
a@https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.23.2/js/jquery.terminal.min.js:40:82615
k@https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.23.2/js/jquery.terminal.min.js:40:83463
ENTER@https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.23.2/js/jquery.terminal.min.js:40:14915
$e@https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.23.2/js/jquery.terminal.min.js:40:28362
dispatch@https://code.jquery.com/jquery-latest.js:4641:9
add/elemData.handle@https://code.jquery.com/jquery-latest.js:4309:28

output with gopherjs(https://gpython.org/):

Gpython 3.4.0 running in your browser with go/wasm
>>> def f(*args, **kwargs): return (len(args), len(kwargs))
>>> f(*[0] * (2 ** 32 + 1))
panic: runtime error: makeslice: len out of range
goroutine 5 [running]:
github.com/go-python/gpython/py.NewListSized(...)
    /home/ncw/go/src/github.com/go-python/gpython/py/list.go:52
github.com/go-python/gpython/py.(*List).M__mul__(0xc05eba0, 0x9d6e0, 0xc01e568, 0x2c931ef0, 0xc05eba0, 0x1, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/py/list.go:239 +0x13
github.com/go-python/gpython/py.Mul(0x9d340, 0xc05eba0, 0x9d6e0, 0xc01e568, 0x9d6e0, 0xc01e568, 0x0, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/py/arithmetic.go:262 +0x1d
github.com/go-python/gpython/vm.do_BINARY_MULTIPLY(0xc074930, 0x3, 0x0, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:248 +0xc
github.com/go-python/gpython/vm.RunFrame(0xc0a4370, 0x0, 0xc07bd18, 0x0, 0x0)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:1785 +0x3f
github.com/go-python/gpython/vm.EvalCodeEx(0xc04c400, 0xc062db0, 0xc062db0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:2162 +0xa3
github.com/go-python/gpython/vm.Run(0xc062db0, 0xc062db0, 0xc04c400, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9d240, 0xc04c400)
    /home/ncw/go/src/github.com/go-python/gpython/vm/eval.go:2182 +0x2
github.com/go-python/gpython/repl.(*REPL).Run(0xc09a6c0, 0xc04a660, 0x17)
    /home/ncw/go/src/github.com/go-python/gpython/repl/repl.go:99 +0x20
main.main.func1(0xc01e450, 0x2, 0x2)
    /home/ncw/go/src/github.com/go-python/gpython/repl/web/main.go:82 +0x4
syscall/js.callbackLoop()
    /opt/go/go1.11/src/syscall/js/callback.go:116 +0x7
created by syscall/js.NewCallback.func1
    /opt/go/go1.11/src/syscall/js/callback.go:40 +0x2
ncw commented 1 year ago

Under Go I get quite a clean

fatal error: runtime: out of memory

Then a backtrace.

I think this is just gpython running out of memory because you asked it for a 2^32 entry list and not a particularly interesting bug. The gopher.js and the wasm behaviour are interesting but I don't think that is a gpython problem.