On 01/07/2011 02:42 AM, Caspar Zhang wrote: > Hi Garrett, this is the *final* version, please review.
Hi, anybody have a chance to look at this patch? Thanks! Caspar > > On 01/07/2011 02:40 AM, [email protected] wrote: >> From: Caspar Zhang <[email protected]> >> >> We get segfaults during testing mtest01 on a 5TB memory machine, the >> problem was traced to the array pid_list[] went to overflow and >> corrupted memory. This fix makes pid_list dynamically sized with >> correct memory size to avoid overflow. >> >> v2: not split into different bits when allocating pid_list. >> v3: 1) fix optargs: -b and -p should not be used at the same time. >> 2) pre_mem maybe not initialized before using if -p option not used. >> fix it by moving it outside ``if(maxpercent)'' block. >> v4: fix code format. >> >> Signed-off-by: Caspar Zhang <[email protected]> >> --- >> testcases/kernel/mem/mtest01/mtest01.c | 409 >> +++++++++++++++++--------------- >> 1 files changed, 215 insertions(+), 194 deletions(-) >> >> diff --git a/testcases/kernel/mem/mtest01/mtest01.c >> b/testcases/kernel/mem/mtest01/mtest01.c >> index aee0d51..94b429a 100644 >> --- a/testcases/kernel/mem/mtest01/mtest01.c >> +++ b/testcases/kernel/mem/mtest01/mtest01.c >> @@ -44,223 +44,244 @@ >> >> #include "test.h" >> >> +#define FIVE_HUNDRED_KB (unsigned long long)(500*1024*1024) >> +#define ONE_MEGABYTE (unsigned long long)(1024*1024*1024) >> +#define THREE_MEGABYTES (unsigned long long)(3*ONE_MEGABYTE) >> + >> char *TCID = "mtest01"; >> int TST_TOTAL = 1; >> - >> int pid_count = 0; >> >> void handler(int signo) >> { >> - pid_count++; >> + pid_count++; >> } >> >> -int main(int argc, char* argv[]) { >> - char* mem; >> - float percent; >> - unsigned int maxpercent=0, dowrite=0, verbose=0, j, c; >> - unsigned long bytecount, alloc_bytes; >> - unsigned long long original_maxbytes,maxbytes=0; >> - unsigned long long pre_mem, post_mem; >> - extern char* optarg; >> - int chunksize = 1024*1024; /* one meg at a time by default */ >> - struct sysinfo sstats; >> - int i,pid_cntr; >> - pid_t pid,pid_list[1000]; >> - struct sigaction act; >> - >> - act.sa_handler = handler; >> - act.sa_flags = 0; >> - sigemptyset(&act.sa_mask); >> - sigaction(SIGRTMIN, &act, 0); >> - >> - for (i=0;i<1000;i++) >> - pid_list[i]=(pid_t)0; >> - >> - while ((c=getopt(argc, argv, "c:b:p:wvh")) != EOF) { >> - switch((char)c) { >> - case 'c': >> - chunksize = atoi(optarg); >> - break; >> - case 'b': >> - maxbytes = atoll(optarg); >> - break; >> - case 'p': >> - maxpercent = atoi(optarg); >> - if (maxpercent <= 0) { >> - tst_resm(TFAIL, "ERROR: -p option requires number greater than 0"); >> - exit(1);} >> - if (maxpercent > 99) { >> - tst_resm(TFAIL, "ERROR: -p option cannot be greater than 99"); >> - exit(1);} >> - break; >> - case 'w': >> - dowrite = 1; >> - break; >> - case 'v': >> - verbose = 1; >> - break; >> - case 'h': >> - default: >> - printf("Usage: %s [-c <bytes>] [-b <bytes>|-p <percent>] [-v]\n", >> argv[0]); >> - printf("\t-c <num>\tsize of chunk in bytes to malloc on each >> pass\n"); >> - printf("\t-b <bytes>\tmaximum number of bytes to allocate before >> stopping\n"); >> - printf("\t-p <bytes>\tpercent of total memory used at which the >> program stops\n"); >> - printf("\t-w\t\twrite to the memory after allocating\n"); >> - printf("\t-v\t\tverbose\n"); >> - printf("\t-h\t\tdisplay usage\n"); >> - exit(-1); >> - } >> - } >> - >> - sysinfo(&sstats); >> - if (maxpercent) { >> +int main(int argc, char* argv[]) >> +{ >> + char* mem; >> + float percent; >> + unsigned int maxpercent = 0, dowrite = 0, verbose=0, j, c; >> + unsigned long bytecount, alloc_bytes, max_pids; >> + unsigned long long original_maxbytes, maxbytes = 0; >> + unsigned long long pre_mem, post_mem; >> unsigned long long total_ram, total_free, D, C; >> - percent=(float)maxpercent/100.00; >> - >> - total_ram=sstats.totalram; >> - total_ram=total_ram+sstats.totalswap; >> - >> - total_free=sstats.freeram; >> - total_free=total_free+sstats.freeswap; >> - >> - /* Total memory used needed to reach maxpercent */ >> - D = percent*(sstats.mem_unit*total_ram); >> - tst_resm(TINFO, "Total memory used needed to reach maxpercent = %llu >> kbytes", D/1024); >> - >> - /* Total memory already used */ >> - C = sstats.mem_unit*(total_ram-total_free); >> - tst_resm(TINFO, "Total memory already used on system = %llu kbytes", >> C/1024); >> + extern char* optarg; >> + int chunksize = 1024*1024; /* one meg at a time by default */ >> + struct sysinfo sstats; >> + int i, pid_cntr; >> + pid_t pid, *pid_list; >> + struct sigaction act; >> >> + act.sa_handler = handler; >> + act.sa_flags = 0; >> + sigemptyset(&act.sa_mask); >> + sigaction(SIGRTMIN, &act, 0); >> + >> + while ((c = getopt(argc, argv, "c:b:p:wvh")) != EOF) >> + { >> + switch((char)c) >> + { >> + case 'c': >> + chunksize = atoi(optarg); >> + break; >> + case 'b': >> + if (maxpercent != 0) { >> + tst_resm(TFAIL, "ERROR: -b option cannot be used with >> -p option at the same time"); >> + exit(1); >> + } >> + maxbytes = atoll(optarg); >> + break; >> + case 'p': >> + if (maxbytes != 0) { >> + tst_resm(TFAIL, "ERROR: -p option cannot be used with >> -b option at the same time"); >> + exit(1); >> + } >> + maxpercent = atoi(optarg); >> + if (maxpercent <= 0) { >> + tst_resm(TFAIL, "ERROR: -p option requires number >> greater than 0"); >> + exit(1); >> + } >> + if (maxpercent > 99) { >> + tst_resm(TFAIL, "ERROR: -p option cannot be greater >> than 99"); >> + exit(1); >> + } >> + break; >> + case 'w': >> + dowrite = 1; >> + break; >> + case 'v': >> + verbose = 1; >> + break; >> + case 'h': >> + default: >> + printf("Usage: %s [-c <bytes>] [-b <bytes>|-p <percent>] >> [-v]\n", argv[0]); >> + printf("\t-c <num>\tsize of chunk in bytes to malloc on >> each pass\n"); >> + printf("\t-b <bytes>\tmaximum number of bytes to allocate >> before stopping\n"); >> + printf("\t-p <bytes>\tpercent of total memory used at which >> the program stops\n"); >> + printf("\t-w\t\twrite to the memory after allocating\n"); >> + printf("\t-v\t\tverbose\n"); >> + printf("\t-h\t\tdisplay usage\n"); >> + exit(-1); >> + } >> + } >> + >> + sysinfo(&sstats); >> + total_ram = sstats.totalram + sstats.totalswap; >> + total_free = sstats.freeram + sstats.freeswap; >> /* Total Free Pre-Test RAM */ >> - pre_mem = sstats.mem_unit*total_free; >> - >> - /* Are we already using more than maxpercent? */ >> - if (C>D) { >> - tst_resm(TFAIL, "More memory than the maximum amount you specified is >> already being used"); >> - exit(1); >> + pre_mem = sstats.mem_unit * total_free; >> + max_pids = total_ram / (unsigned long)FIVE_HUNDRED_KB + 1; >> + >> + if ((pid_list = malloc(max_pids * sizeof(pid_t))) == NULL) >> + { >> + tst_resm(TBROK|TERRNO, "malloc failed."); >> + exit(1); >> } >> - else >> - pre_mem = sstats.mem_unit*total_free; >> + memset(pid_list, 0, max_pids * sizeof(pid_t)); >> + >> + /* Currently used memory */ >> + C = sstats.mem_unit * (total_ram - total_free); >> + tst_resm(TINFO, "Total memory already used on system = %llu kbytes", >> C/1024); >> + >> + if (maxpercent) >> + { >> + percent = (float)maxpercent / 100.00; >> >> - /* set maxbytes to the extra amount we want to allocate */ >> - maxbytes = D-C; >> - tst_resm(TINFO, "Filling up %d%% of ram which is %llu kbytes", >> maxpercent, maxbytes/1024); >> - } >> - original_maxbytes=maxbytes; >> - i=0; >> - pid_cntr=0; >> - pid=fork(); >> - if (pid != 0) >> - pid_cntr++; >> - pid_list[i]=pid; >> + /* Desired memory needed to reach maxpercent */ >> + D = percent * (sstats.mem_unit * total_ram); >> + tst_resm(TINFO, "Total memory used needed to reach maxpercent = >> %llu kbytes", D/1024); >> + >> + /* Are we already using more than maxpercent? */ >> + if (C > D) >> + { >> + tst_resm(TFAIL, "More memory than the maximum amount you >> specified is already being used"); >> + free(pid_list); >> + exit(1); >> + } >> + >> + /* set maxbytes to the extra amount we want to allocate */ >> + maxbytes = D - C; >> + tst_resm(TINFO, "Filling up %d%% of ram which is %llu kbytes", >> maxpercent, maxbytes/1024); >> + } >> + original_maxbytes = maxbytes; >> + i = 0; >> + pid_cntr = 0; >> + pid = fork(); >> + if (pid != 0) >> + pid_cntr++; >> + pid_list[i] = pid; >> >> #if defined (_s390_) /* s390's 31bit addressing requires smaller chunks */ >> -#define FIVE_HUNDRED_KB (500*1024*1024) >> -#define ONE_MEGABYTE (1024*1024*1024) >> -#define THREE_MEGABYTES (3*ONE_MEGABYTE) >> - while (pid != 0 && maxbytes > FIVE_HUNDRED_KB) >> - { >> - i++; >> - maxbytes -= FIVE_HUNDRED_KB; >> - pid = fork(); >> - if (pid != 0) { >> - pid_cntr++; >> - pid_list[i] = pid; >> + while (pid != 0 && maxbytes > FIVE_HUNDRED_KB) >> + { >> + i++; >> + maxbytes -= FIVE_HUNDRED_KB; >> + pid = fork(); >> + if (pid != 0) >> + { >> + pid_cntr++; >> + pid_list[i] = pid; >> + } >> } >> - } >> - if (maxbytes > FIVE_HUNDRED_KB) >> - alloc_bytes FIVE_HUNDRED_KB; >> - else >> - alloc_bytes = (unsigned long) maxbytes; >> - >> + if (maxbytes > FIVE_HUNDRED_KB) >> + alloc_bytes = FIVE_HUNDRED_KB; >> + else >> + alloc_bytes = (unsigned long) maxbytes; >> + >> #elif __WORDSIZE==32 >> - while (pid != 0 && maxbytes > ONE_MEGABYTE) >> - { >> - i++; >> - maxbytes -= ONE_MEGABYTE; >> - pid = fork(); >> - if (pid != 0) { >> - pid_cntr++; >> - pid_list[i]=pid; >> + while (pid != 0 && maxbytes > ONE_MEGABYTE) >> + { >> + i++; >> + maxbytes -= ONE_MEGABYTE; >> + pid = fork(); >> + if (pid != 0) >> + { >> + pid_cntr++; >> + pid_list[i]=pid; >> + } >> } >> - } >> - if (maxbytes > ONE_MEGABYTE) >> - alloc_bytes = ONE_MEGABYTE; >> - else >> - alloc_bytes = (unsigned long)maxbytes; >> - >> + if (maxbytes > ONE_MEGABYTE) >> + alloc_bytes = ONE_MEGABYTE; >> + else >> + alloc_bytes = (unsigned long)maxbytes; >> + >> #elif __WORDSIZE==64 >> - while (pid!=0 && maxbytes > THREE_MEGABYTES) >> - { >> - i++; >> - maxbytes -= THREE_MEGABYTES; >> - pid=fork(); >> - if (pid != 0) { >> - pid_cntr++; >> - pid_list[i] = pid; >> - } >> - } >> - if (maxbytes > THREE_MEGABYTES) >> - alloc_bytes = THREE_MEGABYTES; >> - else >> - alloc_bytes = maxbytes; >> -#endif >> - >> - if (pid == 0) /** CHILD **/ >> - { >> - bytecount=chunksize; >> - while (1) { >> - if ((mem = (char*)malloc(chunksize)) == NULL) { >> - tst_resm(TINFO, "stopped at %lu bytes", bytecount); >> - exit(1); >> - } >> - if (dowrite) >> - for (j=0; j<chunksize; j++) >> - *(mem+j)='a'; >> - if (verbose) >> - tst_resm(TINFO, "allocated %lu bytes chunksize is %d", bytecount, >> chunksize); >> - bytecount+=chunksize; >> - if (alloc_bytes && (bytecount >= alloc_bytes)) >> - break; >> + while (pid!=0 && maxbytes > THREE_MEGABYTES) >> + { >> + i++; >> + maxbytes -= THREE_MEGABYTES; >> + pid = fork(); >> + if (pid != 0) >> + { >> + pid_cntr++; >> + pid_list[i] = pid; >> + } >> } >> - if (dowrite) >> - tst_resm(TINFO, "... %lu bytes allocated and used.", bytecount); >> + if (maxbytes > THREE_MEGABYTES) >> + alloc_bytes = THREE_MEGABYTES; >> else >> - tst_resm(TINFO, "... %lu bytes allocated only.", bytecount); >> - kill(getppid(),SIGRTMIN); >> - while (1) >> - sleep(1); >> - } >> - else /** PARENT **/ >> - { >> - >> - i=0; >> - sysinfo(&sstats); >> + alloc_bytes = maxbytes; >> +#endif >> >> - if (dowrite) >> + if (pid == 0) /** CHILD **/ >> { >> - /* Total Free Post-Test RAM */ >> - post_mem = (unsigned long long)sstats.mem_unit*sstats.freeram; >> - post_mem = post_mem+((unsigned long >> long)sstats.mem_unit*sstats.freeswap); >> - >> - while ((((unsigned long long)pre_mem - post_mem) < (unsigned long >> long)original_maxbytes) && >> - (pid_count < pid_cntr) ) >> - { >> - sleep(1); >> - sysinfo(&sstats); >> - post_mem = (unsigned long long)sstats.mem_unit*sstats.freeram; >> - post_mem = post_mem+((unsigned long >> long)sstats.mem_unit*sstats.freeswap); >> - } >> + bytecount = chunksize; >> + while (1) >> + { >> + if ((mem = malloc(chunksize)) == NULL) >> + { >> + tst_resm(TBROK|TERRNO, "stopped at %lu bytes", bytecount); >> + free(pid_list); >> + exit(1); >> + } >> + if (dowrite) >> + for (j = 0; j < chunksize; j++) >> + *(mem+j) = 'a'; >> + if (verbose) >> + tst_resm(TINFO, "allocated %lu bytes chunksize is %d", >> bytecount, chunksize); >> + bytecount += chunksize; >> + if (alloc_bytes && bytecount >= alloc_bytes) >> + break; >> + } >> + if (dowrite) >> + tst_resm(TINFO, "... %lu bytes allocated and used.", bytecount); >> + else >> + tst_resm(TINFO, "... %lu bytes allocated only.", bytecount); >> + kill(getppid(), SIGRTMIN); >> + while (1) >> + sleep(1); >> } >> - while (pid_list[i]!=0) >> + else /** PARENT **/ >> { >> - kill(pid_list[i],SIGKILL); >> - i++; >> + i = 0; >> + sysinfo(&sstats); >> + >> + if (dowrite) >> + { >> + /* Total Free Post-Test RAM */ >> + post_mem = (unsigned long long)sstats.mem_unit * sstats.freeram; >> + post_mem = post_mem + (unsigned long long)sstats.mem_unit * >> sstats.freeswap; >> + >> + while ((((unsigned long long)pre_mem - post_mem) < (unsigned >> long long)original_maxbytes) && >> + (pid_count < pid_cntr)) >> + { >> + sleep(1); >> + sysinfo(&sstats); >> + post_mem = (unsigned long long)sstats.mem_unit * >> sstats.freeram; >> + post_mem = post_mem + (unsigned long long)sstats.mem_unit * >> sstats.freeswap; >> + } >> + } >> + while (pid_list[i] != 0) >> + { >> + kill(pid_list[i], SIGKILL); >> + i++; >> + } >> + if (dowrite) >> + tst_resm(TPASS, "%llu kbytes allocated and used.", >> original_maxbytes/1024); >> + else >> + tst_resm(TPASS, "%llu kbytes allocated only.", >> original_maxbytes/1024); >> } >> - if (dowrite) >> - tst_resm(TPASS, "%llu kbytes allocated and used.", >> original_maxbytes/1024); >> - else >> - tst_resm(TPASS, "%llu kbytes allocated only.", >> original_maxbytes/1024); >> - } >> - exit(0); >> -} >> \ No newline at end of file >> + free(pid_list); >> + exit(0); >> +} > > -- Quality Assurance Associate (Kernel) in Red Hat Software (Beijing) Co., R&D Branch TEL: +86-10-62608150 WEB: http://www.redhat.com/ -- C-A-S-P-A-R, Caspar /kæspɑ:/ ;-) ------------------------------------------------------------------------------ Gaining the trust of online customers is vital for the success of any company that requires sensitive data to be transmitted over the Web. Learn how to best implement a security strategy that keeps consumers' information secure and instills the confidence they need to proceed with transactions. http://p.sf.net/sfu/oracle-sfdevnl _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
