immudb
immudb copied to clipboard
PostgreSQL wire protocol unable to handle invalid traffic
What happened
If the PostgreSQL server is enabled, simple requests via curl
or other non-PG wire protocol traffic can cause immudb to panic.
- When testing with a container with restricted RAM (~2GB), immudb runs out of memory and crashes. See journalctl log attached at bottom of report.
- When testing with an unrestricted container, the request hangs for ~30 seconds and CPU/RAM consumption spike during this.
What you expected to happen
Instant response stating error message.
How to reproduce it (as minimally and precisely as possible)
- Enable
pgsql-server
in/etc/immudb/immudb.toml
. - Make a variety of invalid requests (e.g.
curl localhost:5432
) to the specified PostgreSQL address/port.
Example of 10 requests in serial using hyperfine:
$ hyperfine -i "curl localhost:5432"
Benchmark 1: curl localhost:5432
Time (mean ± σ): 25.071 s ± 1.956 s [User: 0.007 s, System: 0.004 s]
Range (min … max): 22.499 s … 27.274 s 10 runs
Warning: Ignoring non-zero exit code.
Environment
Latest immudb version (currently 1.2.1) on Arch Linux.
Additional info (any other context about the problem)
Output of journalctl -fu immudb.service
on a RAM-restricted container:
NOTE First line is the last line after normal systemctl start immudb.service
.
Dec 29 03:27:53 testing immudb[13437]: You can now use immuadmin and immuclient CLIs to login with the immudb superadmin user and start using immudb.
Dec 29 03:28:13 testing immudb[13437]: fatal error: runtime: out of memory
Dec 29 03:28:13 testing immudb[13437]: runtime stack:
Dec 29 03:28:13 testing immudb[13437]: runtime.throw({0x561ed70146ab, 0x47800000})
Dec 29 03:28:13 testing immudb[13437]: runtime/panic.go:1198 +0x71
Dec 29 03:28:13 testing immudb[13437]: runtime.sysMap(0xc009800000, 0x561ed68c5ba0, 0x7f1652b19c98)
Dec 29 03:28:13 testing immudb[13437]: runtime/mem_linux.go:169 +0x96
Dec 29 03:28:13 testing immudb[13437]: runtime.(*mheap).grow(0x561ed8272d40, 0x23a2b)
Dec 29 03:28:13 testing immudb[13437]: runtime/mheap.go:1393 +0x225
Dec 29 03:28:13 testing immudb[13437]: runtime.(*mheap).allocSpan(0x561ed8272d40, 0x23a2b, 0x0, 0x1)
Dec 29 03:28:13 testing immudb[13437]: runtime/mheap.go:1179 +0x165
Dec 29 03:28:13 testing immudb[13437]: runtime.(*mheap).alloc.func1()
Dec 29 03:28:13 testing immudb[13437]: runtime/mheap.go:913 +0x69
Dec 29 03:28:13 testing immudb[13437]: runtime.systemstack()
Dec 29 03:28:13 testing immudb[13437]: runtime/asm_amd64.s:383 +0x46
Dec 29 03:28:13 testing immudb[13437]: goroutine 61 [running]:
Dec 29 03:28:13 testing immudb[13437]: runtime.systemstack_switch()
Dec 29 03:28:13 testing immudb[13437]: runtime/asm_amd64.s:350 fp=0xc0066ebcd8 sp=0xc0066ebcd0 pc=0x561ed68fe960
Dec 29 03:28:13 testing immudb[13437]: runtime.(*mheap).alloc(0x47456000, 0x23a2b, 0x49, 0x0)
Dec 29 03:28:13 testing immudb[13437]: runtime/mheap.go:907 +0x73 fp=0xc0066ebd28 sp=0xc0066ebcd8 pc=0x561ed68c1ed3
Dec 29 03:28:13 testing immudb[13437]: runtime.(*mcache).allocLarge(0xb, 0x4745541c, 0xc0, 0x1)
Dec 29 03:28:13 testing immudb[13437]: runtime/mcache.go:227 +0x89 fp=0xc0066ebd88 sp=0xc0066ebd28 pc=0x561ed68b2b09
Dec 29 03:28:13 testing immudb[13437]: runtime.mallocgc(0x4745541c, 0x561ed7b560e0, 0x1)
Dec 29 03:28:13 testing immudb[13437]: runtime/malloc.go:1082 +0x5c5 fp=0xc0066ebe08 sp=0xc0066ebd88 pc=0x561ed68a8ec5
Dec 29 03:28:13 testing immudb[13437]: runtime.makeslice(0xc0004630d4, 0xc0004630d4, 0x7f16503558a8)
Dec 29 03:28:13 testing immudb[13437]: runtime/slice.go:98 +0x52 fp=0xc0066ebe30 sp=0xc0066ebe08 pc=0x561ed68e7172
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server.(*session).InitializeSession(0xc008dfc5a0)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server/initialize_session.go:84 +0x465 fp=0xc0066ebf58 sp=0xc0066ebe30 pc=0x561ed6fcb065
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server.(*srv).handleRequest(0xc0002acbe0, {0x561ed7cbbcb8, 0xc00961dcb0})
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server/request_handler.go:27 +0x62 fp=0xc0066ebfb8 sp=0xc0066ebf58 pc=0x561ed6fce502
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server.(*srv).Serve·dwrap·2()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server/server.go:100 +0x2e fp=0xc0066ebfe0 sp=0xc0066ebfb8 pc=0x561ed6fceb4e
Dec 29 03:28:13 testing immudb[13437]: runtime.goexit()
Dec 29 03:28:13 testing immudb[13437]: runtime/asm_amd64.s:1581 +0x1 fp=0xc0066ebfe8 sp=0xc0066ebfe0 pc=0x561ed6900c01
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/pkg/pgsql/server.(*srv).Serve
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server/server.go:100 +0x27d
Dec 29 03:28:13 testing immudb[13437]: goroutine 1 [chan receive]:
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.(*ImmuServer).Start(0xc00027e640)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:306 +0x45b
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.Service.Run(...)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/service.go:36
Dec 29 03:28:13 testing immudb[13437]: github.com/takama/daemon.(*systemDRecord).Run(0x561ed7ca7048, {0x561ed7ca7048, 0xc00628f000})
Dec 29 03:28:13 testing immudb[13437]: github.com/takama/[email protected]/daemon_linux_systemd.go:206 +0x73
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/cmd/immudb/command.(*Commandline).Immudb.func1(0xc00021b680, {0xc00006bba0, 0x0, 0x2})
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/cmd/immudb/command/root.go:123 +0x28c
Dec 29 03:28:13 testing immudb[13437]: github.com/spf13/cobra.(*Command).execute(0xc00021b680, {0xc000032190, 0x2, 0x2})
Dec 29 03:28:13 testing immudb[13437]: github.com/spf13/[email protected]/command.go:856 +0x60e
Dec 29 03:28:13 testing immudb[13437]: github.com/spf13/cobra.(*Command).ExecuteC(0xc00021b680)
Dec 29 03:28:13 testing immudb[13437]: github.com/spf13/[email protected]/command.go:974 +0x3bc
Dec 29 03:28:13 testing immudb[13437]: github.com/spf13/cobra.(*Command).Execute(...)
Dec 29 03:28:13 testing immudb[13437]: github.com/spf13/[email protected]/command.go:902
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/cmd/immudb/command.Execute()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/cmd/immudb/command/cmd.go:54 +0x293
Dec 29 03:28:13 testing immudb[13437]: main.main()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/cmd/immudb/immudb.go:22 +0x17
Dec 29 03:28:13 testing immudb[13437]: goroutine 35 [select]:
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/watchers.(*WatchersHub).WaitFor(0xc002be4f90, 0x3, 0xc00007c420)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/watchers/watchers.go:128 +0x2b6
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store.(*ImmuStore).WaitForTx(...)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store/immustore.go:677
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store.(*indexer).doIndexing(0xc00261be00, 0x0)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store/indexer.go:279 +0xa5
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/embedded/store.(*indexer).resume
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store/indexer.go:224 +0xcf
Dec 29 03:28:13 testing immudb[13437]: goroutine 37 [select]:
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/watchers.(*WatchersHub).WaitFor(0xc0059522a0, 0x4, 0xc00007c660)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/watchers/watchers.go:128 +0x2b6
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store.(*ImmuStore).WaitForTx(...)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store/immustore.go:677
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store.(*indexer).doIndexing(0xc0053837a0, 0x0)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store/indexer.go:279 +0xa5
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/embedded/store.(*indexer).resume
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/embedded/store/indexer.go:224 +0xcf
Dec 29 03:28:13 testing immudb[13437]: goroutine 41 [chan receive]:
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.StartMetrics.func1()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/metrics.go:163 +0x8b
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/pkg/server.StartMetrics
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/metrics.go:161 +0xe5
Dec 29 03:28:13 testing immudb[13437]: goroutine 45 [IO wait]:
Dec 29 03:28:13 testing immudb[13437]: internal/poll.runtime_pollWait(0x7f16512e8648, 0x72)
Dec 29 03:28:13 testing immudb[13437]: runtime/netpoll.go:234 +0x89
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*pollDesc).wait(0xc0000ba480, 0x203002, 0x0)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_poll_runtime.go:84 +0x32
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*pollDesc).waitRead(...)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_poll_runtime.go:89
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*FD).Accept(0xc0000ba480)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_unix.go:402 +0x22c
Dec 29 03:28:13 testing immudb[13437]: net.(*netFD).accept(0xc0000ba480)
Dec 29 03:28:13 testing immudb[13437]: net/fd_unix.go:173 +0x35
Dec 29 03:28:13 testing immudb[13437]: net.(*TCPListener).accept(0xc006279ab8)
Dec 29 03:28:13 testing immudb[13437]: net/tcpsock_posix.go:140 +0x28
Dec 29 03:28:13 testing immudb[13437]: net.(*TCPListener).Accept(0xc006279ab8)
Dec 29 03:28:13 testing immudb[13437]: net/tcpsock.go:262 +0x3d
Dec 29 03:28:13 testing immudb[13437]: net/http.(*Server).Serve(0xc00011e0e0, {0x561ed7ca6d18, 0xc006279ab8})
Dec 29 03:28:13 testing immudb[13437]: net/http/server.go:3002 +0x394
Dec 29 03:28:13 testing immudb[13437]: net/http.(*Server).ListenAndServe(0xc00011e0e0)
Dec 29 03:28:13 testing immudb[13437]: net/http/server.go:2931 +0x7d
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.StartMetrics.func2()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/metrics.go:178 +0x33
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/pkg/server.StartMetrics
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/metrics.go:177 +0x308
Dec 29 03:28:13 testing immudb[13437]: goroutine 47 [syscall]:
Dec 29 03:28:13 testing immudb[13437]: os/signal.signal_recv()
Dec 29 03:28:13 testing immudb[13437]: runtime/sigqueue.go:169 +0x98
Dec 29 03:28:13 testing immudb[13437]: os/signal.loop()
Dec 29 03:28:13 testing immudb[13437]: os/signal/signal_unix.go:24 +0x19
Dec 29 03:28:13 testing immudb[13437]: created by os/signal.Notify.func1.1
Dec 29 03:28:13 testing immudb[13437]: os/signal/signal.go:151 +0x2c
Dec 29 03:28:13 testing immudb[13437]: goroutine 48 [chan receive]:
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.(*ImmuServer).installShutdownHandler.func1()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:748 +0x2c
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/pkg/server.(*ImmuServer).installShutdownHandler
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:747 +0xdd
Dec 29 03:28:13 testing immudb[13437]: goroutine 49 [IO wait]:
Dec 29 03:28:13 testing immudb[13437]: internal/poll.runtime_pollWait(0x7f16512e8818, 0x72)
Dec 29 03:28:13 testing immudb[13437]: runtime/netpoll.go:234 +0x89
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*pollDesc).wait(0xc0000ba280, 0x8, 0x0)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_poll_runtime.go:84 +0x32
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*pollDesc).waitRead(...)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_poll_runtime.go:89
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*FD).Accept(0xc0000ba280)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_unix.go:402 +0x22c
Dec 29 03:28:13 testing immudb[13437]: net.(*netFD).accept(0xc0000ba280)
Dec 29 03:28:13 testing immudb[13437]: net/fd_unix.go:173 +0x35
Dec 29 03:28:13 testing immudb[13437]: net.(*TCPListener).accept(0xc0002a0318)
Dec 29 03:28:13 testing immudb[13437]: net/tcpsock_posix.go:140 +0x28
Dec 29 03:28:13 testing immudb[13437]: net.(*TCPListener).Accept(0xc0002a0318)
Dec 29 03:28:13 testing immudb[13437]: net/tcpsock.go:262 +0x3d
Dec 29 03:28:13 testing immudb[13437]: google.golang.org/grpc.(*Server).Serve(0xc0002aa1c0, {0x561ed7ca6d18, 0xc0002a0318})
Dec 29 03:28:13 testing immudb[13437]: google.golang.org/[email protected]/server.go:786 +0x362
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.(*ImmuServer).Start.func2()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:268 +0x32
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/pkg/server.(*ImmuServer).Start
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:267 +0x214
Dec 29 03:28:13 testing immudb[13437]: goroutine 50 [select]:
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/sessions.(*manager).StartSessionsGuard(0xc006292000)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/sessions/manager.go:158 +0xf0
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.(*ImmuServer).Start.func3()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:275 +0x3e
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/pkg/server.(*ImmuServer).Start
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:274 +0x285
Dec 29 03:28:13 testing immudb[13437]: goroutine 51 [IO wait]:
Dec 29 03:28:13 testing immudb[13437]: internal/poll.runtime_pollWait(0x7f16512e8730, 0x72)
Dec 29 03:28:13 testing immudb[13437]: runtime/netpoll.go:234 +0x89
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*pollDesc).wait(0xc0000ba300, 0x2, 0x0)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_poll_runtime.go:84 +0x32
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*pollDesc).waitRead(...)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_poll_runtime.go:89
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*FD).Accept(0xc0000ba300)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_unix.go:402 +0x22c
Dec 29 03:28:13 testing immudb[13437]: net.(*netFD).accept(0xc0000ba300)
Dec 29 03:28:13 testing immudb[13437]: net/fd_unix.go:173 +0x35
Dec 29 03:28:13 testing immudb[13437]: net.(*TCPListener).accept(0xc006279320)
Dec 29 03:28:13 testing immudb[13437]: net/tcpsock_posix.go:140 +0x28
Dec 29 03:28:13 testing immudb[13437]: net.(*TCPListener).Accept(0xc006279320)
Dec 29 03:28:13 testing immudb[13437]: net/tcpsock.go:262 +0x3d
Dec 29 03:28:13 testing immudb[13437]: golang.org/x/net/netutil.(*limitListener).Accept(0xc00631cfc0)
Dec 29 03:28:13 testing immudb[13437]: golang.org/x/[email protected]/netutil/listen.go:48 +0x3e
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server.(*srv).Serve(0xc0002acbe0)
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/pgsql/server/server.go:96 +0x18b
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.(*ImmuServer).Start.func4()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:284 +0xbd
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/pkg/server.(*ImmuServer).Start
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/server.go:282 +0x2e5
Dec 29 03:28:13 testing immudb[13437]: goroutine 52 [IO wait]:
Dec 29 03:28:13 testing immudb[13437]: internal/poll.runtime_pollWait(0x7f16512e8560, 0x72)
Dec 29 03:28:13 testing immudb[13437]: runtime/netpoll.go:234 +0x89
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*pollDesc).wait(0xc008e7a900, 0x4, 0x0)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_poll_runtime.go:84 +0x32
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*pollDesc).waitRead(...)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_poll_runtime.go:89
Dec 29 03:28:13 testing immudb[13437]: internal/poll.(*FD).Accept(0xc008e7a900)
Dec 29 03:28:13 testing immudb[13437]: internal/poll/fd_unix.go:402 +0x22c
Dec 29 03:28:13 testing immudb[13437]: net.(*netFD).accept(0xc008e7a900)
Dec 29 03:28:13 testing immudb[13437]: net/fd_unix.go:173 +0x35
Dec 29 03:28:13 testing immudb[13437]: net.(*TCPListener).accept(0xc0061fb680)
Dec 29 03:28:13 testing immudb[13437]: net/tcpsock_posix.go:140 +0x28
Dec 29 03:28:13 testing immudb[13437]: net.(*TCPListener).Accept(0xc0061fb680)
Dec 29 03:28:13 testing immudb[13437]: net/tcpsock.go:262 +0x3d
Dec 29 03:28:13 testing immudb[13437]: net/http.(*Server).Serve(0xc006d40b60, {0x561ed7ca6d18, 0xc0061fb680})
Dec 29 03:28:13 testing immudb[13437]: net/http/server.go:3002 +0x394
Dec 29 03:28:13 testing immudb[13437]: net/http.(*Server).ListenAndServe(0xc006d40b60)
Dec 29 03:28:13 testing immudb[13437]: net/http/server.go:2931 +0x7d
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server.StartWebServer.func1()
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/webserver.go:38 +0x16d
Dec 29 03:28:13 testing immudb[13437]: created by github.com/codenotary/immudb/pkg/server.StartWebServer
Dec 29 03:28:13 testing immudb[13437]: github.com/codenotary/immudb/pkg/server/webserver.go:31 +0x233
Dec 29 03:28:13 testing systemd[1]: immudb.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Dec 29 03:28:13 testing systemd[1]: immudb.service: Failed with result 'exit-code'.
thanks a lot @grawlinson for reporting this issue
Fixed.