• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2002
4  *   Copyright (c) 2012 Cyril Hrubis <chrubis@suse.cz>
5  *
6  *   This program is free software;  you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14  *   the GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program;  if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /* IBM Corporation */
22 /* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
23 /* 10/30/2002	Port to LTP	dbarrera@us.ibm.com */
24 
25 /*======================================================================
26 /	=================== TESTPLAN SEGMENT ===================
27 >KEYS:	< calloc, malloc, free, realloc, valloc
28 >WHAT:	< check that memory can be allocated and freed. check for zeroed
29    	< memory.
30 >HOW:	< Allocate a big chunk of memory, verify it is available (zeroed
31 	< in the case of calloc).
32 	< Write into it and verify, free memory and verify free was
33 	< successful.
34 	< In the case of valloc, allocate memory and free it (do this for
35 	< several iterations). Check if valloc returns unaligned pointers.
36 	< If valloc causes a SIGSEGV, that means a failure has occured.
37 >BUGS:	<
38 ======================================================================*/
39 
40 #include <stdio.h>
41 #include <signal.h>
42 #include <stdlib.h>
43 #include "test.h"
44 #include <unistd.h>
45 #include <errno.h>
46 #include <time.h>
47 #include <string.h>
48 #include <sys/types.h>
49 #include <sys/user.h>
50 
51 #define MEMSIZE	8192*8192
52 
53 void on_mem_fault(int sig);
54 
55 char *TCID = "mem02";
56 int TST_TOTAL = 1;
57 
usage(char * progname)58 static void usage(char *progname)
59 {
60 	fprintf(stderr, "usage: %s -m memsize\n", progname);
61 	fprintf(stderr, "\t-m specify the size of memory to allocate, in MB\n");
62 	exit(1);
63 }
64 
main(int argc,char ** argv)65 int main(int argc, char **argv)
66 {
67 	int i;
68 	char *pm1, *pm2, *pm3, *pm4;
69 	long pm6;
70 	void *memptr;
71 	long laddr;
72 	int iteration_count;
73 	int size;		/* Size to memory to be valloced */
74 	int pagesize = 12;	/* 2^12 = 4096, PAGESIZE      */
75 	int memsize = MEMSIZE;	/* Size of memory to allocate */
76 	extern char *optarg;	/* getopt() function global variables */
77 	extern int optopt;	/* stores bad option passed to the program */
78 	int ch;
79 
80 	optarg = NULL;
81 	opterr = 0;
82 
83 	while ((ch = getopt(argc, argv, "m:")) != -1) {
84 		switch (ch) {
85 		case 'm':
86 			if (optarg)
87 				memsize = atoi(optarg) * 1024 * 1024;
88 			else
89 				fprintf(stderr, "%s: option -%c requires "
90 					"an argument\n", argv[0], optopt);
91 			break;
92 		default:
93 			usage(argv[0]);
94 			exit(1);
95 		}
96 	}
97 
98 	/* check out calloc/free */
99 	if ((pm2 = pm1 = calloc(memsize, 1)) == NULL) {
100 
101 		tst_brkm(TFAIL, NULL, "calloc - alloc of %dMB failed",
102 			 memsize / 1024 / 1024);
103 	}
104 
105 	for (i = 0; i < memsize; i++)
106 		if (*pm2++ != 0) {
107 			tst_brkm(TFAIL, NULL,
108 				 "calloc returned non zero memory");
109 		}
110 
111 	pm2 = pm1;
112 	for (i = 0; i < memsize; i++)
113 		*pm2++ = 'X';
114 	pm2 = pm1;
115 	for (i = 0; i < memsize; i++)
116 		if (*pm2++ != 'X') {
117 			tst_brkm(TFAIL, NULL,
118 				 "could not write/verify memory ");
119 		}
120 
121 	free(pm1);
122 
123 	tst_resm(TPASS, "calloc - calloc of %uMB of memory succeeded",
124 		 memsize / 1024 / 1024);
125 
126 /*--------------------------------------------------------------------*/
127 
128 	/* check out malloc/free */
129 	if ((pm2 = pm1 = malloc(memsize)) == NULL) {
130 		tst_brkm(TFAIL, NULL, "malloc did not alloc memory ");
131 	}
132 
133 	for (i = 0; i < memsize; i++)
134 		*pm2++ = 'X';
135 	pm2 = pm1;
136 	for (i = 0; i < memsize; i++)
137 		if (*pm2++ != 'X') {
138 			tst_brkm(TFAIL, NULL,
139 				 "could not write/verify memory ");
140 		}
141 
142 	free(pm1);
143 
144 	tst_resm(TPASS, "malloc - malloc of %uMB of memory succeeded",
145 		 memsize / 1024 / 1024);
146 
147 /*--------------------------------------------------------------------*/
148 
149 	/* check out realloc */
150 
151 	pm4 = pm3 = malloc(10);
152 	for (i = 0; i < 10; i++)
153 		*pm4++ = 'X';
154 
155 	/* realloc with reduced size */
156 	pm4 = realloc(pm3, 5);
157 	pm6 = (long)pm4;
158 	pm3 = pm4;
159 	/* verify contents did not change */
160 	for (i = 0; i < 5; i++) {
161 		if (*pm4++ != 'X') {
162 			tst_brkm(TFAIL, NULL,
163 				 "realloc changed memory contents");
164 		}
165 	}
166 
167 	tst_resm(TPASS, "realloc - realloc of 5 bytes succeeded");
168 
169 	/* realloc with increased size after fragmenting memory */
170 	pm4 = realloc(pm3, 15);
171 	pm6 = (long)pm3;
172 	pm3 = pm4;
173 	/* verify contents did not change */
174 	for (i = 0; i < 5; i++) {
175 		if (*pm3++ != 'X') {
176 			tst_brkm(TFAIL, NULL,
177 				 "realloc changed memory contents");
178 		}
179 	}
180 
181 	tst_resm(TPASS, "realloc - realloc of 15 bytes succeeded");
182 	free(pm4);
183 
184 /*--------------------------------------------------------------------*/
185 	/*
186 	 * Check out for valloc failures
187 	 */
188 
189 	/*
190 	 * Setup to catch the memory fault, otherwise the core might
191 	 * be dumped on failures.
192 	 */
193 	if ((signal(SIGSEGV, on_mem_fault)) == SIG_ERR) {
194 		tst_brkm(TFAIL, NULL,
195 			 "Could not get signal handler for SIGSEGV");
196 	}
197 
198 	srand(1);		/* Ensure Determinism         */
199 
200 	for (iteration_count = 15000; iteration_count > 0; iteration_count--) {
201 		/*
202 		 * size is a fraction of 100000 and is determined by rand().
203 		 */
204 		size = (int)((rand() / (float)RAND_MAX) * 100000) + 1;
205 		memptr = valloc(size);
206 
207 		/*
208 		 * Check to see if valloc returns unaligned data.
209 		 * This can be done by copying the memory address into
210 		 * a variable and the by diving and multipying the address
211 		 * by the pagesize and checking.
212 		 */
213 		laddr = (long)memptr;
214 		if (((laddr >> pagesize) << pagesize) != laddr) {
215 			tst_brkm(TFAIL, NULL,
216 				 "Valloc returned unaligned data");
217 		}
218 
219 		free(memptr);
220 	}
221 
222 	tst_exit();
223 }
224 
225 /*
226  * void
227  * on_mem_fault(int sig)
228  *
229  *	on_mem_fault() is a signal handler used by the valloc test-case
230  *	(block 3). This function will catch the signal, indicate a failure,
231  *	write to the log file (a failure message) and exit the test.
232  */
on_mem_fault(int sig)233 void on_mem_fault(int sig)
234 {
235 	tst_brkm(TFAIL, NULL, "\tTest failed on receipt of a SIGSEGV signal");
236 }
237