esbmc / esbmc

The efficient SMT-based context-bounded model checker (ESBMC)
http://esbmc.org/
Other
268 stars 90 forks source link

ESBMC Segmentation Fault #1513

Open Yiannis128 opened 8 months ago

Yiannis128 commented 8 months ago

Hi, I was running through the FormAI dataset with ESBMC-AI with the following parameters:

esbmc --overflow --memory-leak-check --timeout 30 --unwind 1 --multi-property --no-unwinding-assertions --no-remove-unreachable ~/git/formai/DATASETSUB/FormAI_52349.c

I have received the following output (stdout):

ESBMC version 7.4.0 64-bit x86_64 linux
Target: 64-bit little-endian x86_64-unknown-linux with esbmclibc
Parsing /home/yiannis/git/formai/DATASETSUB/FormAI_52349.c
Converting
Generating GOTO Program
GOTO program creation time: 0.082s
GOTO program processing time: 0.000s
Starting Bounded Model Checking
no body for function srand
Not unwinding loop 12 iteration 1   file string.c line 30 column 3 function strcpy
Not unwinding loop 34 iteration 1   file FormAI_52349.c line 26 column 5 function main
Symex completed in: 0.002s (58 assignments)
Slicing time: 0.000s (removed 32 assignments)
Generated 10 VCC(s), 10 remaining after simplification (26 assignments)
No solver specified; defaulting to Boolector
Slicing for Claim arithmetic overflow on add (0.000s)
Slicing time: 0.000s (removed 32 assignments)
No solver specified; defaulting to Boolector
Encoding remaining VCC(s) using bit-vector/floating-point arithmetic
zsh: segmentation fault (core dumped)  esbmc --overflow --memory-leak-check --timeout 30 --unwind 1 --multi-property

There was no stderr output.

The code of the sample is the following:

//FormAI DATASET v1.0 Category: Automated Fortune Teller ; Style: multiplayer
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define MAX_NAME_LENGTH 30
#define MAX_MESSAGE_LENGTH 100

struct Player {
    char name[MAX_NAME_LENGTH];
    char fortune[MAX_MESSAGE_LENGTH];
};

void generate_fortune(struct Player *player);

int main() {
    srand(time(NULL)); //set the random seed based on the current time
    int num_players;
    printf("Welcome to the Automated Fortune Teller!\nHow many players will be playing today? ");
    fflush(stdout); //force printing to the console before scanf
    scanf("%d", &num_players);

    struct Player players[num_players];

    for (int i = 0; i < num_players; i++) {
        printf("Player %d, what is your name? ", i + 1);
        fflush(stdout);
        scanf("%s", players[i].name);
        generate_fortune(&players[i]);
        printf("Hello %s, your fortune is: %s\n", players[i].name, players[i].fortune);
    }

    return 0; //exit program
}

void generate_fortune(struct Player *player) {
    char *fortunes[7] = {"Good things come to those who wait.", 
                         "Your future is looking bright!",
                         "The path to success is never easy, but it will be worth it.",
                         "You will soon receive a pleasant surprise.",
                         "Take a moment to reflect, it will benefit you in the long run.",
                         "Be patient with yourself and those around you.",
                         "Your hard work will pay off in due time."};
    //generate a random index to select a fortune
    int index = rand() % 7;
    strcpy(player->fortune, fortunes[index]); //copy the fortune to the player's struct
}
Yiannis128 commented 8 months ago

The following code (FormAI_58452.c) also produces a crash:

