|
|
@ -1933,7 +1933,7 @@ static void save_auto(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Load automatically generated extras. */
|
|
|
|
/* Load automatically generated extras. */
|
|
|
|
|
|
|
|
// 用于加载自动生成的extras的函数。
|
|
|
|
static void load_auto(void) {
|
|
|
|
static void load_auto(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
u32 i;
|
|
|
@ -1976,7 +1976,7 @@ static void load_auto(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Destroy extras. */
|
|
|
|
/* Destroy extras. */
|
|
|
|
|
|
|
|
// 用于销毁extras的函数。
|
|
|
|
static void destroy_extras(void) {
|
|
|
|
static void destroy_extras(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
u32 i;
|
|
|
@ -2971,7 +2971,7 @@ static void link_or_copy(u8* old_path, u8* new_path) {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 用于删除用于即时会话恢复的临时目录的函数。
|
|
|
|
static void nuke_resume_dir(void);
|
|
|
|
static void nuke_resume_dir(void);
|
|
|
|
|
|
|
|
|
|
|
|
/* Create hard links for input test cases in the output directory, choosing
|
|
|
|
/* Create hard links for input test cases in the output directory, choosing
|
|
|
@ -3417,7 +3417,7 @@ static void find_timeout(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Update stats file for unattended monitoring. */
|
|
|
|
/* Update stats file for unattended monitoring. */
|
|
|
|
|
|
|
|
// 用于更新统计文件的函数,用于无人值守的监控。
|
|
|
|
static void write_stats_file(double bitmap_cvg, double stability, double eps) {
|
|
|
|
static void write_stats_file(double bitmap_cvg, double stability, double eps) {
|
|
|
|
|
|
|
|
|
|
|
|
static double last_bcvg, last_stab, last_eps;
|
|
|
|
static double last_bcvg, last_stab, last_eps;
|
|
|
@ -3516,7 +3516,7 @@ static void write_stats_file(double bitmap_cvg, double stability, double eps) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Update the plot file if there is a reason to. */
|
|
|
|
/* Update the plot file if there is a reason to. */
|
|
|
|
|
|
|
|
// 用于更新绘图文件的函数,如果有必要的话。
|
|
|
|
static void maybe_update_plot_file(double bitmap_cvg, double eps) {
|
|
|
|
static void maybe_update_plot_file(double bitmap_cvg, double eps) {
|
|
|
|
|
|
|
|
|
|
|
|
static u32 prev_qp, prev_pf, prev_pnf, prev_ce, prev_md;
|
|
|
|
static u32 prev_qp, prev_pf, prev_pnf, prev_ce, prev_md;
|
|
|
@ -3556,7 +3556,7 @@ static void maybe_update_plot_file(double bitmap_cvg, double eps) {
|
|
|
|
|
|
|
|
|
|
|
|
/* A helper function for maybe_delete_out_dir(), deleting all prefixed
|
|
|
|
/* A helper function for maybe_delete_out_dir(), deleting all prefixed
|
|
|
|
files in a directory. */
|
|
|
|
files in a directory. */
|
|
|
|
|
|
|
|
// 用于删除所有以特定前缀开头的文件的辅助函数。
|
|
|
|
static u8 delete_files(u8* path, u8* prefix) {
|
|
|
|
static u8 delete_files(u8* path, u8* prefix) {
|
|
|
|
|
|
|
|
|
|
|
|
DIR* d;
|
|
|
|
DIR* d;
|
|
|
@ -3587,7 +3587,7 @@ static u8 delete_files(u8* path, u8* prefix) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Get the number of runnable processes, with some simple smoothing. */
|
|
|
|
/* Get the number of runnable processes, with some simple smoothing. */
|
|
|
|
|
|
|
|
// 用于获取可运行进程数量的函数,带有一定的简单平滑处理。
|
|
|
|
static double get_runnable_processes(void) {
|
|
|
|
static double get_runnable_processes(void) {
|
|
|
|
|
|
|
|
|
|
|
|
static double res;
|
|
|
|
static double res;
|
|
|
@ -3680,7 +3680,7 @@ dir_cleanup_failed:
|
|
|
|
|
|
|
|
|
|
|
|
/* Delete fuzzer output directory if we recognize it as ours, if the fuzzer
|
|
|
|
/* Delete fuzzer output directory if we recognize it as ours, if the fuzzer
|
|
|
|
is not currently running, and if the last run time isn't too great. */
|
|
|
|
is not currently running, and if the last run time isn't too great. */
|
|
|
|
|
|
|
|
// 用于删除输出目录的函数,如果它被认为是我们的,并且fuzzer没有在运行,并且最后一次运行时间不是很长。
|
|
|
|
static void maybe_delete_out_dir(void) {
|
|
|
|
static void maybe_delete_out_dir(void) {
|
|
|
|
|
|
|
|
|
|
|
|
FILE* f;
|
|
|
|
FILE* f;
|
|
|
@ -6842,7 +6842,7 @@ static void handle_stop_sig(int sig) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle skip request (SIGUSR1). */
|
|
|
|
/* Handle skip request (SIGUSR1). */
|
|
|
|
|
|
|
|
// 用于处理用户请求跳过当前输入的信号(SIGUSR1)的函数。
|
|
|
|
static void handle_skipreq(int sig) {
|
|
|
|
static void handle_skipreq(int sig) {
|
|
|
|
|
|
|
|
|
|
|
|
skip_requested = 1;
|
|
|
|
skip_requested = 1;
|
|
|
@ -7274,7 +7274,7 @@ EXP_ST void setup_dirs_fds(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Setup the output file for fuzzed data, if not using -f. */
|
|
|
|
/* Setup the output file for fuzzed data, if not using -f. */
|
|
|
|
|
|
|
|
// 准备输出文件用于测试的函数。如果指定了输出文件,则会创建一个新文件;否则,会重置并截断现有的输出文件描述符。
|
|
|
|
EXP_ST void setup_stdio_file(void) {
|
|
|
|
EXP_ST void setup_stdio_file(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u8* fn = alloc_printf("%s/.cur_input", out_dir);
|
|
|
|
u8* fn = alloc_printf("%s/.cur_input", out_dir);
|
|
|
@ -7542,14 +7542,14 @@ static void fix_up_sync(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle screen resize (SIGWINCH). */
|
|
|
|
/* Handle screen resize (SIGWINCH). */
|
|
|
|
|
|
|
|
// 处理屏幕大小变化的信号处理函数。
|
|
|
|
static void handle_resize(int sig) {
|
|
|
|
static void handle_resize(int sig) {
|
|
|
|
clear_screen = 1;
|
|
|
|
clear_screen = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check ASAN options. */
|
|
|
|
/* Check ASAN options. */
|
|
|
|
|
|
|
|
// 检查ASAN选项的函数。
|
|
|
|
static void check_asan_opts(void) {
|
|
|
|
static void check_asan_opts(void) {
|
|
|
|
u8* x = getenv("ASAN_OPTIONS");
|
|
|
|
u8* x = getenv("ASAN_OPTIONS");
|
|
|
|
|
|
|
|
|
|
|
@ -7580,7 +7580,7 @@ static void check_asan_opts(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Detect @@ in args. */
|
|
|
|
/* Detect @@ in args. */
|
|
|
|
|
|
|
|
// 用于处理文件名中'@@'参数的函数。
|
|
|
|
EXP_ST void detect_file_args(char** argv) {
|
|
|
|
EXP_ST void detect_file_args(char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
u32 i = 0;
|
|
|
|
u32 i = 0;
|
|
|
@ -7629,7 +7629,7 @@ EXP_ST void detect_file_args(char** argv) {
|
|
|
|
/* Set up signal handlers. More complicated that needs to be, because libc on
|
|
|
|
/* Set up signal handlers. More complicated that needs to be, because libc on
|
|
|
|
Solaris doesn't resume interrupted reads(), sets SA_RESETHAND when you call
|
|
|
|
Solaris doesn't resume interrupted reads(), sets SA_RESETHAND when you call
|
|
|
|
siginterrupt(), and does other unnecessary things. */
|
|
|
|
siginterrupt(), and does other unnecessary things. */
|
|
|
|
|
|
|
|
// 设置信号处理程序的函数。
|
|
|
|
EXP_ST void setup_signal_handlers(void) {
|
|
|
|
EXP_ST void setup_signal_handlers(void) {
|
|
|
|
|
|
|
|
|
|
|
|
struct sigaction sa;
|
|
|
|
struct sigaction sa;
|
|
|
@ -7672,7 +7672,7 @@ EXP_ST void setup_signal_handlers(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Rewrite argv for QEMU. */
|
|
|
|
/* Rewrite argv for QEMU. */
|
|
|
|
|
|
|
|
// 用于重写argv以用于QEMU的函数。
|
|
|
|
static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
|
|
|
|
static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
|
|
|
|
|
|
|
|
|
|
|
|
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
|
|
|
|
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
|
|
|
@ -9036,7 +9036,7 @@ static void add_to_queue(u8* fname, u32 len, u8 passed_det) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Destroy the entire queue. */
|
|
|
|
/* Destroy the entire queue. */
|
|
|
|
|
|
|
|
// 销毁队列的函数。它释放与测试用例队列相关的所有内存资源。
|
|
|
|
EXP_ST void destroy_queue(void) {
|
|
|
|
EXP_ST void destroy_queue(void) {
|
|
|
|
|
|
|
|
|
|
|
|
struct queue_entry *q = queue, *n;
|
|
|
|
struct queue_entry *q = queue, *n;
|
|
|
@ -9565,7 +9565,7 @@ static void cull_queue(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Configure shared memory and virgin_bits. This is called at startup. */
|
|
|
|
/* Configure shared memory and virgin_bits. This is called at startup. */
|
|
|
|
|
|
|
|
// 初始化共享内存和virgin_bits。这在程序启动时被调用。
|
|
|
|
EXP_ST void setup_shm(void) {
|
|
|
|
EXP_ST void setup_shm(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u8* shm_str;
|
|
|
|
u8* shm_str;
|
|
|
@ -9628,7 +9628,7 @@ static void setup_post(void) {
|
|
|
|
|
|
|
|
|
|
|
|
/* Read all testcases from the input directory, then queue them for testing.
|
|
|
|
/* Read all testcases from the input directory, then queue them for testing.
|
|
|
|
Called at startup. */
|
|
|
|
Called at startup. */
|
|
|
|
|
|
|
|
// 从输入目录中读取所有测试用例,并将它们排队以供测试。这在程序启动时被调用。
|
|
|
|
static void read_testcases(void) {
|
|
|
|
static void read_testcases(void) {
|
|
|
|
|
|
|
|
|
|
|
|
struct dirent **nl;
|
|
|
|
struct dirent **nl;
|
|
|
@ -10103,7 +10103,7 @@ sort_a_extras:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Save automatically generated extras. */
|
|
|
|
/* Save automatically generated extras. */
|
|
|
|
|
|
|
|
// 用于保存自动生成的extras的函数。
|
|
|
|
static void save_auto(void) {
|
|
|
|
static void save_auto(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
u32 i;
|
|
|
@ -10131,7 +10131,7 @@ static void save_auto(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Load automatically generated extras. */
|
|
|
|
/* Load automatically generated extras. */
|
|
|
|
|
|
|
|
// 用于加载自动生成的extras的函数。
|
|
|
|
static void load_auto(void) {
|
|
|
|
static void load_auto(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
u32 i;
|
|
|
@ -10484,7 +10484,7 @@ EXP_ST void init_forkserver(char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
/* Execute target application, monitoring for timeouts. Return status
|
|
|
|
/* Execute target application, monitoring for timeouts. Return status
|
|
|
|
information. The called program will update trace_bits[]. */
|
|
|
|
information. The called program will update trace_bits[]. */
|
|
|
|
|
|
|
|
// 执行目标程序并监控超时。这个函数负责启动目标程序,等待其执行完成,并捕获任何超时或崩溃。
|
|
|
|
static u8 run_target(char** argv, u32 timeout) {
|
|
|
|
static u8 run_target(char** argv, u32 timeout) {
|
|
|
|
|
|
|
|
|
|
|
|
static struct itimerval it;
|
|
|
|
static struct itimerval it;
|
|
|
@ -10765,7 +10765,7 @@ static void show_stats(void);
|
|
|
|
/* Calibrate a new test case. This is done when processing the input directory
|
|
|
|
/* Calibrate a new test case. This is done when processing the input directory
|
|
|
|
to warn about flaky or otherwise problematic test cases early on; and when
|
|
|
|
to warn about flaky or otherwise problematic test cases early on; and when
|
|
|
|
new paths are discovered to detect variable behavior and so on. */
|
|
|
|
new paths are discovered to detect variable behavior and so on. */
|
|
|
|
|
|
|
|
// 校准测试用例的函数。它执行目标程序多次,以确定测试用例的执行时间和覆盖率,这有助于确定测试用例的优先级。
|
|
|
|
static u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem,
|
|
|
|
static u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem,
|
|
|
|
u32 handicap, u8 from_queue) {
|
|
|
|
u32 handicap, u8 from_queue) {
|
|
|
|
|
|
|
|
|
|
|
@ -10920,7 +10920,7 @@ abort_calibration:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Examine map coverage. Called once, for first test case. */
|
|
|
|
/* Examine map coverage. Called once, for first test case. */
|
|
|
|
|
|
|
|
// 检查位图覆盖率。如果位图的覆盖率不足,这个函数会提醒用户可能需要重新编译目标程序以获得更好的覆盖率。
|
|
|
|
static void check_map_coverage(void) {
|
|
|
|
static void check_map_coverage(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
u32 i;
|
|
|
@ -10937,7 +10937,7 @@ static void check_map_coverage(void) {
|
|
|
|
|
|
|
|
|
|
|
|
/* Perform dry run of all test cases to confirm that the app is working as
|
|
|
|
/* Perform dry run of all test cases to confirm that the app is working as
|
|
|
|
expected. This is done only for the initial inputs, and only once. */
|
|
|
|
expected. This is done only for the initial inputs, and only once. */
|
|
|
|
|
|
|
|
// 执行干运行。在正式开始模糊测试之前,这个函数用于验证目标程序的行为,确保它能够正确处理初始的测试用例集。
|
|
|
|
static void perform_dry_run(char** argv) {
|
|
|
|
static void perform_dry_run(char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
struct queue_entry* q = queue;
|
|
|
|
struct queue_entry* q = queue;
|
|
|
@ -12127,7 +12127,7 @@ static void check_term_size(void);
|
|
|
|
|
|
|
|
|
|
|
|
/* A spiffy retro stats screen! This is called every stats_update_freq
|
|
|
|
/* A spiffy retro stats screen! This is called every stats_update_freq
|
|
|
|
execve() calls, plus in several other circumstances. */
|
|
|
|
execve() calls, plus in several other circumstances. */
|
|
|
|
|
|
|
|
// 显示模糊测试的统计信息,如执行速度、发现的路径数量、唯一崩溃等。
|
|
|
|
static void show_stats(void) {
|
|
|
|
static void show_stats(void) {
|
|
|
|
|
|
|
|
|
|
|
|
static u64 last_stats_ms, last_plot_ms, last_ms, last_execs;
|
|
|
|
static u64 last_stats_ms, last_plot_ms, last_ms, last_execs;
|
|
|
@ -13197,7 +13197,7 @@ static u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) {
|
|
|
|
/* Take the current entry from the queue, fuzz it for a while. This
|
|
|
|
/* Take the current entry from the queue, fuzz it for a while. This
|
|
|
|
function is a tad too long... returns 0 if fuzzed successfully, 1 if
|
|
|
|
function is a tad too long... returns 0 if fuzzed successfully, 1 if
|
|
|
|
skipped or bailed out. */
|
|
|
|
skipped or bailed out. */
|
|
|
|
|
|
|
|
// 执行一次模糊测试的函数。它接受一个测试用例,应用各种变异技术来生成新的测试用例,然后执行目标程序来检查新测试用例的效果。
|
|
|
|
static u8 fuzz_one(char** argv) {
|
|
|
|
static u8 fuzz_one(char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
s32 len, fd, temp_len, i, j;
|
|
|
|
s32 len, fd, temp_len, i, j;
|
|
|
@ -14889,7 +14889,7 @@ abandon_entry:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Grab interesting test cases from other fuzzers. */
|
|
|
|
/* Grab interesting test cases from other fuzzers. */
|
|
|
|
|
|
|
|
// 用于同步不同fuzzer实例进度的函数。
|
|
|
|
static void sync_fuzzers(char** argv) {
|
|
|
|
static void sync_fuzzers(char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
DIR* sd;
|
|
|
|
DIR* sd;
|
|
|
@ -15027,7 +15027,7 @@ static void sync_fuzzers(char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle stop signal (Ctrl-C, etc). */
|
|
|
|
/* Handle stop signal (Ctrl-C, etc). */
|
|
|
|
|
|
|
|
// 处理停止信号(如Ctrl+C)的函数。它设置一个标志来告诉主循环停止执行。
|
|
|
|
static void handle_stop_sig(int sig) {
|
|
|
|
static void handle_stop_sig(int sig) {
|
|
|
|
|
|
|
|
|
|
|
|
stop_soon = 1;
|
|
|
|
stop_soon = 1;
|
|
|
@ -15047,7 +15047,7 @@ static void handle_skipreq(int sig) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle timeout (SIGALRM). */
|
|
|
|
/* Handle timeout (SIGALRM). */
|
|
|
|
|
|
|
|
// 处理超时信号的函数。它设置一个标志来指示目标程序已经超时。
|
|
|
|
static void handle_timeout(int sig) {
|
|
|
|
static void handle_timeout(int sig) {
|
|
|
|
|
|
|
|
|
|
|
|
if (child_pid > 0) {
|
|
|
|
if (child_pid > 0) {
|
|
|
@ -15068,7 +15068,7 @@ static void handle_timeout(int sig) {
|
|
|
|
/* Do a PATH search and find target binary to see that it exists and
|
|
|
|
/* Do a PATH search and find target binary to see that it exists and
|
|
|
|
isn't a shell script - a common and painful mistake. We also check for
|
|
|
|
isn't a shell script - a common and painful mistake. We also check for
|
|
|
|
a valid ELF header and for evidence of AFL instrumentation. */
|
|
|
|
a valid ELF header and for evidence of AFL instrumentation. */
|
|
|
|
|
|
|
|
// 检查二进制文件是否存在,是否可执行,以及是否具有AFL所需的instrumentation
|
|
|
|
EXP_ST void check_binary(u8* fname) {
|
|
|
|
EXP_ST void check_binary(u8* fname) {
|
|
|
|
|
|
|
|
|
|
|
|
u8* env_path = 0;
|
|
|
|
u8* env_path = 0;
|
|
|
@ -15471,7 +15471,7 @@ EXP_ST void setup_dirs_fds(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Setup the output file for fuzzed data, if not using -f. */
|
|
|
|
/* Setup the output file for fuzzed data, if not using -f. */
|
|
|
|
|
|
|
|
// 准备输出文件用于测试的函数。如果指定了输出文件,则会创建一个新文件;否则,会重置并截断现有的输出文件描述符。
|
|
|
|
EXP_ST void setup_stdio_file(void) {
|
|
|
|
EXP_ST void setup_stdio_file(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u8* fn = alloc_printf("%s/.cur_input", out_dir);
|
|
|
|
u8* fn = alloc_printf("%s/.cur_input", out_dir);
|
|
|
@ -15554,7 +15554,7 @@ static void check_crash_handling(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check CPU governor. */
|
|
|
|
/* Check CPU governor. */
|
|
|
|
|
|
|
|
// 检查CPU调速器设置的函数。确保CPU在高负载下不会降频,从而影响测试的执行速度。
|
|
|
|
static void check_cpu_governor(void) {
|
|
|
|
static void check_cpu_governor(void) {
|
|
|
|
|
|
|
|
|
|
|
|
FILE* f;
|
|
|
|
FILE* f;
|
|
|
@ -15610,7 +15610,7 @@ static void check_cpu_governor(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Count the number of logical CPU cores. */
|
|
|
|
/* Count the number of logical CPU cores. */
|
|
|
|
|
|
|
|
// 获取CPU核心数。这个函数用于确定系统中可用的CPU核心数,以便AFL可以有效地分配工作负载。
|
|
|
|
static void get_core_count(void) {
|
|
|
|
static void get_core_count(void) {
|
|
|
|
|
|
|
|
|
|
|
|
u32 cur_runnable = 0;
|
|
|
|
u32 cur_runnable = 0;
|
|
|
@ -15739,14 +15739,14 @@ static void fix_up_sync(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle screen resize (SIGWINCH). */
|
|
|
|
/* Handle screen resize (SIGWINCH). */
|
|
|
|
|
|
|
|
// 处理屏幕大小变化的信号处理函数。
|
|
|
|
static void handle_resize(int sig) {
|
|
|
|
static void handle_resize(int sig) {
|
|
|
|
clear_screen = 1;
|
|
|
|
clear_screen = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check ASAN options. */
|
|
|
|
/* Check ASAN options. */
|
|
|
|
|
|
|
|
// 检查ASAN选项的函数。
|
|
|
|
static void check_asan_opts(void) {
|
|
|
|
static void check_asan_opts(void) {
|
|
|
|
u8* x = getenv("ASAN_OPTIONS");
|
|
|
|
u8* x = getenv("ASAN_OPTIONS");
|
|
|
|
|
|
|
|
|
|
|
@ -15777,7 +15777,7 @@ static void check_asan_opts(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Detect @@ in args. */
|
|
|
|
/* Detect @@ in args. */
|
|
|
|
|
|
|
|
// 用于处理文件名中'@@'参数的函数。
|
|
|
|
EXP_ST void detect_file_args(char** argv) {
|
|
|
|
EXP_ST void detect_file_args(char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
u32 i = 0;
|
|
|
|
u32 i = 0;
|
|
|
@ -15826,7 +15826,7 @@ EXP_ST void detect_file_args(char** argv) {
|
|
|
|
/* Set up signal handlers. More complicated that needs to be, because libc on
|
|
|
|
/* Set up signal handlers. More complicated that needs to be, because libc on
|
|
|
|
Solaris doesn't resume interrupted reads(), sets SA_RESETHAND when you call
|
|
|
|
Solaris doesn't resume interrupted reads(), sets SA_RESETHAND when you call
|
|
|
|
siginterrupt(), and does other unnecessary things. */
|
|
|
|
siginterrupt(), and does other unnecessary things. */
|
|
|
|
|
|
|
|
// 设置信号处理程序的函数。
|
|
|
|
EXP_ST void setup_signal_handlers(void) {
|
|
|
|
EXP_ST void setup_signal_handlers(void) {
|
|
|
|
|
|
|
|
|
|
|
|
struct sigaction sa;
|
|
|
|
struct sigaction sa;
|
|
|
@ -15869,7 +15869,7 @@ EXP_ST void setup_signal_handlers(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Rewrite argv for QEMU. */
|
|
|
|
/* Rewrite argv for QEMU. */
|
|
|
|
|
|
|
|
// 用于重写argv以用于QEMU的函数。
|
|
|
|
static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
|
|
|
|
static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
|
|
|
|
|
|
|
|
|
|
|
|
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
|
|
|
|
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
|
|
|
|