8 #include "params.h" // logging, monochrome, quiet_level
12 #include "arch.h" //PAGE_MASK
13 #include "maps.h" //pages
14 #include "syscall.h" //syscalls
20 bool logfiles_opened
= FALSE
;
22 void open_logfiles(void)
27 logfilename
= malloc(64);
28 sprintf(logfilename
, "trinity.log");
30 mainlogfile
= fopen(logfilename
, "a");
32 outputerr("## couldn't open logfile %s\n", logfilename
);
37 sprintf(logfilename
, "trinity-child%d.log", i
);
39 shm
->logfiles
[i
] = fopen(logfilename
, "a");
40 if (!shm
->logfiles
[i
]) {
41 outputerr("## couldn't open logfile %s\n", logfilename
);
46 logfiles_opened
= TRUE
;
49 void close_logfiles(void)
54 if (shm
->logfiles
[i
] != NULL
)
55 fclose(shm
->logfiles
[i
]);
58 static FILE * find_logfile_handle(void)
68 if (pid
== shm
->mainpid
)
71 if (pid
== watchdog_pid
)
74 i
= find_pid_slot(pid
);
75 if (i
!= PIDSLOT_NOT_FOUND
)
76 return shm
->logfiles
[i
];
78 /* try one more time. FIXME: This is awful. */
80 i
= find_pid_slot(pid
);
81 if (i
!= PIDSLOT_NOT_FOUND
)
82 return shm
->logfiles
[i
];
84 outputerr("## Couldn't find logfile for pid %d\n", pid
);
86 outputerr("## Logfiles for pids: ");
88 outputerr("%p ", shm
->logfiles
[j
]);
94 unsigned int highest_logfile(void)
102 file
= shm
->logfiles
[shm
->max_children
- 1];
113 if (logging
== FALSE
)
116 for_each_pidslot(i
) {
117 ret
= fflush(shm
->logfiles
[i
]);
119 outputerr("## logfile flushing failed! %s\n", strerror(errno
));
123 fd
= fileno(shm
->logfiles
[i
]);
127 outputerr("## fsyncing logfile %d failed. %s\n", i
, strerror(errno
));
131 (void)fflush(mainlogfile
);
132 fsync(fileno(mainlogfile
));
135 static void output_arg(unsigned int call
, unsigned int argnum
, const char *name
, unsigned long reg
, int type
, FILE *fd
, bool mono
)
137 if (syscalls
[call
].entry
->num_args
>= argnum
) {
146 fprintf(fd
, "%s=", name
);
150 fprintf(fd
, "\"%s\"", (char *) reg
);
155 fprintf(fd
, "%ld", reg
);
159 fprintf(fd
, "%o", (mode_t
) reg
);
164 case ARG_NON_NULL_ADDRESS
:
170 case ARG_RANDOM_LONG
:
174 case ARG_SOCKADDRLEN
:
177 fprintf(fd
, "0x%lx", reg
);
179 fprintf(fd
, "%ld", reg
);
183 if (reg
== (((unsigned long)page_zeros
) & PAGE_MASK
))
184 fprintf(fd
, "[page_zeros]");
185 if (reg
== (((unsigned long)page_rand
) & PAGE_MASK
))
186 fprintf(fd
, "[page_rand]");
187 if (reg
== (((unsigned long)page_0xff
) & PAGE_MASK
))
188 fprintf(fd
, "[page_0xff]");
189 if (reg
== (((unsigned long)page_allocs
) & PAGE_MASK
))
190 fprintf(fd
, "[page_allocs]");
194 static FILE *robust_find_logfile_handle(void)
199 if ((logging
== TRUE
) && (logfiles_opened
)) {
200 handle
= find_logfile_handle();
202 outputerr("## child logfile handle was null logging to main!\n");
203 (void)fflush(stdout
);
205 shm
->logfiles
[j
] = mainlogfile
;
207 handle
= find_logfile_handle();
214 * level defines whether it gets displayed to the screen with printf.
216 * 0 = everything, even all the registers
217 * 1 = Watchdog prints syscall count
218 * 2 = Just the reseed values
221 void output(unsigned char level
, const char *fmt
, ...)
226 unsigned int len
, i
, j
;
228 char outputbuf
[BUFSIZE
];
229 char monobuf
[BUFSIZE
];
231 char watchdog_prefix
[]="[watchdog]";
232 char init_prefix
[]="[init]";
233 char main_prefix
[]="[main]";
234 char child_prefix
[]="[childNN:1234567890]";
237 if (logging
== FALSE
&& level
>= quiet_level
)
240 /* prefix preparation */
242 if (pid
== watchdog_pid
)
243 prefix
= watchdog_prefix
;
246 prefix
= init_prefix
;
248 if (pid
== shm
->mainpid
)
249 prefix
= main_prefix
;
251 if (prefix
== NULL
) {
252 slot
= find_pid_slot(pid
);
253 sprintf(child_prefix
, "[child%d:%d]", slot
, pid
);
254 prefix
= child_prefix
;
257 /* formatting output */
259 n
= vsnprintf(outputbuf
, sizeof(outputbuf
), fmt
, args
);
262 outputerr("## Something went wrong in output() [%d]\n", n
);
266 /* stdout output if needed */
267 if (quiet_level
> level
) {
268 printf("%s %s", prefix
, outputbuf
);
269 (void)fflush(stdout
);
272 /* go on with file logs only if enabled */
273 if (logging
== FALSE
)
276 handle
= robust_find_logfile_handle();
280 /* If we've specified monochrome, we can just dump the buffer into
281 * the logfile as is, because there shouldn't be any ANSI codes
282 * in the buffer to be stripped out. */
283 if (monochrome
== FALSE
) {
284 /* copy buffer, sans ANSI codes */
285 len
= strlen(outputbuf
);
286 for (i
= 0, j
= 0; (i
< len
) && (i
+ 2 < BUFSIZE
) && (j
< BUFSIZE
); i
++) {
287 if (outputbuf
[i
] == '\e') {
288 if (outputbuf
[i
+ 2] == '1')
289 i
+= 6; // ANSI_COLOUR
291 i
+= 3; // ANSI_RESET
293 monobuf
[j
] = outputbuf
[i
];
298 fprintf(handle
, "%s %s", prefix
, monobuf
);
300 fprintf(handle
, "%s %s", prefix
, outputbuf
);
303 (void)fflush(handle
);
307 * Used as a way to consolidated all printf calls if someones one to redirect it to somewhere else.
308 * note: this function ignores quiet_level since it main purpose is error output.
310 void outputerr(const char *fmt
, ...)
315 vfprintf(stderr
, fmt
, args
);
319 void outputstd(const char *fmt
, ...)
324 vfprintf(stdout
, fmt
, args
);
328 static void output_syscall_prefix_to_fd(const unsigned int childno
, const pid_t pid
, const unsigned int syscallno
, FILE *fd
, bool mono
)
330 fprintf(fd
, "[child%d:%d] [%ld] %s", childno
, pid
, shm
->child_syscall_count
[childno
],
331 (shm
->do32bit
[childno
] == TRUE
) ? "[32BIT] " : "");
333 if (syscallno
> max_nr_syscalls
)
334 fprintf(fd
, "%u", syscallno
);
336 fprintf(fd
, "%s", syscalls
[syscallno
].entry
->name
);
340 output_arg(syscallno
, 1, syscalls
[syscallno
].entry
->arg1name
, shm
->a1
[childno
],
341 syscalls
[syscallno
].entry
->arg1type
, fd
, mono
);
342 output_arg(syscallno
, 2, syscalls
[syscallno
].entry
->arg2name
, shm
->a2
[childno
],
343 syscalls
[syscallno
].entry
->arg2type
, fd
, mono
);
344 output_arg(syscallno
, 3, syscalls
[syscallno
].entry
->arg3name
, shm
->a3
[childno
],
345 syscalls
[syscallno
].entry
->arg3type
, fd
, mono
);
346 output_arg(syscallno
, 4, syscalls
[syscallno
].entry
->arg4name
, shm
->a4
[childno
],
347 syscalls
[syscallno
].entry
->arg4type
, fd
, mono
);
348 output_arg(syscallno
, 5, syscalls
[syscallno
].entry
->arg5name
, shm
->a5
[childno
],
349 syscalls
[syscallno
].entry
->arg5type
, fd
, mono
);
350 output_arg(syscallno
, 6, syscalls
[syscallno
].entry
->arg6name
, shm
->a6
[childno
],
351 syscalls
[syscallno
].entry
->arg6type
, fd
, mono
);
357 /* This function is always called from a fuzzing child. */
358 void output_syscall_prefix(const unsigned int childno
, const unsigned int syscallno
)
363 /* Exit if should not continue at all. */
364 if (logging
== FALSE
&& quiet_level
< MAX_LOGLEVEL
)
368 /* Find the log file handle */
369 log_handle
= robust_find_logfile_handle();
371 /* do not output any ascii control symbols to files */
372 if ((logging
== TRUE
) && (log_handle
!= NULL
))
373 output_syscall_prefix_to_fd(childno
, pid
, syscallno
, log_handle
, TRUE
);
375 /* Output to stdout only if -q param is not specified */
376 if (quiet_level
== MAX_LOGLEVEL
)
377 output_syscall_prefix_to_fd(childno
, pid
, syscallno
, stdout
, monochrome
);
380 static void output_syscall_postfix_err(unsigned long ret
, int errno_saved
, FILE *fd
, bool mono
)
383 fprintf(fd
, "= %ld (%s)", ret
, strerror(errno_saved
));
389 static void output_syscall_postfix_success(unsigned long ret
, FILE *fd
, bool mono
)
392 if ((unsigned long)ret
> 10000)
393 fprintf(fd
, "= 0x%lx", ret
);
395 fprintf(fd
, "= %ld", ret
);
401 void output_syscall_postfix(unsigned long ret
, int errno_saved
, bool err
)
405 /* Exit if should not continue at all. */
406 if (logging
== FALSE
&& quiet_level
< MAX_LOGLEVEL
)
409 /* Find the log file handle */
410 log_handle
= robust_find_logfile_handle();
413 if ((logging
== TRUE
) && (log_handle
!= NULL
))
414 output_syscall_postfix_err(ret
, errno_saved
, log_handle
, TRUE
);
415 if (quiet_level
== MAX_LOGLEVEL
)
416 output_syscall_postfix_err(ret
, errno_saved
, stdout
, monochrome
);
418 if ((logging
== TRUE
) && (log_handle
!= NULL
))
419 output_syscall_postfix_success(ret
, log_handle
, TRUE
);
420 if (quiet_level
== MAX_LOGLEVEL
)
421 output_syscall_postfix_success(ret
, stdout
, monochrome
);
425 void debugf(const char *fmt
, ...)