1
+ /* ************************************************************************** */
2
+ /* */
3
+ /* ::: :::::::: */
4
+ /* brutalize.c :+: :+: :+: */
5
+ /* +:+ +:+ +:+ */
6
+ /* By: gpouyat <[email protected] > +#+ +:+ +#+ */
7
+ /* +#+#+#+#+#+ +#+ */
8
+ /* Created: 2017/11/30 18:05:32 by tvallee #+# #+# */
9
+ /* Updated: 2018/10/03 16:25:49 by gpouyat ### ########.fr */
10
+ /* */
11
+ /* ************************************************************************** */
12
+
13
+ #include "./includes/intern_malloc.h"
14
+ #include <stdbool.h>
15
+ #include <pthread.h>
16
+ #include <assert.h>
17
+ #include <string.h>
18
+ #include <stdio.h>
19
+
20
+ // Wrapper for define
21
+ #define TINY_SIZE_BRUT TINY_SIZE
22
+ #define MEDIUM_SIZE_BRUT MEDIUM_SIZE
23
+
24
+
25
+ /*
26
+ * ./brut -e => error
27
+ * ./brut -c => calloc
28
+ * ./brut -p => pthread
29
+ * ./brut -l => limit
30
+ */
31
+
32
+
33
+ void ft_putchar (char c )
34
+ {
35
+ write (STDOUT_FILENO , & c , 1 );
36
+ }
37
+
38
+ void ft_putstr (char const * str )
39
+ {
40
+ if (str )
41
+ write (1 , str , strlen (str ));
42
+ }
43
+
44
+ void ft_putendl (char const * str )
45
+ {
46
+ puts (str );
47
+ }
48
+
49
+ void ft_putnbr (int n )
50
+ {
51
+ unsigned int number ;
52
+
53
+ number = 0 ;
54
+ if (n < 0 )
55
+ {
56
+ ft_putchar ('-' );
57
+ number = - n ;
58
+ }
59
+ else
60
+ number = n ;
61
+ if (number >= 10 )
62
+ {
63
+ ft_putnbr (number / 10 );
64
+ ft_putnbr (number % 10 );
65
+ }
66
+ if (number < 10 )
67
+ ft_putchar (number + '0' );
68
+ }
69
+
70
+ typedef struct s_flag
71
+ {
72
+ bool quiet ;
73
+ bool calloc ;
74
+ size_t limit ;
75
+ bool pthread ;
76
+ int nbPthread ;
77
+ bool checkError ;
78
+ int align ;
79
+ } t_flag ;
80
+
81
+ typedef struct s_data
82
+ {
83
+ void * ptr ;
84
+ uint32_t size ;
85
+ } t_data ;
86
+
87
+ t_flag g_flag = {
88
+ false,
89
+ false,
90
+ 0 ,
91
+ false,
92
+ 2 ,
93
+ false,
94
+ 0
95
+ };
96
+
97
+ char g_type_map [3 ][6 ] = {"TINY" , "SMALL" , "LARGE" };
98
+
99
+
100
+ static uint32_t get_random_size (unsigned * type )
101
+ {
102
+ uint32_t ret ;
103
+
104
+ * type = arc4random_uniform (3 );
105
+ switch (* type )
106
+ {
107
+ case 0 :
108
+ ret = arc4random_uniform (TINY_SIZE_BRUT + 1 );
109
+ break ;
110
+ case 1 :
111
+ do {
112
+ ret = arc4random_uniform (MEDIUM_SIZE_BRUT + 1 );
113
+ } while (ret <= TINY_SIZE_BRUT );
114
+ break ;
115
+ case 2 :
116
+ do {
117
+ ret = arc4random_uniform (1024 * 1024 * 42 );
118
+ } while (ret <= MEDIUM_SIZE_BRUT );
119
+ break ;
120
+ }
121
+ return (ret );
122
+ }
123
+
124
+ static void fill_mem (t_data * current )
125
+ {
126
+ if (current -> ptr != NULL )
127
+ {
128
+ g_flag .quiet ? : ft_putstr ("=> filling available memory: " );
129
+ arc4random_buf (current -> ptr , current -> size );
130
+ g_flag .quiet ? : ft_putendl ("OK !" );
131
+ }
132
+ }
133
+
134
+ static void use_malloc (t_data * current , unsigned * type )
135
+ {
136
+ current -> size = get_random_size (type );
137
+
138
+ g_flag .quiet ? : ft_putstr (" malloc " );
139
+ g_flag .quiet ? : ft_putstr (g_type_map [* type ]);
140
+ g_flag .quiet ? : ft_putstr (" size " );
141
+ g_flag .quiet ? : ft_putnbr (current -> size );
142
+ g_flag .quiet ? : ft_putchar (10 );
143
+
144
+ current -> ptr = malloc (current -> size );
145
+ g_flag .align ? assert (!((long )current -> ptr % g_flag .align )): NULL ;
146
+
147
+ if (current -> ptr == NULL )
148
+ {
149
+ ft_putendl ("malloc returned NULL !" );
150
+ exit (1 );
151
+ }
152
+ }
153
+
154
+ static void use_calloc (t_data * current , unsigned * type )
155
+ {
156
+ size_t second_arg ;
157
+ current -> size = get_random_size (type );
158
+
159
+ if (arc4random_uniform (2 ) == 1 )
160
+ second_arg = arc4random_uniform (10 );
161
+ else
162
+ second_arg = 0 ;
163
+ g_flag .quiet ? : ft_putstr (" calloc " );
164
+ g_flag .quiet ? : ft_putstr (g_type_map [* type ]);
165
+ g_flag .quiet ? : ft_putstr (" size " );
166
+ g_flag .quiet ? : ft_putnbr (current -> size );
167
+ g_flag .quiet ? : ft_putstr (", " );
168
+ g_flag .quiet ? : ft_putnbr (second_arg );
169
+ g_flag .quiet ? : ft_putchar (10 );
170
+
171
+ current -> ptr = calloc (current -> size , second_arg );
172
+ g_flag .align ? assert (!((long )current -> ptr % g_flag .align )): NULL ;
173
+ current -> size = current -> size * second_arg ;
174
+ if (!current -> size )
175
+ current -> size = 1 ;
176
+ if (current -> ptr == NULL )
177
+ {
178
+ ft_putendl ("calloc returned NULL !" );
179
+ exit (1 );
180
+ }
181
+ }
182
+
183
+ void * brut (void * argv )
184
+ {
185
+ t_data table [200 ] = { {.ptr = NULL , .size = 0 } };
186
+ t_data * current ;
187
+ unsigned type ;
188
+ size_t count ;
189
+
190
+ (void )argv ;
191
+ count = 0 ;
192
+ g_flag .quiet ? : ft_putendl ("=========BEGIN BRUTALIZE=========" );
193
+ while (!g_flag .limit || count ++ < g_flag .limit )
194
+ {
195
+ g_flag .quiet ? : ft_putstr ("\n=> new iteration: " );
196
+
197
+ current = & (table [arc4random_uniform (200 )]);
198
+ if (current -> ptr == NULL )
199
+ g_flag .calloc ? use_calloc (current , & type ) : use_malloc (current , & type );
200
+ else {
201
+ switch (arc4random_uniform (5 ))
202
+ {
203
+ case 0 :
204
+ g_flag .quiet ? : ft_putendl ("free" );
205
+ free (current -> ptr );
206
+ current -> ptr = NULL ;
207
+ break ;
208
+ case 1 :
209
+ g_flag .quiet ? : ft_putstr ("realloc size: " );
210
+ g_flag .quiet ? : ft_putnbr (current -> size );
211
+ g_flag .quiet ? : ft_putstr (" => " );
212
+ current -> size = get_random_size (& type );
213
+ g_flag .quiet ? : ft_putnbr (current -> size );
214
+ g_flag .quiet ? : ft_putchar (10 );
215
+ current -> ptr = realloc (current -> ptr , current -> size );
216
+ g_flag .align ? assert (!((long )current -> ptr % g_flag .align )): NULL ;
217
+ break ;
218
+ default :
219
+ g_flag .quiet ? : ft_putendl ("no op" );
220
+ break ;
221
+ }
222
+ }
223
+ fill_mem (current );
224
+ }
225
+ return NULL ;
226
+ }
227
+
228
+
229
+ void check_pthread ()
230
+ {
231
+ pthread_t thread_id [g_flag .nbPthread ];
232
+ size_t count ;
233
+
234
+ count = 0 ;
235
+ while (!g_flag .limit || count ++ < g_flag .limit )
236
+ {
237
+ for (int i = 0 ; i < g_flag .nbPthread ; i ++ )
238
+ pthread_create (& thread_id [i ], NULL , brut , NULL );
239
+ for (int i = 0 ; i < g_flag .nbPthread ; i ++ )
240
+ {
241
+ pthread_join (thread_id [i ], NULL );
242
+ ft_putnbr (i );
243
+ puts (" + pthread OK" );
244
+ }
245
+ count ++ ;
246
+ }
247
+ }
248
+
249
+ static void check_error ()
250
+ {
251
+ char * str ;
252
+
253
+ puts (" ================ BEGIN CHECK ERROR ================ " );
254
+ str = malloc (42 );
255
+ free (str + 1 );
256
+ free (str - 1 );
257
+ if (realloc (str + 1 , 43 ) || realloc (str - 1 , 43 ))
258
+ puts ("realloc error fail test" );
259
+ free (str );
260
+ if (realloc (str , 42 ))
261
+ puts ("realloc error fail test" );
262
+ puts ("================ END CHECK ERROR ================" );
263
+ }
264
+
265
+
266
+ int main (int ac , char * * av )
267
+ {
268
+ int opt ;
269
+
270
+ while ((opt = getopt (ac , av , "a:ql:cpn:e" )) != -1 ) {
271
+ switch (opt ) {
272
+ case 'q' :
273
+ g_flag .quiet = true;
274
+ break ;
275
+ case 'l' :
276
+ g_flag .limit = atoi (optarg );
277
+ break ;
278
+ case 'c' :
279
+ g_flag .calloc = true;
280
+ break ;
281
+ case 'p' :
282
+ g_flag .pthread = true;
283
+ break ;
284
+ case 'n' :
285
+ g_flag .nbPthread = atoi (optarg );
286
+ break ;
287
+ case 'a' :
288
+ g_flag .align = atoi (optarg );
289
+ break ;
290
+ case 'e' :
291
+ check_error ();
292
+ return (0 );
293
+ break ;
294
+ default : /* '?' */
295
+ puts ("Usage: ./brut [-qcpe] [–aln number] \n\t-q: quiet (no print except pthread log)\n\t-l: limit set limit number of loop\n\t-c: use calloc \n\t-p: pthread\n\t-n set the number of pthread(default 2)\n\t-e launch test error\n\t-a check align\n" );
296
+ exit (EXIT_FAILURE );
297
+ }
298
+ }
299
+
300
+ if (g_flag .pthread )
301
+ check_pthread ();
302
+ else
303
+ brut (NULL );
304
+ exit (0 );
305
+ };
0 commit comments