Skip to content

Potentially missing test cases generated from a simple loop #88

@thuanpv

Description

@thuanpv

Hello SymCC maintainers,

I have been trying to test how SymCC works on loops. To that end, I wrote a simple C program based on this example: https://github.com/AdaLogics/adacc/blob/master/examples/afl-sample.c. Following is my modified program (stored in example.c) and the function of interest is foo.

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

int foo(char *arr, int count) {
    int i = 0;

    for (i = 0; i < count; i++) {
      if (arr[i] == 'A' + i) return i;
    }

    if (*(int*)(arr) != 0x4d4f4f42) {
        return i;
    }
    return 0;
}

int main(int argc, char* argv[]) {
    // open file
    FILE *f = fopen(argv[1], "rb");

    // get file size
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);

    // read file contents
    fseek(f, 0, SEEK_SET);
    char *string = (char*)malloc(fsize + 1);
    fread(string, 1, fsize, f);
    fclose(f);

    // call into target
    int retval = foo(string, fsize);

    free(string);
    return retval;
}

I compiled this program and ran SymCC using the following commands

symcc example.c -o example
printf "xxxx" > seed
SYMCC_INPUT_FILE=seed ./example seed

I expected that SymCC would generate 5 test cases ("Axxx", "xBxx", "xxCx", "xxxD", and "BOOM"). However, somehow SymCC only generated 4 test cases, the string "xxxD" was missing.

It looked strange to me so I thought something had gone wrong. I modified the program and manually unrolled the loop 4 times; the modified foo function is listed below

int foo(char *arr, int count) {
    int i = 0;
    if (i < count) {
      if (arr[i] == 'A' + i) return i;
      i++;
    }

    if (i < count) {
      if (arr[i] == 'A' + i) return i;
      i++;
    }

    if (i < count) {
      if (arr[i] == 'A' + i) return i;
      i++;
    }

    if (i < count) {
      if (arr[i] == 'A' + i) return i;
      i++;
    }

    if (*(int*)(arr) != 0x4d4f4f42) {
        return i;
    }
    return 0;
}

Interestingly, when I ran SymCC with the new program, which was saved into example_loop_unrolled.c, SymCC generated 5 test cases as expected. The commands are similar to the above ones

symcc example_loop_unrolled.c -o example_loop_unrolled
SYMCC_INPUT_FILE=seed ./example_loop_unrolled seed

So I suspect that there are some issues in the loop-handling code of SymCC. Could you please confirm?

Thanks,

Thuan

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions