最近所參與開發的linux系統發生了,死機的情形. http 還可連入, 但整個動作非常的慢.
在console mode下, 打 top 命令也非常慢才出現, 而看不到任何一支程式吃掉CPU,
但system CPU 佔全部的 80% 以上. 之後再仔細看到memory free剩非常的少(跟剛開機的時侯相比)
故而懷疑是 memory leak 導致的, 於是寫了一支程式去吃記憶體, 複製發生異常時,情形是否一致.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
void main(){
printf("this program will eat memory 1M every 10 seconds\n");
int i = 0;
while (1){
i++;
sleep(10);
if (i<= 50) {
char* leak_mem;
leak_mem = malloc (1024*1024);
int iValue = i % 256;
memset(leak_mem,iValue,1024*1024);
int j=0;
for ( j=0; j< 1024*1024; j++)
{
leak_mem[j] = (iValue+j) % 256;
}
printf("%d. eat 1M memory now ... %d %d ~ %d %d \n", i,leak_mem[0],leak_mem[1],leak_mem[1024*1024-2],leak_mem[1024*1024-1]);
}
printf("this program will eat memory 1M every 10 seconds\n");
int i = 0;
while (1){
i++;
sleep(10);
if (i<= 50) {
char* leak_mem;
leak_mem = malloc (1024*1024);
int iValue = i % 256;
memset(leak_mem,iValue,1024*1024);
int j=0;
for ( j=0; j< 1024*1024; j++)
{
leak_mem[j] = (iValue+j) % 256;
}
printf("%d. eat 1M memory now ... %d %d ~ %d %d \n", i,leak_mem[0],leak_mem[1],leak_mem[1024*1024-2],leak_mem[1024*1024-1]);
}
}
printf("this program exit now \n");
}
printf("this program exit now \n");
}
由於Linux如果將吃掉記憶的程式砍掉的話, 其記憶體還是會被釋放回來, 故而當吃掉一定程度的記憶體之後, 即開始休息(不要離開程式, 否則會釋放回去). 另外allocate的記憶體須要memset,才會真的使用到.
可以用來看系統CPU分配的情形, 可以經由top 中的Load average, 其欄位分別記錄著過去時間有多少程式須共用一個CPU, 分別是1/5/15 分鐘. 也可經由下列指令得知 cat /proc/loadavg
另外top也可以有不同的排序方式 N/M/P/T (show CPU usage, sort by pid/mem/cpu/time) . 而top 也能看到記憶使用的仔細情形 ( S: show memory), 可以觀察到VSZ RSS 的使用情形.
想要得知某一程式有多少執行緒正在執行, 命令如下:
ps -T | grep process-name
如果要得知wis-stream 有多少個執行緒在執行, 則範例如下(除了主程式外還有四個子執行緒):
#
# ps -T | grep wis-stream
1376 root 56:19 /bin/wis-streamer
1377 root 0:01 /bin/wis-streamer
1378 root 0:00 /bin/wis-streamer
1379 root 0:00 /bin/wis-streamer
1380 root 0:00 /bin/wis-streamer
15792 root 0:00 grep wis-stream
#
#
# ps -T | grep wis-stream
1376 root 56:19 /bin/wis-streamer
1377 root 0:01 /bin/wis-streamer
1378 root 0:00 /bin/wis-streamer
1379 root 0:00 /bin/wis-streamer
1380 root 0:00 /bin/wis-streamer
15792 root 0:00 grep wis-stream
#
而要查看某一執行緒(pid) , 有執行那些 system call 的指令會特別佔用記憶體, 則用下列命令去查詢:
strace -c -p PidOfThread
strace此會attech 到此pid ,直到你中斷它的執行(Ctrl-C), 如要看上述wis-streamer的情形如下:
# strace -c -p 1376
Process 1376 attached - interrupt to quit
^CProcess 1376 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
97.10 0.220000 280 785 select
2.90 0.006581 3 2501 gettimeofday
------ ----------- ----------- --------- --------- ----------------
100.00 0.226581 3286 total
#
Process 1376 attached - interrupt to quit
^CProcess 1376 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
97.10 0.220000 280 785 select
2.90 0.006581 3 2501 gettimeofday
------ ----------- ----------- --------- --------- ----------------
100.00 0.226581 3286 total
#
可以得知大部分的CPU 都在執行select 這個system call 上面.
那些命令屬於 system call , 可以查詢下列網址 Linux System Call Table
要看記憶體使用的情形, 可以用下列命令:
free -m
cat /proc/meminfo
top (執行之後再按大寫 S)
pidstat -r 10 -p ALL
其中以 pidstat 較好用, 它可以看到所有程式佔用記憶體的情形
# pidstat -r 10 -p ALL
Linux 2.6.38.8 (VN-H228) 11/18/14 _armv6l_ (1 CPU)
Linux 2.6.38.8 (VN-H228) 11/18/14 _armv6l_ (1 CPU)
11:37:17 PID minflt/s majflt/s VSZ RSS %MEM Command
11:37:28 1 0.00 0.00 3272 700 0.66 linuxrc
11:37:28 823 0.00 0.00 2532 968 0.91 check_daemon
11:37:28 826 0.00 0.00 3784 1164 1.09 syslogd
11:37:28 828 0.00 0.00 3276 660 0.62 logger
11:37:28 830 0.00 0.00 12224 1476 1.39 topbus
11:37:28 837 0.10 0.00 60608 2988 2.81 topservice
11:37:28 842 0.00 0.00 3272 328 0.31 telnetd
11:37:28 843 0.00 0.00 3276 728 0.68 sh
11:37:28 874 0.00 0.00 0 0 0.00 loop0
11:37:28 875 0.00 0.00 0 0 0.00 ext4-dio-unwrit
11:37:28 943 0.00 0.00 0 0 0.00 dsplogd
11:37:28 944 0.00 0.00 0 0 0.00 vsyncd
11:37:28 958 0.00 0.00 0 0 0.00 hdmid
11:37:28 967 0.00 0.00 279680 1324 1.24 capture_server
11:37:28 979 0.00 0.00 164904 1056 0.99 encode_server
11:37:28 982 0.00 0.00 69304 1704 1.60 tv_3a_service
11:37:28 989 0.00 0.00 30872 3992 3.75 jackd
11:37:28 1028 0.00 0.00 18716 800 0.75 check_auth
11:37:28 1033 0.00 0.00 2300 672 0.63 detection
11:37:28 1036 0.00 0.00 2676 1128 1.06 fget
11:37:28 1039 0.00 0.00 2292 556 0.52 fset
11:37:28 1041 0.00 0.00 18596 848 0.80 ieee8021x
11:37:28 1104 0.00 0.00 2436 780 0.73 yaweb
11:37:28 1120 0.00 0.00 60444 788 0.74 ftp_service
11:37:28 1122 0.00 0.00 60460 712 0.67 email_service
11:37:28 1124 0.00 0.00 18388 540 0.51 sd_service
11:37:28 1126 0.00 0.00 43256 968 0.91 event_service
11:37:28 1155 0.00 0.00 30128 1136 1.07 subscriberman
11:37:28 1157 0.10 0.00 26668 760 0.71 tv_wsdiscovery
11:37:28 1159 0.00 0.00 1868 412 0.39 dbgsvr
11:37:28 1161 0.00 0.00 18392 620 0.58 FocusAssist
11:37:28 1163 0.00 0.00 18396 620 0.58 alarmserver
11:37:28 1169 0.00 0.00 18428 564 0.53 scan_port
11:37:28 1171 0.00 0.00 48360 2324 2.18 audio_server
11:37:28 1173 0.00 0.00 23780 2180 2.05 jvc_audio_clien
11:37:28 1175 0.00 0.00 40176 2212 2.08 audio_read
11:37:28 1204 0.00 0.00 21800 492 0.46 subscriberman
11:37:28 1213 0.00 0.00 18500 664 0.62 jvc_search
11:37:28 1234 0.00 0.00 18500 664 0.62 jvc_search
11:37:28 1246 0.29 0.00 12072 4008 3.77 upnpd
11:37:28 1272 0.00 0.00 43020 796 0.75 rtsp_client
11:37:28 1281 0.00 0.00 10204 624 0.59 ipfinder
11:37:28 1316 0.00 0.00 24604 4176 3.92 snmpd
11:37:28 1376 0.00 0.00 93700 1828 1.72 wis-streamer
11:37:28 1619 0.00 0.00 5736 2032 1.91 lighttpd
11:37:28 1660 0.00 0.00 79444 1972 1.85 rtsp_over_http
11:37:28 1774 0.00 0.00 82516 1808 1.70 rtsp_over_http
11:37:28 6321 0.00 0.00 0 0 0.00 kworker/0:0
11:37:28 7513 0.00 0.00 0 0 0.00 kworker/0:4
11:37:28 15898 0.00 0.00 0 0 0.00 flush-ubifs_0_0
11:37:28 15899 0.00 0.00 0 0 0.00 flush-7:0
11:37:28 1 0.00 0.00 3272 700 0.66 linuxrc
11:37:28 823 0.00 0.00 2532 968 0.91 check_daemon
11:37:28 826 0.00 0.00 3784 1164 1.09 syslogd
11:37:28 828 0.00 0.00 3276 660 0.62 logger
11:37:28 830 0.00 0.00 12224 1476 1.39 topbus
11:37:28 837 0.10 0.00 60608 2988 2.81 topservice
11:37:28 842 0.00 0.00 3272 328 0.31 telnetd
11:37:28 843 0.00 0.00 3276 728 0.68 sh
11:37:28 874 0.00 0.00 0 0 0.00 loop0
11:37:28 875 0.00 0.00 0 0 0.00 ext4-dio-unwrit
11:37:28 943 0.00 0.00 0 0 0.00 dsplogd
11:37:28 944 0.00 0.00 0 0 0.00 vsyncd
11:37:28 958 0.00 0.00 0 0 0.00 hdmid
11:37:28 967 0.00 0.00 279680 1324 1.24 capture_server
11:37:28 979 0.00 0.00 164904 1056 0.99 encode_server
11:37:28 982 0.00 0.00 69304 1704 1.60 tv_3a_service
11:37:28 989 0.00 0.00 30872 3992 3.75 jackd
11:37:28 1028 0.00 0.00 18716 800 0.75 check_auth
11:37:28 1033 0.00 0.00 2300 672 0.63 detection
11:37:28 1036 0.00 0.00 2676 1128 1.06 fget
11:37:28 1039 0.00 0.00 2292 556 0.52 fset
11:37:28 1041 0.00 0.00 18596 848 0.80 ieee8021x
11:37:28 1104 0.00 0.00 2436 780 0.73 yaweb
11:37:28 1120 0.00 0.00 60444 788 0.74 ftp_service
11:37:28 1122 0.00 0.00 60460 712 0.67 email_service
11:37:28 1124 0.00 0.00 18388 540 0.51 sd_service
11:37:28 1126 0.00 0.00 43256 968 0.91 event_service
11:37:28 1155 0.00 0.00 30128 1136 1.07 subscriberman
11:37:28 1157 0.10 0.00 26668 760 0.71 tv_wsdiscovery
11:37:28 1159 0.00 0.00 1868 412 0.39 dbgsvr
11:37:28 1161 0.00 0.00 18392 620 0.58 FocusAssist
11:37:28 1163 0.00 0.00 18396 620 0.58 alarmserver
11:37:28 1169 0.00 0.00 18428 564 0.53 scan_port
11:37:28 1171 0.00 0.00 48360 2324 2.18 audio_server
11:37:28 1173 0.00 0.00 23780 2180 2.05 jvc_audio_clien
11:37:28 1175 0.00 0.00 40176 2212 2.08 audio_read
11:37:28 1204 0.00 0.00 21800 492 0.46 subscriberman
11:37:28 1213 0.00 0.00 18500 664 0.62 jvc_search
11:37:28 1234 0.00 0.00 18500 664 0.62 jvc_search
11:37:28 1246 0.29 0.00 12072 4008 3.77 upnpd
11:37:28 1272 0.00 0.00 43020 796 0.75 rtsp_client
11:37:28 1281 0.00 0.00 10204 624 0.59 ipfinder
11:37:28 1316 0.00 0.00 24604 4176 3.92 snmpd
11:37:28 1376 0.00 0.00 93700 1828 1.72 wis-streamer
11:37:28 1619 0.00 0.00 5736 2032 1.91 lighttpd
11:37:28 1660 0.00 0.00 79444 1972 1.85 rtsp_over_http
11:37:28 1774 0.00 0.00 82516 1808 1.70 rtsp_over_http
11:37:28 6321 0.00 0.00 0 0 0.00 kworker/0:0
11:37:28 7513 0.00 0.00 0 0 0.00 kworker/0:4
11:37:28 15898 0.00 0.00 0 0 0.00 flush-ubifs_0_0
11:37:28 15899 0.00 0.00 0 0 0.00 flush-7:0
如果有那支程式的RSS欄位一直在增長, 則表示此程序有可能是造成memory leak的元凶.此處不能光看VSZ欄位, 因為VSZ 有可能只是allocate memory, 但並沒有真的使用它.
而RSS欄位的增長有時是因為使用到ShareMemory的關後, 所以要配合看free memory是否有減少, 才能正確判斷是否一直吃記憶體.
PS 2019/6/18: 如果採用ram拿來當linux aufs , 則檔案一直寫入增大的話, 會導致memory cache一直增大; 最後可用的記憶體會被吃光而當機. 所以不能有任何程式一直讓檔案變大.
另外, 試了 valgrind , 可以用來偵測 memory leak的問題. 但由於ld-uClibc-0.9.33.2.so 是stripped, 所以cross-compile之後無法有效偵測memory.
d-uClibc-0.9.33.2.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, stripped
2 - 不要使用完全剝離的Linux發行版/lib/ld.so。(比如上面的getoff-arm-linux 就連結了 /lib/ld-uClibc.so.0, 那就要求我們的開發板根目錄下的/lib/ld-uClibc.so.0 必須是 not stripped)
2 - 不要使用完全剝離的Linux發行版/lib/ld.so。(比如上面的getoff-arm-linux 就連結了 /lib/ld-uClibc.so.0, 那就要求我們的開發板根目錄下的/lib/ld-uClibc.so.0 必須是 not stripped)
refernce of valgrind as follow:
沒有留言:
張貼留言