18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2018, Breno Leitao, IBM Corp. 48c2ecf20Sopenharmony_ci * Licensed under GPLv2. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Sigfuz(tm): A PowerPC TM-aware signal fuzzer. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This is a new selftest that raises SIGUSR1 signals and handles it in a set 98c2ecf20Sopenharmony_ci * of different ways, trying to create different scenario for testing 108c2ecf20Sopenharmony_ci * purpose. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * This test works raising a signal and calling sigreturn interleaved with 138c2ecf20Sopenharmony_ci * TM operations, as starting, suspending and terminating a transaction. The 148c2ecf20Sopenharmony_ci * test depends on random numbers, and, based on them, it sets different TM 158c2ecf20Sopenharmony_ci * states. 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * Other than that, the test fills out the user context struct that is passed 188c2ecf20Sopenharmony_ci * to the sigreturn system call with random data, in order to make sure that 198c2ecf20Sopenharmony_ci * the signal handler syscall can handle different and invalid states 208c2ecf20Sopenharmony_ci * properly. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * This selftest has command line parameters to control what kind of tests the 238c2ecf20Sopenharmony_ci * user wants to run, as for example, if a transaction should be started prior 248c2ecf20Sopenharmony_ci * to signal being raised, or, after the signal being raised and before the 258c2ecf20Sopenharmony_ci * sigreturn. If no parameter is given, the default is enabling all options. 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * This test does not check if the user context is being read and set 288c2ecf20Sopenharmony_ci * properly by the kernel. Its purpose, at this time, is basically 298c2ecf20Sopenharmony_ci * guaranteeing that the kernel does not crash on invalid scenarios. 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#include <stdio.h> 338c2ecf20Sopenharmony_ci#include <limits.h> 348c2ecf20Sopenharmony_ci#include <sys/wait.h> 358c2ecf20Sopenharmony_ci#include <unistd.h> 368c2ecf20Sopenharmony_ci#include <stdlib.h> 378c2ecf20Sopenharmony_ci#include <signal.h> 388c2ecf20Sopenharmony_ci#include <string.h> 398c2ecf20Sopenharmony_ci#include <ucontext.h> 408c2ecf20Sopenharmony_ci#include <sys/mman.h> 418c2ecf20Sopenharmony_ci#include <pthread.h> 428c2ecf20Sopenharmony_ci#include "utils.h" 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* Selftest defaults */ 458c2ecf20Sopenharmony_ci#define COUNT_MAX 600 /* Number of interactions */ 468c2ecf20Sopenharmony_ci#define THREADS 16 /* Number of threads */ 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* Arguments options */ 498c2ecf20Sopenharmony_ci#define ARG_MESS_WITH_TM_AT 0x1 508c2ecf20Sopenharmony_ci#define ARG_MESS_WITH_TM_BEFORE 0x2 518c2ecf20Sopenharmony_ci#define ARG_MESS_WITH_MSR_AT 0x4 528c2ecf20Sopenharmony_ci#define ARG_FOREVER 0x10 538c2ecf20Sopenharmony_ci#define ARG_COMPLETE (ARG_MESS_WITH_TM_AT | \ 548c2ecf20Sopenharmony_ci ARG_MESS_WITH_TM_BEFORE | \ 558c2ecf20Sopenharmony_ci ARG_MESS_WITH_MSR_AT) 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic int args; 588c2ecf20Sopenharmony_cistatic int nthread = THREADS; 598c2ecf20Sopenharmony_cistatic int count_max = COUNT_MAX; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* checkpoint context */ 628c2ecf20Sopenharmony_cistatic ucontext_t *tmp_uc; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/* Return true with 1/x probability */ 658c2ecf20Sopenharmony_cistatic int one_in_chance(int x) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci return rand() % x == 0; 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci/* Change TM states */ 718c2ecf20Sopenharmony_cistatic void mess_with_tm(void) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci /* Starts a transaction 33% of the time */ 748c2ecf20Sopenharmony_ci if (one_in_chance(3)) { 758c2ecf20Sopenharmony_ci asm ("tbegin. ;" 768c2ecf20Sopenharmony_ci "beq 8 ;"); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* And suspended half of them */ 798c2ecf20Sopenharmony_ci if (one_in_chance(2)) 808c2ecf20Sopenharmony_ci asm("tsuspend. ;"); 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci /* Call 'tend' in 5% of the runs */ 848c2ecf20Sopenharmony_ci if (one_in_chance(20)) 858c2ecf20Sopenharmony_ci asm("tend. ;"); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/* Signal handler that will be invoked with raise() */ 898c2ecf20Sopenharmony_cistatic void trap_signal_handler(int signo, siginfo_t *si, void *uc) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci ucontext_t *ucp = uc; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci ucp->uc_link = tmp_uc; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci /* 968c2ecf20Sopenharmony_ci * Set uc_link in three possible ways: 978c2ecf20Sopenharmony_ci * - Setting a single 'int' in the whole chunk 988c2ecf20Sopenharmony_ci * - Cloning ucp into uc_link 998c2ecf20Sopenharmony_ci * - Allocating a new memory chunk 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_ci if (one_in_chance(3)) { 1028c2ecf20Sopenharmony_ci memset(ucp->uc_link, rand(), sizeof(ucontext_t)); 1038c2ecf20Sopenharmony_ci } else if (one_in_chance(2)) { 1048c2ecf20Sopenharmony_ci memcpy(ucp->uc_link, uc, sizeof(ucontext_t)); 1058c2ecf20Sopenharmony_ci } else if (one_in_chance(2)) { 1068c2ecf20Sopenharmony_ci if (tmp_uc) { 1078c2ecf20Sopenharmony_ci free(tmp_uc); 1088c2ecf20Sopenharmony_ci tmp_uc = NULL; 1098c2ecf20Sopenharmony_ci } 1108c2ecf20Sopenharmony_ci tmp_uc = malloc(sizeof(ucontext_t)); 1118c2ecf20Sopenharmony_ci ucp->uc_link = tmp_uc; 1128c2ecf20Sopenharmony_ci /* Trying to cause a major page fault at Kernel level */ 1138c2ecf20Sopenharmony_ci madvise(ucp->uc_link, sizeof(ucontext_t), MADV_DONTNEED); 1148c2ecf20Sopenharmony_ci } 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci if (args & ARG_MESS_WITH_MSR_AT) { 1178c2ecf20Sopenharmony_ci /* Changing the checkpointed registers */ 1188c2ecf20Sopenharmony_ci if (one_in_chance(4)) { 1198c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |= MSR_TS_S; 1208c2ecf20Sopenharmony_ci } else { 1218c2ecf20Sopenharmony_ci if (one_in_chance(2)) { 1228c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |= 1238c2ecf20Sopenharmony_ci MSR_TS_T; 1248c2ecf20Sopenharmony_ci } else if (one_in_chance(2)) { 1258c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] |= 1268c2ecf20Sopenharmony_ci MSR_TS_T | MSR_TS_S; 1278c2ecf20Sopenharmony_ci } 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci /* Checking the current register context */ 1318c2ecf20Sopenharmony_ci if (one_in_chance(2)) { 1328c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_MSR] |= MSR_TS_S; 1338c2ecf20Sopenharmony_ci } else if (one_in_chance(2)) { 1348c2ecf20Sopenharmony_ci if (one_in_chance(2)) 1358c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_MSR] |= 1368c2ecf20Sopenharmony_ci MSR_TS_T; 1378c2ecf20Sopenharmony_ci else if (one_in_chance(2)) 1388c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_MSR] |= 1398c2ecf20Sopenharmony_ci MSR_TS_T | MSR_TS_S; 1408c2ecf20Sopenharmony_ci } 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci if (one_in_chance(20)) { 1448c2ecf20Sopenharmony_ci /* Nested transaction start */ 1458c2ecf20Sopenharmony_ci if (one_in_chance(5)) 1468c2ecf20Sopenharmony_ci mess_with_tm(); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci /* Return without changing any other context info */ 1498c2ecf20Sopenharmony_ci return; 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci if (one_in_chance(10)) 1538c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_MSR] = random(); 1548c2ecf20Sopenharmony_ci if (one_in_chance(10)) 1558c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_NIP] = random(); 1568c2ecf20Sopenharmony_ci if (one_in_chance(10)) 1578c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_MSR] = random(); 1588c2ecf20Sopenharmony_ci if (one_in_chance(10)) 1598c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_NIP] = random(); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_TRAP] = random(); 1628c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_DSISR] = random(); 1638c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_DAR] = random(); 1648c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_ORIG_R3] = random(); 1658c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_XER] = random(); 1668c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_RESULT] = random(); 1678c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_SOFTE] = random(); 1688c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_DSCR] = random(); 1698c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_CTR] = random(); 1708c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_LNK] = random(); 1718c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_CCR] = random(); 1728c2ecf20Sopenharmony_ci ucp->uc_mcontext.gp_regs[PT_REGS_COUNT] = random(); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_TRAP] = random(); 1758c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_DSISR] = random(); 1768c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_DAR] = random(); 1778c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_ORIG_R3] = random(); 1788c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_XER] = random(); 1798c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_RESULT] = random(); 1808c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_SOFTE] = random(); 1818c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_DSCR] = random(); 1828c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_CTR] = random(); 1838c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_LNK] = random(); 1848c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_CCR] = random(); 1858c2ecf20Sopenharmony_ci ucp->uc_link->uc_mcontext.gp_regs[PT_REGS_COUNT] = random(); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci if (args & ARG_MESS_WITH_TM_BEFORE) { 1888c2ecf20Sopenharmony_ci if (one_in_chance(2)) 1898c2ecf20Sopenharmony_ci mess_with_tm(); 1908c2ecf20Sopenharmony_ci } 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic void seg_signal_handler(int signo, siginfo_t *si, void *uc) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci /* Clear exit for process that segfaults */ 1968c2ecf20Sopenharmony_ci exit(0); 1978c2ecf20Sopenharmony_ci} 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistatic void *sigfuz_test(void *thrid) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci struct sigaction trap_sa, seg_sa; 2028c2ecf20Sopenharmony_ci int ret, i = 0; 2038c2ecf20Sopenharmony_ci pid_t t; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci tmp_uc = malloc(sizeof(ucontext_t)); 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci /* Main signal handler */ 2088c2ecf20Sopenharmony_ci trap_sa.sa_flags = SA_SIGINFO; 2098c2ecf20Sopenharmony_ci trap_sa.sa_sigaction = trap_signal_handler; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci /* SIGSEGV signal handler */ 2128c2ecf20Sopenharmony_ci seg_sa.sa_flags = SA_SIGINFO; 2138c2ecf20Sopenharmony_ci seg_sa.sa_sigaction = seg_signal_handler; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci /* The signal handler will enable MSR_TS */ 2168c2ecf20Sopenharmony_ci sigaction(SIGUSR1, &trap_sa, NULL); 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci /* If it does not crash, it will segfault, avoid it to retest */ 2198c2ecf20Sopenharmony_ci sigaction(SIGSEGV, &seg_sa, NULL); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci while (i < count_max) { 2228c2ecf20Sopenharmony_ci t = fork(); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci if (t == 0) { 2258c2ecf20Sopenharmony_ci /* Once seed per process */ 2268c2ecf20Sopenharmony_ci srand(time(NULL) + getpid()); 2278c2ecf20Sopenharmony_ci if (args & ARG_MESS_WITH_TM_AT) { 2288c2ecf20Sopenharmony_ci if (one_in_chance(2)) 2298c2ecf20Sopenharmony_ci mess_with_tm(); 2308c2ecf20Sopenharmony_ci } 2318c2ecf20Sopenharmony_ci raise(SIGUSR1); 2328c2ecf20Sopenharmony_ci exit(0); 2338c2ecf20Sopenharmony_ci } else { 2348c2ecf20Sopenharmony_ci waitpid(t, &ret, 0); 2358c2ecf20Sopenharmony_ci } 2368c2ecf20Sopenharmony_ci if (!(args & ARG_FOREVER)) 2378c2ecf20Sopenharmony_ci i++; 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci /* If not freed already, free now */ 2418c2ecf20Sopenharmony_ci if (tmp_uc) { 2428c2ecf20Sopenharmony_ci free(tmp_uc); 2438c2ecf20Sopenharmony_ci tmp_uc = NULL; 2448c2ecf20Sopenharmony_ci } 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci return NULL; 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic int signal_fuzzer(void) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci int t, rc; 2528c2ecf20Sopenharmony_ci pthread_t *threads; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci threads = malloc(nthread * sizeof(pthread_t)); 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci for (t = 0; t < nthread; t++) { 2578c2ecf20Sopenharmony_ci rc = pthread_create(&threads[t], NULL, sigfuz_test, 2588c2ecf20Sopenharmony_ci (void *)&t); 2598c2ecf20Sopenharmony_ci if (rc) 2608c2ecf20Sopenharmony_ci perror("Thread creation error\n"); 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci for (t = 0; t < nthread; t++) { 2648c2ecf20Sopenharmony_ci rc = pthread_join(threads[t], NULL); 2658c2ecf20Sopenharmony_ci if (rc) 2668c2ecf20Sopenharmony_ci perror("Thread join error\n"); 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci free(threads); 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci return EXIT_SUCCESS; 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_cistatic void show_help(char *name) 2758c2ecf20Sopenharmony_ci{ 2768c2ecf20Sopenharmony_ci printf("%s: Sigfuzzer for powerpc\n", name); 2778c2ecf20Sopenharmony_ci printf("Usage:\n"); 2788c2ecf20Sopenharmony_ci printf("\t-b\t Mess with TM before raising a SIGUSR1 signal\n"); 2798c2ecf20Sopenharmony_ci printf("\t-a\t Mess with TM after raising a SIGUSR1 signal\n"); 2808c2ecf20Sopenharmony_ci printf("\t-m\t Mess with MSR[TS] bits at mcontext\n"); 2818c2ecf20Sopenharmony_ci printf("\t-x\t Mess with everything above\n"); 2828c2ecf20Sopenharmony_ci printf("\t-f\t Run forever (Press ^C to Quit)\n"); 2838c2ecf20Sopenharmony_ci printf("\t-i\t Amount of interactions. (Default = %d)\n", COUNT_MAX); 2848c2ecf20Sopenharmony_ci printf("\t-t\t Amount of threads. (Default = %d)\n", THREADS); 2858c2ecf20Sopenharmony_ci exit(-1); 2868c2ecf20Sopenharmony_ci} 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ciint main(int argc, char **argv) 2898c2ecf20Sopenharmony_ci{ 2908c2ecf20Sopenharmony_ci int opt; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci while ((opt = getopt(argc, argv, "bamxt:fi:h")) != -1) { 2938c2ecf20Sopenharmony_ci if (opt == 'b') { 2948c2ecf20Sopenharmony_ci printf("Mess with TM before signal\n"); 2958c2ecf20Sopenharmony_ci args |= ARG_MESS_WITH_TM_BEFORE; 2968c2ecf20Sopenharmony_ci } else if (opt == 'a') { 2978c2ecf20Sopenharmony_ci printf("Mess with TM at signal handler\n"); 2988c2ecf20Sopenharmony_ci args |= ARG_MESS_WITH_TM_AT; 2998c2ecf20Sopenharmony_ci } else if (opt == 'm') { 3008c2ecf20Sopenharmony_ci printf("Mess with MSR[TS] bits in mcontext\n"); 3018c2ecf20Sopenharmony_ci args |= ARG_MESS_WITH_MSR_AT; 3028c2ecf20Sopenharmony_ci } else if (opt == 'x') { 3038c2ecf20Sopenharmony_ci printf("Running with all options enabled\n"); 3048c2ecf20Sopenharmony_ci args |= ARG_COMPLETE; 3058c2ecf20Sopenharmony_ci } else if (opt == 't') { 3068c2ecf20Sopenharmony_ci nthread = atoi(optarg); 3078c2ecf20Sopenharmony_ci printf("Threads = %d\n", nthread); 3088c2ecf20Sopenharmony_ci } else if (opt == 'f') { 3098c2ecf20Sopenharmony_ci args |= ARG_FOREVER; 3108c2ecf20Sopenharmony_ci printf("Press ^C to stop\n"); 3118c2ecf20Sopenharmony_ci test_harness_set_timeout(-1); 3128c2ecf20Sopenharmony_ci } else if (opt == 'i') { 3138c2ecf20Sopenharmony_ci count_max = atoi(optarg); 3148c2ecf20Sopenharmony_ci printf("Running for %d interactions\n", count_max); 3158c2ecf20Sopenharmony_ci } else if (opt == 'h') { 3168c2ecf20Sopenharmony_ci show_help(argv[0]); 3178c2ecf20Sopenharmony_ci } 3188c2ecf20Sopenharmony_ci } 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci /* Default test suite */ 3218c2ecf20Sopenharmony_ci if (!args) 3228c2ecf20Sopenharmony_ci args = ARG_COMPLETE; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci test_harness(signal_fuzzer, "signal_fuzzer"); 3258c2ecf20Sopenharmony_ci} 326