ESBMC version 7.4.0 64-bit x86_64 linux
Target: 64-bit little-endian x86_64-unknown-linux with esbmclibc
Parsing /home/yiannis/git/formai/DATASETSUB/FormAI_58452.c
Converting
Generating GOTO Program
GOTO program creation time: 0.051s
GOTO program processing time: 0.001s
Starting Bounded Model Checking
Not unwinding loop 35 iteration 1   file FormAI_58452.c line 30 column 5 function main
Not unwinding loop 34 iteration 1   file FormAI_58452.c line 16 column 5 function printRooms
Not unwinding loop 36 iteration 1   file FormAI_58452.c line 59 column 17 function main
Not unwinding loop 37 iteration 1   file FormAI_58452.c line 82 column 17 function main
Not unwinding loop 38 iteration 1   file FormAI_58452.c line 38 column 5 function main
Symex completed in: 0.002s (114 assignments)
Slicing time: 0.000s (removed 42 assignments)
Generated 31 VCC(s), 23 remaining after simplification (72 assignments)
No solver specified; defaulting to Boolector
Slicing for Claim arithmetic overflow on add (0.000s)
Slicing time: 0.000s (removed 42 assignments)
No solver specified; defaulting to Boolector
Encoding remaining VCC(s) using bit-vector/floating-point arithmetic
//FormAI DATASET v1.0 Category: Hotel Management System ; Style: relaxed
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Structure for each room's details.
struct Room {
    char name[20];
    int roomNumber;
    int occupancy;
};

// Function to print available rooms.
void printRooms(struct Room rooms[], int numRooms) {
    printf("List of available rooms: \n");
    for (int i = 0; i < numRooms; i++) {
        if (rooms[i].occupancy == 0) {
            printf("Room %d: %s \n", rooms[i].roomNumber, rooms[i].name);
        }
    }
}

int main() {
    int numRooms;
    printf("Enter the number of rooms in the hotel: ");
    scanf("%d", &numRooms);
    struct Room rooms[numRooms];

    // Get the details of each room from the user.
    for (int i = 0; i < numRooms; i++) {
        printf("Enter the name and room number for room %d: ", i+1);
        scanf("%s %d", &rooms[i].name, &rooms[i].roomNumber);
        rooms[i].occupancy = 0; // Set to 0 initially (i.e., room is not occupied).
    }

    // Main loop of the program.
    int choice = 0;
    while (choice != 4) {
        printf("\nMENU: \n");
        printf("1. Check room availability \n");
        printf("2. Book a room \n");
        printf("3. Check out of a room \n");
        printf("4. Exit \n");
        printf("Enter your choice (1-4): ");
        scanf("%d", &choice);

        switch(choice) {
            case 1:
                printRooms(rooms, numRooms);
                break;

            case 2:
                printf("Enter the room number you wish to book: ");
                int roomToBook;
                scanf("%d", &roomToBook);

                // Find the room with the given room number.
                int indexToBook;
                for (int i = 0; i < numRooms; i++) {
                    if (rooms[i].roomNumber == roomToBook) {
                        indexToBook = i;
                        break;
                    }
                }

                // If the room is available, book it.
                if (rooms[indexToBook].occupancy == 0) {
                    rooms[indexToBook].occupancy = 1;
                    printf("Room %d has been booked for you. Enjoy your stay!\n", rooms[indexToBook].roomNumber);
                } else {
                    printf("Sorry, the room is already occupied. Please choose a different room.\n");
                }
                break;

            case 3:
                printf("Enter the room number you wish to check out of: ");
                int roomToCheckOut;
                scanf("%d", &roomToCheckOut);

                // Find the room with the given room number.
                int indexToCheckOut;
                for (int i = 0; i < numRooms; i++) {
                    if (rooms[i].roomNumber == roomToCheckOut) {
                        indexToCheckOut = i;
                        break;
                    }
                }

                // If the room is occupied, check out and print the bill.
                if (rooms[indexToCheckOut].occupancy == 1) {
                    rooms[indexToCheckOut].occupancy = 0;
                    int bill = rand() % 500 + 500; // Generate random bill amount between $500-$1000.
                    printf("Thank you for your stay. Your bill is $%d.\n", bill);
                } else {
                    printf("Sorry, the room is not occupied. Please choose a different room.\n");
                }
                break;

            case 4:
                printf("Thank you for using the hotel management system!\n");
                break;

            default:
                printf("Invalid choice. Please try again.\n");
        }
    }

    return 0;
}
lucasccordeiro commented 8 months ago

@Yiannis128: we will be able to check this issue just after the SV-COMP 2024 deadline.

fbrausse commented 8 months ago

The first one is an error in the array_convt during smt conversion. It has to do with nondet-size'd array symbols, i.e., this VLA: struct Player players[num_players];

The second example works for me on the current master branch, when using the same flags as for the first one. @Yiannis128 could you try the second one again with an updated version of ESBMC?