Shell `local' leads to memory leak
Table of Contents
1 description
When I analysis a shell script in Openwrt which leads to memory leak.
I found that the local command made it happen.
shell version:
root@AP-1A:B0:~# /bin/sh --version BusyBox v1.23.2 (2017-06-09 06:54:32 CST) built-in shell (ash)
2 test
2.1 test with local
The test script as below:
#!/bin/sh while [ "1"="1" ] do local len=1 done
test steps:
root@AP-1A:B0:~# ./bb.sh & root@AP-1A:B0:~# ps | grep bb.sh 29434 root 10428 R {bb.sh} /bin/sh ./bb.sh 29620 root 1348 S grep bb.sh root@AP-1A:B0:~# ps | grep bb.sh 29434 root 16660 R {bb.sh} /bin/sh ./bb.sh 29690 root 1348 S grep bb.sh
As we can see, the VmSize increase rapidly.
2.2 test without local
The test script as below:
#!/bin/sh while [ "1"="1" ] do len=1 done
test steps:
root@AP-1A:B0:~# ./bb.sh & root@AP-1A:B0:~# ps | grep bb.sh 32170 root 1352 R {bb.sh} /bin/sh ./bb.sh 32204 root 1348 S grep bb.sh root@AP-1A:B0:~# ps | grep bb.sh 32170 root 1352 R {bb.sh} /bin/sh ./bb.sh 32233 root 1348 S grep bb.sh
As we can see the VmSize stay the same.
3 reason
I got the definiton from GNU bash handbook:
local local [option] name[=value] ... For each argument, a local variable named name is created, and assigned value. The option can be any of the options accepted by declare. local can only be used within a function; it makes the variable name have a visible scope restricted to that function and its children. The return status is zero unless local is used outside a function, an invalid name is supplied, or name is a readonly variable.
So the reason is that the undefined behavior of local used in while (not
in a function) leads to memory leak issue.
4 fix
remove the local command.