最近在linux嵌入式平台上做nandflash的压力测试,即磨损均衡,通过dd工具生成一个大文件,然后测试程序去读取该文件的内容进行判断是否出现ECC校验错误,在测试程序内部出现了一个bug,测试程序每次使用dd 生成文件9次之后就会出现异常退出,具体log如下:
[root@szclou /mnt/app]#./flash_stress
read last total_cnt=47
****************************Start: total_cnt=47, cur_cnt=0***********************************
total used free shared buffers cached
Mem: 60140 16792 43348 0 1300 10796
-/+ buffers/cache: 4696 55444
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 3.4M 91.6M 4% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 27040 33100 0 1300 21040
-/+ buffers/cache: 4700 55440
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 12.7M 82.3M 13% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 37276 22864 0 1300 31284
-/+ buffers/cache: 4692 55448
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 22.8M 72.2M 24% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 47536 12604 0 1300 41528
-/+ buffers/cache: 4708 55432
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 33.0M 62.0M 35% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 57796 2344 0 1300 51772
-/+ buffers/cache: 4724 55416
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 43.2M 51.8M 45% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 58732 1408 0 300 53732
-/+ buffers/cache: 4700 55440
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 53.3M 41.7M 56% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 57832 2308 0 472 52620
-/+ buffers/cache: 4740 55400
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 63.5M 31.5M 67% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 57940 2200 0 188 53028
-/+ buffers/cache: 4724 55416
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 73.6M 21.4M 78% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 57712 2428 0 188 52792
-/+ buffers/cache: 4732 55408
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 83.8M 11.2M 88% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 57868 2272 0 188 52948
-/+ buffers/cache: 4732 55408
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 94.1M 940.0K 99% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
dd: writing '/mnt/data/stress-test-file': No space left on device
2+0 records in
0+1 records out
system-shell: dd if=/dev/zero of=/mnt/data/stress-test-file bs=1M count=10 error exit!!!
total used free shared buffers cached
Mem: 60140 57760 2380 0 268 52788
-/+ buffers/cache: 4704 55436
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 10.0M 40.0K 100% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 95.0M 40.0K 100% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
total 899
drwxr-xr-x 1 root root 2048 Dec 13 08:38 .
drwxr-xr-x 5 root root 0 Jan 1 1970 ..
d--------- 1 root root 2048 Dec 12 12:20 cfg
d--------- 1 root root 2048 Dec 12 12:20 data
drwx------ 1 root root 2048 Jan 1 1970 lost+found
d--------- 1 root root 2048 Dec 12 12:20 para
-rw-r--r-- 1 root root 909312 Dec 13 08:38 stress-test-file
-rwsr-sr-t 1 root root 4 Dec 13 07:59 total_cnt
write total_cnt=56
****************************End: total_cnt=56, cur_cnt=9***********************************
[root@szclou /mnt/app]#
通过log发现物理内存一直在减小,最后只剩下free=2380kb,我是在/mnt/data分区下进行的dd文件的生成,所以/dev/mtdblock7总大小为95M,最后只剩下40kb!!!最后发现是源码内部打开了dd生产的文件,而没有关闭,关闭之后内存、和分区的使用情况就正常了,测试程序不会在退出,修改后的log如下:
[root@szclou /mnt/app]#./flash_stress
read last total_cnt=56
****************************Start: total_cnt=56, cur_cnt=0***********************************
total used free shared buffers cached
Mem: 60140 14068 46072 0 1140 8228
-/+ buffers/cache: 4700 55440
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 6.8M 3.2M 68% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 3.5M 91.5M 4% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 23404 36736 0 1140 17580
-/+ buffers/cache: 4684 55456
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 6.8M 3.2M 68% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 12.7M 82.3M 13% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 23404 36736 0 1140 17580
-/+ buffers/cache: 4684 55456
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 6.8M 3.2M 68% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 12.9M 82.1M 14% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 23404 36736 0 1140 17580
-/+ buffers/cache: 4684 55456
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 6.8M 3.2M 68% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 13.1M 81.9M 14% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 23404 36736 0 1140 17580
-/+ buffers/cache: 4684 55456
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/root 5.4M 5.4M 0 100% /
devtmpfs 29.3M 0 29.3M 0% /dev
tmpfs 29.4M 0 29.4M 0% /dev/shm
tmpfs 29.4M 24.0K 29.3M 0% /tmp
tmpfs 29.4M 16.0K 29.3M 0% /run
/dev/mtdblock5 10.0M 6.8M 3.2M 68% /mnt/app
/dev/mtdblock6 8.0M 1.9M 6.1M 24% /mnt/ext
/dev/mtdblock7 95.0M 13.2M 81.8M 14% /mnt/data
tmpfs 1.0G 0 1.0G 0% /mnt/app/tmpfs_test
10+0 records in
10+0 records out
file size = 10M.
total used free shared buffers cached
Mem: 60140 23448 36692 0 1140 17580
-/+ buffers/cache: 4728 55412
Swap: 0 0 0
测试程序源码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef O_BINARY
#define O_BINARY 0
#endif
bool check_buf(char *p, char b,int len)
{
int i;
for (i=0; i<len; i++) {
if (p[i] != b){
printf("check_buf: error p[%d]=%02x\n", i, p[i]);
return false;
}
}
return true;
}
int main(int argc, char *argv[])
{
struct stat st;
const static char *stress_abs_file = "/mnt/data/stress-test-file";
char cmd_dd[128];
char cmd_rm[128];
int default_count = 10; //默认10M
int default_bs = 1; //默认1M
int fd, idx, ret, total_cnt, cur_cnt;
char buf[1024];
memset(cmd_dd, 0, sizeof(cmd_dd));
sprintf(cmd_dd, "dd if=/dev/zero of=%s bs=%dM count=%d", stress_abs_file, default_bs, default_count);
memset(cmd_rm, 0, sizeof(cmd_rm));
sprintf(cmd_rm, "rm %s", stress_abs_file);
cur_cnt = 0;
total_cnt = 0;
if ((fd=open("/mnt/data/total_cnt", O_RDWR|O_BINARY|O_CREAT)) >= 0) {
if (read(fd, (char*)&total_cnt, sizeof(total_cnt))>=0){
printf("read last total_cnt=%d\n", total_cnt);
} else {
printf("read last total_cnt failure.\n");
}
close(fd);
} else {
printf("open /mnt/data/total_cnt failure.\n");
}
printf("****************************Start: total_cnt=%d, cur_cnt=%d***********************************\n", total_cnt, cur_cnt);
while (1) {
system("free");
system("df -h");
if (access(stress_abs_file, F_OK) == 0) {
ret = system(cmd_rm);
if (WIFEXITED(ret)) { //正常退出(指调用system函数后的返回值)
if (WEXITSTATUS(ret) == 0) {//正常退出 (指调用system函数内的shell的返回值)
;
} else {
printf("system-shell: %s error exit!!!\n", cmd_rm);
goto RET;
}
} else {
printf("system: %s error exit!!!\n", cmd_rm);
goto RET;
}
}
ret = system(cmd_dd);
if (WIFEXITED(ret)) { //正常退出(指调用system函数后的返回值)
if (WEXITSTATUS(ret) == 0) {//正常退出 (指调用system函数内的shell的返回值)
;
} else {
printf("system-shell: %s error exit!!!\n", cmd_dd);
system("free");
system("df -h");
system("ls -la /mnt/data/");
goto RET;
}
} else {
printf("system: %s error exit!!!\n", cmd_dd);
goto RET;
}
if (stat(stress_abs_file, &st)!=-1 && S_ISREG(st.st_mode)) {
if ((fd=open(stress_abs_file, O_RDWR|O_BINARY)) > -1) {
printf("file size = %dM.\n", ((int)st.st_size+1)/(1024*1024));
idx = 0;
memset(buf, 0xff, sizeof(buf));
while ((ret=read(fd, buf, sizeof(buf))) > 0){
if (!check_buf(buf, 0x00, ret)) {
printf("Error: abort stress test!!!\n");
goto RET;
}
idx += ret;
if (idx >= (int)st.st_size){
total_cnt++;
cur_cnt++;
}
}
close(fd); //之前忘了关闭文件句柄,导致物理内存和/dev/mtdblock7一直申请,没有释放空间
} else {
printf("system: open %s error\n", cmd_dd);
}
} else {
printf("system: exec %s error\n", cmd_dd);
}
}
RET:
close(fd);
if ((fd=open("/mnt/data/total_cnt", O_RDWR|O_BINARY|O_CREAT)) >= 0) {
if (write(fd, (char*)&total_cnt, sizeof(total_cnt))>=0) {
printf("write total_cnt=%d\n", total_cnt);
} else {
printf("write total_cnt failure.\n");
}
close(fd);
} else {
printf("open /mnt/data/total_cnt failure.\n");
}
printf("****************************End: total_cnt=%d, cur_cnt=%d***********************************\n", total_cnt, cur_cnt);
return 0;
}
Makefile:
GCC = nuc972-arm-none-linux-gnueabi-gcc
FLAGS = -std=c99 -o
SRC = flash_stress.c
APP = flash_stress
all:
${GCC} ${FLAGS} ${APP} ${SRC}
clean:
rm -rf ${APP} *.o