Menu

Code snippet that takes forever to finish scanning

ryan
2023-09-21
2023-09-22
  • ryan

    ryan - 2023-09-21

    Cppcheck Version: 2.9

    Command: cppcheck --enable=warning,unusedFunction ./theFile.c -v --max-configs=2 --xml 2> ./out.xml

    Following is from "redis-cli.c". Trimmed to reproduce minimum working example

    static int parseOptions(int argc, char **argv) {
        int i;
    
        for (i = 1; i < argc; i++) {
            int lastarg = i==argc-1;
    
            if (!strcmp(argv[i],"-h") && !lastarg) {
                sdsfree(config.conn_info.hostip);
                config.conn_info.hostip = sdsnew(argv[++i]);
            } else if (!strcmp(argv[i],"-h") && lastarg) {
                usage(0);
            } else if (!strcmp(argv[i],"--help")) {
                usage(0);
            } else if (!strcmp(argv[i],"-x")) {
                config.stdin_lastarg = 1;
            } else if (!strcmp(argv[i], "-X") && !lastarg) {
                config.stdin_tag_arg = 1;
                config.stdin_tag_name = argv[++i];
            } else if (!strcmp(argv[i],"-p") && !lastarg) {
                config.conn_info.hostport = atoi(argv[++i]);
                if (config.conn_info.hostport < 0 || config.conn_info.hostport > 65535) {
                    fprintf(stderr, "Invalid server port.\n");
                    exit(1);
                }
            } else if (!strcmp(argv[i],"-s") && !lastarg) {
                config.hostsocket = argv[++i];
            } else if (!strcmp(argv[i],"-r") && !lastarg) {
                config.repeat = strtoll(argv[++i],NULL,10);
            } else if (!strcmp(argv[i],"-i") && !lastarg) {
                double seconds = atof(argv[++i]);
                config.interval = seconds*1000000;
            } else if (!strcmp(argv[i],"-n") && !lastarg) {
                config.conn_info.input_dbnum = atoi(argv[++i]);
            } else if (!strcmp(argv[i], "--no-auth-warning")) {
                config.no_auth_warning = 1;
            } else if (!strcmp(argv[i], "--askpass")) {
                config.askpass = 1;
            } else if ((!strcmp(argv[i],"-a") || !strcmp(argv[i],"--pass"))
                       && !lastarg)
            {
                config.conn_info.auth = sdsnew(argv[++i]);
            } else if (!strcmp(argv[i],"--user") && !lastarg) {
                config.conn_info.user = sdsnew(argv[++i]);
            } else if (!strcmp(argv[i],"-u") && !lastarg) {
                parseRedisUri(argv[++i],"redis-cli",&config.conn_info,&config.tls);
                if (config.conn_info.hostport < 0 || config.conn_info.hostport > 65535) {
                    fprintf(stderr, "Invalid server port.\n");
                    exit(1);
                }
            } else if (!strcmp(argv[i],"--raw")) {
                config.output = OUTPUT_RAW;
            } else if (!strcmp(argv[i],"--no-raw")) {
                config.output = OUTPUT_STANDARD;
            } else if (!strcmp(argv[i],"--quoted-input")) {
                config.quoted_input = 1;
            } else if (!strcmp(argv[i],"--csv")) {
                config.output = OUTPUT_CSV;
            } else if (!strcmp(argv[i],"--json")) {
                /* Not overwrite explicit value by -3 */
                if (config.resp3 == 0) {
                    config.resp3 = 2;
                }
                config.output = OUTPUT_JSON;
            } else if (!strcmp(argv[i],"--quoted-json")) {
                /* Not overwrite explicit value by -3*/
                if (config.resp3 == 0) {
                    config.resp3 = 2;
                }
                config.output = OUTPUT_QUOTED_JSON;
            } else if (!strcmp(argv[i],"--latency")) {
                config.latency_mode = 1;
            } else if (!strcmp(argv[i],"--latency-dist")) {
                config.latency_dist_mode = 1;
            } else if (!strcmp(argv[i],"--mono")) {
                spectrum_palette = spectrum_palette_mono;
                spectrum_palette_size = spectrum_palette_mono_size;
            } else if (!strcmp(argv[i],"--latency-history")) {
                config.latency_mode = 1;
                config.latency_history = 1;
            } else if (!strcmp(argv[i],"--lru-test") && !lastarg) {
                config.lru_test_mode = 1;
                config.lru_test_sample_size = strtoll(argv[++i],NULL,10);
            } else if (!strcmp(argv[i],"--slave")) {
                config.slave_mode = 1;
            } else if (!strcmp(argv[i],"--replica")) {
                config.slave_mode = 1;
            } else if (!strcmp(argv[i],"--stat")) {
                config.stat_mode = 1;
            } else if (!strcmp(argv[i],"--scan")) {
                config.scan_mode = 1;
            } else if (!strcmp(argv[i],"--pattern") && !lastarg) {
                sdsfree(config.pattern);
                config.pattern = sdsnew(argv[++i]);
            } else if (!strcmp(argv[i],"--count") && !lastarg) {
                config.count = atoi(argv[++i]);
            } else if (!strcmp(argv[i],"--quoted-pattern") && !lastarg) {
                sdsfree(config.pattern);
                config.pattern = unquoteCString(argv[++i]);
                if (!config.pattern) {
                    fprintf(stderr,"Invalid quoted string specified for --quoted-pattern.\n");
                    exit(1);
                }
            } else if (!strcmp(argv[i],"--intrinsic-latency") && !lastarg) {
                config.intrinsic_latency_mode = 1;
                config.intrinsic_latency_duration = atoi(argv[++i]);
            } else if (!strcmp(argv[i],"--rdb") && !lastarg) {
                config.getrdb_mode = 1;
                config.rdb_filename = argv[++i];
            } else if (!strcmp(argv[i],"--functions-rdb") && !lastarg) {
                config.get_functions_rdb_mode = 1;
                config.rdb_filename = argv[++i];
            } else if (!strcmp(argv[i],"--pipe")) {
                config.pipe_mode = 1;
            } else if (!strcmp(argv[i],"--pipe-timeout") && !lastarg) {
                config.pipe_timeout = atoi(argv[++i]);
            } else if (!strcmp(argv[i],"--bigkeys")) {
                config.bigkeys = 1;
            } else if (!strcmp(argv[i],"--memkeys")) {
                config.memkeys = 1;
                config.memkeys_samples = 0; /* use redis default */
            } else if (!strcmp(argv[i],"--memkeys-samples") && !lastarg) {
                config.memkeys = 1;
                config.memkeys_samples = atoi(argv[++i]);
            } else if (!strcmp(argv[i],"--hotkeys")) {
                config.hotkeys = 1;
            } else if (!strcmp(argv[i],"--eval") && !lastarg) {
                config.eval = argv[++i];
            } else if (!strcmp(argv[i],"--ldb")) {
                config.eval_ldb = 1;
                config.output = OUTPUT_RAW;
            } else if (!strcmp(argv[i],"--ldb-sync-mode")) {
                config.eval_ldb = 1;
                config.eval_ldb_sync = 1;
                config.output = OUTPUT_RAW;
            } else if (!strcmp(argv[i],"-c")) {
                config.cluster_mode = 1;
            } else if (!strcmp(argv[i],"-d") && !lastarg) {
                sdsfree(config.mb_delim);
                config.mb_delim = sdsnew(argv[++i]);
            } else if (!strcmp(argv[i],"-D") && !lastarg) {
                sdsfree(config.cmd_delim);
                config.cmd_delim = sdsnew(argv[++i]);
            } else if (!strcmp(argv[i],"-e")) {
                config.set_errcode = 1;
            } else if (!strcmp(argv[i],"--verbose")) {
                config.verbose = 1;
            } else if (!strcmp(argv[i],"--cluster") && !lastarg) {
                if (CLUSTER_MANAGER_MODE()) usage(1);
                char *cmd = argv[++i];
                int j = i;
                while (j < argc && argv[j][0] != '-') j++;
                if (j > i) j--;
                int err = createClusterManagerCommand(cmd, j - i, argv + i + 1);
                if (err) exit(err);
                i = j;
            } else if (!strcmp(argv[i],"--cluster") && lastarg) {
                usage(1);
            } else if ((!strcmp(argv[i],"--cluster-only-masters"))) {
                config.cluster_manager_command.flags |=
                        CLUSTER_MANAGER_CMD_FLAG_MASTERS_ONLY;
            } else if ((!strcmp(argv[i],"--cluster-only-replicas"))) {
                config.cluster_manager_command.flags |=
                        CLUSTER_MANAGER_CMD_FLAG_SLAVES_ONLY;
            } else if (!strcmp(argv[i],"--cluster-replicas") && !lastarg) {
                config.cluster_manager_command.replicas = atoi(argv[++i]);
            } else if (!strcmp(argv[i],"--cluster-master-id") && !lastarg) {
                config.cluster_manager_command.master_id = argv[++i];
            } else if (!strcmp(argv[i],"--cluster-from") && !lastarg) {
                config.cluster_manager_command.from = argv[++i];
            } else if (!strcmp(argv[i],"--cluster-to") && !lastarg) {
                config.cluster_manager_command.to = argv[++i];
            } else if (!strcmp(argv[i],"--cluster-from-user") && !lastarg) {
                config.cluster_manager_command.from_user = argv[++i];
            } else if (!strcmp(argv[i],"--cluster-from-pass") && !lastarg) {
                config.cluster_manager_command.from_pass = argv[++i];
            } else if (!strcmp(argv[i], "--cluster-from-askpass")) {
                config.cluster_manager_command.from_askpass = 1;
            } else if (!strcmp(argv[i],"--cluster-weight") && !lastarg) {
                if (config.cluster_manager_command.weight != NULL) {
                    fprintf(stderr, "WARNING: you cannot use --cluster-weight "
                                    "more than once.\n"
                                    "You can set more weights by adding them "
                                    "as a space-separated list, ie:\n"
                                    "--cluster-weight n1=w n2=w\n");
                    exit(1);
                }
                int widx = i + 1;
                char **weight = argv + widx;
                int wargc = 0;
                for (; widx < argc; widx++) {
                    if (strstr(argv[widx], "--") == argv[widx]) break;
                    if (strchr(argv[widx], '=') == NULL) break;
                    wargc++;
                }
                if (wargc > 0) {
                    config.cluster_manager_command.weight = weight;
                    config.cluster_manager_command.weight_argc = wargc;
                    i += wargc;
                }
            } else if (!strcmp(argv[i],"--cluster-slots") && !lastarg) {
                config.cluster_manager_command.slots = atoi(argv[++i]);
            } else if (!strcmp(argv[i],"--cluster-timeout") && !lastarg) {
                config.cluster_manager_command.timeout = atoi(argv[++i]);
            } else if (!strcmp(argv[i],"--cluster-pipeline") && !lastarg) {
                config.cluster_manager_command.pipeline = atoi(argv[++i]);
            } else if (!strcmp(argv[i],"--cluster-threshold") && !lastarg) {
                config.cluster_manager_command.threshold = atof(argv[++i]);
            } else if (!strcmp(argv[i],"--cluster-yes")) {
                config.cluster_manager_command.flags |=
                    CLUSTER_MANAGER_CMD_FLAG_YES;
            } else if (!strcmp(argv[i],"--cluster-simulate")) {
                config.cluster_manager_command.flags |=
                    CLUSTER_MANAGER_CMD_FLAG_SIMULATE;
            } else if (!strcmp(argv[i],"--cluster-replace")) {
                config.cluster_manager_command.flags |=
                    CLUSTER_MANAGER_CMD_FLAG_REPLACE;
            } else if (!strcmp(argv[i],"--cluster-copy")) {
                config.cluster_manager_command.flags |=
                    CLUSTER_MANAGER_CMD_FLAG_COPY;
            } else if (!strcmp(argv[i],"--cluster-slave")) {
                config.cluster_manager_command.flags |=
                    CLUSTER_MANAGER_CMD_FLAG_SLAVE;
            } else if (!strcmp(argv[i],"--cluster-use-empty-masters")) {
                config.cluster_manager_command.flags |=
                    CLUSTER_MANAGER_CMD_FLAG_EMPTYMASTER;
            } else if (!strcmp(argv[i],"--cluster-search-multiple-owners")) {
                config.cluster_manager_command.flags |=
                    CLUSTER_MANAGER_CMD_FLAG_CHECK_OWNERS;
            } else if (!strcmp(argv[i],"--cluster-fix-with-unreachable-masters")) {
                config.cluster_manager_command.flags |=
                    CLUSTER_MANAGER_CMD_FLAG_FIX_WITH_UNREACHABLE_MASTERS;
            } else if (!strcmp(argv[i],"--test_hint") && !lastarg) {
                config.test_hint = argv[++i];
            } else if (!strcmp(argv[i],"--test_hint_file") && !lastarg) {
                config.test_hint_file = argv[++i];
    #ifdef USE_OPENSSL
            } else if (!strcmp(argv[i],"--tls")) {
                config.tls = 1;
            } else if (!strcmp(argv[i],"--sni") && !lastarg) {
                config.sslconfig.sni = argv[++i];
            } else if (!strcmp(argv[i],"--cacertdir") && !lastarg) {
                config.sslconfig.cacertdir = argv[++i];
            } else if (!strcmp(argv[i],"--cacert") && !lastarg) {
                config.sslconfig.cacert = argv[++i];
            } else if (!strcmp(argv[i],"--cert") && !lastarg) {
                config.sslconfig.cert = argv[++i];
            } else if (!strcmp(argv[i],"--key") && !lastarg) {
                config.sslconfig.key = argv[++i];
            } else if (!strcmp(argv[i],"--tls-ciphers") && !lastarg) {
                config.sslconfig.ciphers = argv[++i];
            } else if (!strcmp(argv[i],"--insecure")) {
                config.sslconfig.skip_cert_verify = 1;
            #ifdef TLS1_3_VERSION
            } else if (!strcmp(argv[i],"--tls-ciphersuites") && !lastarg) {
                config.sslconfig.ciphersuites = argv[++i];
            #endif
    #endif
            } else if (!strcmp(argv[i],"-v") || !strcmp(argv[i], "--version")) {
                sds version = cliVersion();
                printf("redis-cli %s\n", version);
                sdsfree(version);
                exit(0);
            } else if (!strcmp(argv[i],"-2")) {
                config.resp2 = 1;
            } else if (!strcmp(argv[i],"-3")) {
                config.resp3 = 1;
            } else if (!strcmp(argv[i],"--show-pushes") && !lastarg) {
                char *argval = argv[++i];
                if (!strncasecmp(argval, "n", 1)) {
                    config.push_output = 0;
                } else if (!strncasecmp(argval, "y", 1)) {
                    config.push_output = 1;
                } else {
                    fprintf(stderr, "Unknown --show-pushes value '%s' "
                            "(valid: '[y]es', '[n]o')\n", argval);
                }
            } else if (CLUSTER_MANAGER_MODE() && argv[i][0] != '-') {
                if (config.cluster_manager_command.argc == 0) {
                    int j = i + 1;
                    while (j < argc && argv[j][0] != '-') j++;
                    int cmd_argc = j - i;
                    config.cluster_manager_command.argc = cmd_argc;
                    config.cluster_manager_command.argv = argv + i;
                    if (cmd_argc > 1) i = j - 1;
                }
            } else {
                if (argv[i][0] == '-') {
                    fprintf(stderr,
                        "Unrecognized option or bad number of args for: '%s'\n",
                        argv[i]);
                    exit(1);
                } else {
                    /* Likely the command name, stop here. */
                    break;
                }
            }
        }
    
        if (config.hostsocket && config.cluster_mode) {
            fprintf(stderr,"Options -c and -s are mutually exclusive.\n");
            exit(1);
        }
    
        if (config.resp2 && config.resp3 == 1) {
            fprintf(stderr,"Options -2 and -3 are mutually exclusive.\n");
            exit(1);
        }
    
        /* --ldb requires --eval. */
        if (config.eval_ldb && config.eval == NULL) {
            fprintf(stderr,"Options --ldb and --ldb-sync-mode require --eval.\n");
            fprintf(stderr,"Try %s --help for more information.\n", argv[0]);
            exit(1);
        }
    
        if (!config.no_auth_warning && config.conn_info.auth != NULL) {
            fputs("Warning: Using a password with '-a' or '-u' option on the command"
                  " line interface may not be safe.\n", stderr);
        }
    
        if (config.get_functions_rdb_mode && config.getrdb_mode) {
            fprintf(stderr,"Option --functions-rdb and --rdb are mutually exclusive.\n");
            exit(1);
        }
    
        if (config.stdin_lastarg && config.stdin_tag_arg) {
            fprintf(stderr, "Options -x and -X are mutually exclusive.\n");
            exit(1);
        }
    
        return i;
    }
    
     
  • CHR

    CHR - 2023-09-21
     
    • ryan

      ryan - 2023-09-22

      Thanks. This pr seems to be a fix but has been withdrawn? https://github.com/danmar/cppcheck/pull/5103

       
      • CHR

        CHR - 2023-09-22
         
        • ryan

          ryan - 2023-09-22

          Good. But this doesn't seem to solve "is-else" hell and it still take very long time to finish.
          From callgrind dump, token::simpleMatch has been called millions of times. Would it be possible to create certain cache mechanism to decrease such calls? If not, could u provide any suggestions? Thanks a lot!

           
        • ryan

          ryan - 2023-09-22

          Choosed two random open source repos on github: redis and ffmpeg. Both have the same issue so I think this is a common problem that can/need to be solved.

           
          • ryan

            ryan - 2023-09-22

            Forgot to mention that I am using the latest version:V2.12.0 not the v2.9.0. Thats why I think the pr doesn't resolve the problem completely.

             

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.