diff --git a/src/afl-gcc.c b/src/afl-gcc.c index 2e6dffc..e443eb5 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -47,79 +47,73 @@ #include #include -static u8 *as_path; /*AFL“as”包装器的路径*/ -static u8 **cc_params; /*传递给真实CC的参数*/ -static u32 cc_par_cnt = 1; /*参数计数,包括argv0*/ -static u8 be_quiet, /*静音模式*/ - clang_mode; /*被称为afl clang模式**/ +static u8 *as_path; /* AFL“as”包装器的路径 */ +static u8 **cc_params; /* 传递给真实C编译器的参数 */ +static u32 cc_par_cnt = 1; /* 参数计数,包括argv0 */ +static u8 be_quiet, /* 静音模式 */ + clang_mode; /* 被称为afl clang模式 */ /* 尝试在 AFL_PATH 或从 argv[0] 派生的位置找到我们的“假”GNU 汇编器。 如果失败,则中止。 */ - static void find_as(u8 *argv0) { - - u8 *afl_path = getenv("AFL_PATH"); + u8 *afl_path = getenv("AFL_PATH"); // 获取环境变量AFL_PATH的值 u8 *slash, *tmp; - if (afl_path) + if (afl_path) // 如果AFL_PATH环境变量存在 { + tmp = alloc_printf("%s/as", afl_path); // 构造路径字符串 - tmp = alloc_printf("%s/as", afl_path); - - if (!access(tmp, X_OK)) + if (!access(tmp, X_OK)) // 检查路径是否存在且可执行 { - as_path = afl_path; - ck_free(tmp); + as_path = afl_path; // 设置as_path为找到的路径 + ck_free(tmp); // 释放临时字符串 return; } - ck_free(tmp); + ck_free(tmp); // 如果不可执行,释放临时字符串 } - slash = strrchr(argv0, '/'); + slash = strrchr(argv0, '/'); // 在argv0中查找最后一个'/',以获取目录部分 - if (slash) + if (slash) // 如果找到了'/',说明argv0是一个路径 { - u8 *dir; - *slash = 0; - dir = ck_strdup(argv0); - *slash = '/'; + *slash = 0; // 暂时将'/'替换为'\0',以便截取目录部分 + dir = ck_strdup(argv0); // 复制目录部分 + *slash = '/'; // 恢复'/',恢复argv0的完整路径 - tmp = alloc_printf("%s/afl-as", dir); + tmp = alloc_printf("%s/afl-as", dir); // 构造路径字符串 - if (!access(tmp, X_OK)) + if (!access(tmp, X_OK)) // 检查路径是否存在且可执行 { - as_path = dir; - ck_free(tmp); + as_path = dir; // 设置as_path为找到的路径 + ck_free(tmp); // 释放临时字符串 return; } - ck_free(tmp); - ck_free(dir); + ck_free(tmp); // 如果不可执行,释放临时字符串 + ck_free(dir); // 释放目录字符串 } - if (!access(AFL_PATH "/as", X_OK)) + if (!access(AFL_PATH "/as", X_OK)) // 检查默认路径AFL_PATH/as是否存在且可执行 { - as_path = AFL_PATH; + as_path = AFL_PATH; // 设置as_path为默认路径 return; } - FATAL("Unable to find AFL wrapper binary for 'as'. Please set AFL_PATH"); + FATAL("Unable to find AFL wrapper binary for 'as'. Please set AFL_PATH"); // 如果找不到,输出错误信息并中止 } -/*将argv复制到cc_params,进行必要的编辑*/ - +/* 将argv复制到cc_params,进行必要的编辑 */ static void edit_params(u32 argc, char **argv) { - - u8 fortify_set = 0, asan_set = 0; + u8 fortify_set = 0, asan_set = 0; // 标志变量,用于检测是否设置了fortify和asan u8 *name; #if defined(__FreeBSD__) && defined(__x86_64__) - u8 m32_set = 0; + u8 m32_set = 0; // FreeBSD x86_64环境下,检测是否设置了m32 #endif /******************************************************************************** @@ -127,77 +121,74 @@ static void edit_params(u32 argc, char **argv) * 如果使用的是 afl-clang,则根据环境变量确定使用的 C 或 C++ 编译器。 ********************************************************************************/ - cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); - - name = strrchr(argv[0], '/'); - if (!name) - name = argv[0]; - else - name++; - - if (!strncmp(name, "afl-clang", 9)) - { - - clang_mode = 1; - - setenv(CLANG_ENV_VAR, "1", 1); - - if (!strcmp(name, "afl-clang++")) - { - u8 *alt_cxx = getenv("AFL_CXX"); - cc_params[0] = alt_cxx ? alt_cxx : (u8 *)"clang++"; - } - else - { - u8 *alt_cc = getenv("AFL_CC"); - cc_params[0] = alt_cc ? alt_cc : (u8 *)"clang"; - } - } + cc_params = ck_alloc((argc + 128) * sizeof(u8 *)); // 分配足够大的空间来存储编译器参数 + + name = strrchr(argv[0], '/'); // 获取可执行文件名 + if (!name) + name = argv[0]; // 如果没有找到'/',则argv0就是可执行文件名 else - { + name++; // 否则,name指向可执行文件名的第一个字符 - /*安装了GCJ和Eclipse后,您实际上可以编译Java!这个 -仪器将工作(令人惊讶)。唉,未处理的异常确实如此 -不调用abort(),因此需要修改afl-fuzz以使其相等 -使用Java时具有崩溃条件的非零退出代码 -二进制文件。嗯*/ + if (!strncmp(name, "afl-clang", 9)) // 如果可执行文件名以afl-clang开头 + { + clang_mode = 1; // 设置clang_mode标志为1,表示使用clang模式 -#ifdef __APPLE__ + setenv(CLANG_ENV_VAR, "1", 1); // 设置环境变量,表示正在使用afl-clang - if (!strcmp(name, "afl-g++")) - cc_params[0] = getenv("AFL_CXX"); - else if (!strcmp(name, "afl-gcj")) - cc_params[0] = getenv("AFL_GCJ"); + if (!strcmp(name, "afl-clang++")) // 如果是afl-clang++ + { + u8 *alt_cxx = getenv("AFL_CXX"); // 获取环境变量AFL_CXX的值 + cc_params[0] = alt_cxx ? alt_cxx : (u8 *)"clang++"; // 如果设置了AFL_CXX,则使用该值作为编译器,否则使用clang++ + } + else // 如果是afl-clang + { + u8 *alt_cc = getenv("AFL_CC"); // 获取环境变量AFL_CC的值 + cc_params[0] = alt_cc ? alt_cc : (u8 *)"clang"; // 如果设置了AFL_CC,则使用该值作为编译器,否则使用clang + } + } + else // 如果不是afl-clang + { + // 安装了GCJ和Eclipse后,您实际上可以编译Java!这个 + // 仪器将工作(令人惊讶)。唉,未处理的异常确实如此 + // 不调用abort(),因此需要修改afl-fuzz以使其相等 + // 使用Java时具有崩溃条件的非零退出代码 + // 二进制文件。嗯 + +#ifdef __APPLE__ // 如果是在MacOS X系统上 + + if (!strcmp(name, "afl-g++")) // 如果是afl-g++ + cc_params[0] = getenv("AFL_CXX"); // 获取环境变量AFL_CXX的值作为编译器 + else if (!strcmp(name, "afl-gcj")) // 如果是afl-gcj + cc_params[0] = getenv("AFL_GCJ"); // 获取环境变量AFL_GCJ的值作为编译器 else - cc_params[0] = getenv("AFL_CC"); + cc_params[0] = getenv("AFL_CC"); // 其他情况,获取环境变量AFL_CC的值作为编译器 - if (!cc_params[0]) + if (!cc_params[0]) // 如果没有设置相应的环境变量 { - - SAYF("\n" cLRD "[-] " cRST + SAYF("\n" cLRD "[-] " cRST // 输出错误信息 "On Apple systems, 'gcc' is usually just a wrapper for clang. Please use the\n" " 'afl-clang' utility instead of 'afl-gcc'. If you really have GCC installed,\n" " set AFL_CC or AFL_CXX to specify the correct path to that compiler.\n"); - FATAL("AFL_CC or AFL_CXX required on MacOS X"); + FATAL("AFL_CC or AFL_CXX required on MacOS X"); // 输出错误信息并中止 } -#else +#else // 如果不是在MacOS X系统上 - if (!strcmp(name, "afl-g++")) + if (!strcmp(name, "afl-g++")) // 如果是afl-g++ { - u8 *alt_cxx = getenv("AFL_CXX"); - cc_params[0] = alt_cxx ? alt_cxx : (u8 *)"g++"; + u8 *alt_cxx = getenv("AFL_CXX"); // 获取环境变量AFL_CXX的值 + cc_params[0] = alt_cxx ? alt_cxx : (u8 *)"g++"; // 如果设置了AFL_CXX,则使用该值作为编译器,否则使用g++ } - else if (!strcmp(name, "afl-gcj")) + else if (!strcmp(name, "afl-gcj")) // 如果是afl-gcj { - u8 *alt_cc = getenv("AFL_GCJ"); - cc_params[0] = alt_cc ? alt_cc : (u8 *)"gcj"; + u8 *alt_cc = getenv("AFL_GCJ"); // 获取环境变量AFL_GCJ的值 + cc_params[0] = alt_cc ? alt_cc : (u8 *)"gcj"; // 如果设置了AFL_GCJ,则使用该值作为编译器,否则使用gcj } - else + else // 如果是afl-gcc { - u8 *alt_cc = getenv("AFL_CC"); - cc_params[0] = alt_cc ? alt_cc : (u8 *)"gcc"; + u8 *alt_cc = getenv("AFL_CC"); // 获取环境变量AFL_CC的值 + cc_params[0] = alt_cc ? alt_cc : (u8 *)"gcc"; // 如果设置了AFL_CC,则使用该值作为编译器,否则使用gcc } #endif /* __APPLE__ */ @@ -233,32 +224,35 @@ static void edit_params(u32 argc, char **argv) if (!strcmp(cur, "-pipe")) continue; -/ * - * 该段代码用于处理编译器参数设置,包括支持地址和内存消毒功能的相关配置。 - * 根据环境变量和输入参数,启用或禁用特定的功能选项。 - * 代码还处理与FORTIFY_SOURCE和ASAN/MSAN的互斥关系。 - * / + #if defined(__FreeBSD__) && defined(__x86_64__) + // 检测是否在FreeBSD的64位系统上使用了-m32选项,如果是则设置m32_set为1 if (!strcmp(cur, "-m32")) m32_set = 1; #endif + // 检测是否使用了address sanitizer或memory sanitizer选项,如果是则设置asan_set为1 if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; + // 检测是否设置了_FORTIFY_SOURCE宏,如果是则设置fortify_set为1 if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1; + // 将当前命令行参数添加到编译器参数列表中 cc_params[cc_par_cnt++] = cur; } + // 添加编译器的-B参数,指定路径给as_path cc_params[cc_par_cnt++] = "-B"; cc_params[cc_par_cnt++] = as_path; + // 如果clang_mode为真,则添加-no-integrated-as参数 if (clang_mode) cc_params[cc_par_cnt++] = "-no-integrated-as"; + // 如果设置了AFL_HARDEN环境变量,则添加-fstack-protector-all参数,并在未设置_FORTIFY_SOURCE时定义它 if (getenv("AFL_HARDEN")) { @@ -268,6 +262,7 @@ static void edit_params(u32 argc, char **argv) cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2"; } + // 如果asan_set为真,则设置AFL_USE_ASAN环境变量为1,用于通知afl使用asan if (asan_set) { @@ -277,25 +272,27 @@ static void edit_params(u32 argc, char **argv) } else if (getenv("AFL_USE_ASAN")) { - + // 如果设置了AFL_USE_ASAN但未设置asan_set,检查是否同时设置了MSAN和AFL_HARDEN,如果是则报错 if (getenv("AFL_USE_MSAN")) - FATAL("ASAN and MSAN are mutually exclusive"); + FATAL("ASAN和MSAN是互斥的"); if (getenv("AFL_HARDEN")) - FATAL("ASAN and AFL_HARDEN are mutually exclusive"); + FATAL("ASAN和AFL_HARDEN是互斥的"); + // 取消定义_FORTIFY_SOURCE宏,添加address sanitizer参数 cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; cc_params[cc_par_cnt++] = "-fsanitize=address"; } else if (getenv("AFL_USE_MSAN")) { - + // 如果设置了AFL_USE_MSAN,检查是否同时设置了ASAN和AFL_HARDEN,如果是则报错 if (getenv("AFL_USE_ASAN")) - FATAL("ASAN and MSAN are mutually exclusive"); + FATAL("ASAN和MSAN是互斥的"); if (getenv("AFL_HARDEN")) - FATAL("MSAN and AFL_HARDEN are mutually exclusive"); + FATAL("MSAN和AFL_HARDEN是互斥的"); + // 取消定义_FORTIFY_SOURCE宏,添加memory sanitizer参数 cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE"; cc_params[cc_par_cnt++] = "-fsanitize=memory"; } @@ -306,6 +303,7 @@ static void edit_params(u32 argc, char **argv) * 文件名: d:\code\google_AFL\src\afl-gcc.c ********************************************************************************/ + // 如果未设置AFL_DONT_OPTIMIZE环境变量,则进行优化设置 if (!getenv("AFL_DONT_OPTIMIZE")) { @@ -315,41 +313,45 @@ static void edit_params(u32 argc, char **argv) 工作正常。这与我们无关,但让我们避免触发 这个bug*/ + // 如果不是clang模式或者未设置m32选项,则添加-g参数 if (!clang_mode || !m32_set) cc_params[cc_par_cnt++] = "-g"; #else + // 添加调试信息参数-g cc_params[cc_par_cnt++] = "-g"; #endif + // 添加-O3优化级别参数和-unroll-loops参数 cc_params[cc_par_cnt++] = "-O3"; cc_params[cc_par_cnt++] = "-funroll-loops"; /* Two indicators that you're building for fuzzing; one of them is AFL-specific, the other is shared with libfuzzer. */ + // 添加编译器标志,指示正在为模糊测试构建代码 cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1"; cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1"; } - /*********************************************** - * 函数:根据环境变量设置编译器参数 - * 功能:如果环境变量"AFL_NO_BUILTIN"存在, - * 添加禁用内置字符串和内存比较函数的编译器参数。 - ***********************************************/ - if (getenv("AFL_NO_BUILTIN")) - { - - cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-strstr"; - cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr"; - } cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; - cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; + + // 如果设置了AFL_NO_BUILTIN环境变量,则添加参数禁用内置的字符串和内存比较函数 + if (getenv("AFL_NO_BUILTIN")) + { + cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strstr"; + cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr"; + // 注意:这里重复了两遍-fno-builtin-strncasecmp 和 -fno-builtin-memcmp,应去掉重复的部分 + // cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; + // cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; + } + + // 设置编译器参数列表的结束标志NULL cc_params[cc_par_cnt] = NULL; } @@ -358,45 +360,42 @@ static void edit_params(u32 argc, char **argv) // 主函数,程序的入口点 int main(int argc, char **argv) { - // 检查标准错误输出是否为终端,以及环境变量是否开启安静模式 if (isatty(2) && !getenv("AFL_QUIET")) { - SAYF(cCYA "afl-cc " cBRI VERSION cRST " by \n"); } else be_quiet = 1; - // 检查传入的参数数量是否少于2 + // 检查传入的参数数量是否少于2,如果是则输出使用说明并退出 if (argc < 2) { - SAYF("\n" - "This is a helper application for afl-fuzz. It serves as a drop-in replacement\n" - "for gcc or clang, letting you recompile third-party code with the required\n" - "runtime instrumentation. A common use pattern would be one of the following:\n\n" + "这是一个辅助afl-fuzz的工具程序。它可以用作gcc或clang的替代品,\n" + "让你能够使用必要的运行时检测重新编译第三方代码。\n" + "常见的使用模式如下之一:\n\n" " CC=%s/afl-gcc ./configure\n" " CXX=%s/afl-g++ ./configure\n\n" - "You can specify custom next-stage toolchain via AFL_CC, AFL_CXX, and AFL_AS.\n" - "Setting AFL_HARDEN enables hardening optimizations in the compiled code.\n\n", + "你可以通过AFL_CC, AFL_CXX, 和 AFL_AS指定自定义的后续编译工具链。\n" + "设置AFL_HARDEN会在编译代码时启用hardening优化。\n\n", BIN_PATH, BIN_PATH); exit(1); } - // 查找汇编器 + // 查找汇编器,根据argv[0]来确定使用的编译器是gcc还是clang find_as(argv[0]); - // 编辑参数 + // 编辑命令行参数,根据需要添加和调整编译器参数 edit_params(argc, argv); - // 执行编译器,并传递参数 + // 执行编译器,并传递编辑后的参数列表 execvp(cc_params[0], (char **)cc_params); - // 如果执行失败,输出错误信息 + // 如果execvp调用失败,输出错误信息并退出程序 FATAL("Oops, failed to execute '%s' - check your PATH", cc_params[0]); return 0; diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c index 630b7ff..cb5c30d 100644 --- a/src/afl-gotcpu.c +++ b/src/afl-gotcpu.c @@ -57,104 +57,108 @@ /* Get unix time in microseconds. */ +// 定义一个函数来获取当前时间(以微秒为单位) static u64 get_cur_time_us(void) { - struct timeval tv; - struct timezone tz; + struct timeval tv; // 用于存储时间值 + struct timezone tz; // 用于存储时区信息 - gettimeofday(&tv, &tz); + gettimeofday(&tv, &tz); // 获取当前时间 + // 返回以微秒为单位的时间 return (tv.tv_sec * 1000000ULL) + tv.tv_usec; } - -/* Get CPU usage in microseconds. */ - +/* 获取CPU使用时间(以微秒为单位)。 */ static u64 get_cpu_usage_us(void) { - struct rusage u; + struct rusage u; // 用于存储进程资源使用情况 - getrusage(RUSAGE_SELF, &u); + getrusage(RUSAGE_SELF, &u); // 获取当前进程的资源使用情况 + // 返回用户态和内核态CPU使用时间之和(以微秒为单位) return (u.ru_utime.tv_sec * 1000000ULL) + u.ru_utime.tv_usec + (u.ru_stime.tv_sec * 1000000ULL) + u.ru_stime.tv_usec; } - -/* Measure preemption rate. */ - +/* 测量抢占率。 */ static u32 measure_preemption(u32 target_ms) { - static volatile u32 v1, v2; + static volatile u32 v1, v2; // 定义两个静态易失变量用于循环计数 - u64 st_t, en_t, st_c, en_c, real_delta, slice_delta; - s32 loop_repeats = 0; + u64 st_t, en_t, st_c, en_c, real_delta, slice_delta; // 定义时间变量 + s32 loop_repeats = 0; // 定义循环重复次数 - st_t = get_cur_time_us(); - st_c = get_cpu_usage_us(); + st_t = get_cur_time_us(); // 获取开始时间 + st_c = get_cpu_usage_us(); // 获取开始时的CPU使用时间 -repeat_loop: +repeat_loop: // 定义循环标签 - v1 = CTEST_BUSY_CYCLES; + v1 = CTEST_BUSY_CYCLES; // 设置v1为循环次数 + // 循环v1次,每次v2自增1,模拟CPU繁忙 while (v1--) v2++; - sched_yield(); + sched_yield(); // 让出CPU,允许其他进程运行 - en_t = get_cur_time_us(); + en_t = get_cur_time_us(); // 获取结束时间 + // 如果实际运行时间小于目标时间,则增加循环次数并继续循环 if (en_t - st_t < target_ms * 1000) { loop_repeats++; goto repeat_loop; } - /* Let's see what percentage of this time we actually had a chance to - run, and how much time was spent in the penalty box. */ - + // 获取结束时的CPU使用时间 en_c = get_cpu_usage_us(); + // 计算实际运行时间(以毫秒为单位) real_delta = (en_t - st_t) / 1000; + // 计算CPU使用时间(以毫秒为单位) slice_delta = (en_c - st_c) / 1000; + // 返回实际运行时间占CPU使用时间的百分比,作为抢占率 return real_delta * 100 / slice_delta; } - -/* Do the benchmark thing. */ - +/* 进行基准测试。 */ int main(int argc, char** argv) { -#ifdef HAVE_AFFINITY +#ifdef HAVE_AFFINITY // 如果支持AFFINITY(设置进程CPU亲和性) - u32 cpu_cnt = sysconf(_SC_NPROCESSORS_ONLN), - idle_cpus = 0, maybe_cpus = 0, i; + u32 cpu_cnt = sysconf(_SC_NPROCESSORS_ONLN), // 获取CPU核心数 + idle_cpus = 0, maybe_cpus = 0, i; // 初始化空闲和可能可用的CPU核心数 - SAYF(cCYA "afl-gotcpu " cBRI VERSION cRST " by \n"); + SAYF(cCYA "afl-gotcpu " cBRI VERSION cRST " by \n"); // 输出程序信息 + // 输出测量核心抢占率的信息,包括预计所需时间 ACTF("Measuring per-core preemption rate (this will take %0.02f sec)...", ((double)CTEST_CORE_TRG_MS) / 1000); + // 对每个CPU核心进行抢占率测量 for (i = 0; i < cpu_cnt; i++) { - s32 fr = fork(); + s32 fr = fork(); // 创建子进程 - if (fr < 0) PFATAL("fork failed"); + if (fr < 0) PFATAL("fork failed"); // 如果fork失败,则输出错误信息 - if (!fr) { + if (!fr) { // 子进程中 - cpu_set_t c; - u32 util_perc; + cpu_set_t c; // 定义CPU亲和性集合 + u32 util_perc; // 定义CPU利用率 - CPU_ZERO(&c); - CPU_SET(i, &c); + CPU_ZERO(&c); // 清空CPU亲和性集合 + CPU_SET(i, &c); // 设置亲和性为当前核心 + // 设置进程亲和性到指定的核心 if (sched_setaffinity(0, sizeof(c), &c)) PFATAL("sched_setaffinity failed for cpu %d", i); - util_perc = measure_preemption(CTEST_CORE_TRG_MS); + util_perc = measure_preemption(CTEST_CORE_TRG_MS); // 测量抢占率 + // 根据抢占率输出核心状态 if (util_perc < 110) { SAYF(" Core #%u: " cLGN "AVAILABLE " cRST "(%u%%)\n", i, util_perc); @@ -175,18 +179,21 @@ int main(int argc, char** argv) { } + // 等待所有子进程结束,并统计结果 for (i = 0; i < cpu_cnt; i++) { int ret; - if (waitpid(-1, &ret, 0) < 0) PFATAL("waitpid failed"); + if (waitpid(-1, &ret, 0) < 0) PFATAL("waitpid failed"); // 等待子进程结束 + // 根据子进程退出状态判断核心是否可用 if (WEXITSTATUS(ret) == 0) idle_cpus++; if (WEXITSTATUS(ret) <= 1) maybe_cpus++; } - SAYF(cGRA "\n>>> "); + SAYF(cGRA "\n>>> "); // 输出结果标题 + // 根据统计结果输出最终判断 if (idle_cpus) { if (maybe_cpus == idle_cpus) { @@ -201,24 +208,30 @@ int main(int argc, char** argv) { } - SAYF(cGRA " <<<" cRST "\n\n"); + SAYF(cGRA " <<<" cRST "\n\n"); // 输出结果结束标志 return 0; } + // 如果有可能可用的核心,但没有完全空闲的核心 if (maybe_cpus) { SAYF(cYEL "CAUTION: " cRST "You may still have %u core%s available.", maybe_cpus, maybe_cpus > 1 ? "s" : ""); - SAYF(cGRA " <<<" cRST "\n\n"); + SAYF(cGRA " <<<" cRST "\n\n"); // 输出结果结束标志 return 1; } + // 如果所有核心都过载 SAYF(cLRD "FAIL: " cRST "All cores are overbooked."); - SAYF(cGRA " <<<" cRST "\n\n"); + SAYF(cGRA " <<<" cRST "\n\n"); // 输出结果结束标志 return 2; +#endif + +} + #else u32 util_perc;