user2376308
user2376308

Reputation: 1

Segmentation fault (core dumped) when parsing char data

I need your help. I have a program to read gps and accelerometer data from port. The programm work like this : when I send 'a' prog will receive gps data and send to database, when I send 'b', prog will send accelerometer data and save to database too. But when I runn the proggram, gps data success to received and send to databse but accelerometer data canot receive and error is "segmentation fault. Could you help me to resolve the prblem..?

int main(void) {

    int fd;
    fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1) {
        perror("open_port: Unable to open port ");
    } else {
        fcntl(fd, F_SETFL, 0);
    }

    char a[] = "a";
    char b[] = "b";

    int n,m,cnt;
    char in[30];
    //char in2[50];
    //char *in;
    //char in2[100];
    //in = (char*) malloc(i+1);
    //if (in == NULL) exit(1);


    MYSQL *conn;

    const char *localhost   = "127.0.0.1";
    const char *user     = "root";
    const char *password = "";
    const char *database = "arduino1";

    conn = mysql_init(NULL);

    // Connect to database 
    if (!mysql_real_connect(conn, localhost, user, password, database, 0, NULL, 0))
    {
          fprintf(stderr, "%s\n", mysql_error(conn));
          exit(1);
    } 


    for(cnt=0; cnt<5; cnt++) 
    {
        if (cnt < 1) {
            sleep(2);
            n = write(fd, a, sizeof(a));
            printf("Send : %s \n", a);

            //terima data gps dari port
            sleep(1);
            n = read(fd, in, 100);
            if (n < 0)
            {
                perror("read");
                break;
            }

            //query gps         
            char c_lat[50],c_lon[50];
            tokenizer(in,c_lat,c_lon);


            //Isi nilai gps ke database

            char query[255];

            strcat(query,"INSERT INTO gps (latitude, longitude) VALUES (");
                strcat(query,c_lat);
                strcat(query,",");
                strcat(query,c_lon);
                strcat(query,")");

            if (mysql_query(conn, query));
            {
              printf("%s\n", query);
            }


     } else {
            m = write(fd, b, sizeof(b));
            printf("Send : %s \n", b);

            //terima data accelerometer dari port
            sleep(1);
            m = read(fd, in, 100);

            in[m] = '\0';   

            char str[255];

            //query accelerometer   
            char c_nilai_x[10],c_nilai_y[10],c_nilai_z[10],c_teg[6];
            tokenizer_acm(in,c_nilai_x,c_nilai_y,c_nilai_z,c_teg);


            //Isi nilai accelerometer ke database



            strcat(str,"INSERT INTO highcharts_php (x_axis, y_axis, z_axis, tegangan) VALUES (");
                strcat(str,c_nilai_x);
                strcat(str,",");
                strcat(str,c_nilai_y);
                strcat(str,",");
                strcat(str,c_nilai_z);
                strcat(str,",");
                strcat(str,c_teg);
                strcat(str,")");

            if (mysql_query(conn, str));
            {
              printf("%s\n", str);
            }

        }


        // Close database connection
        mysql_close(conn);

    }

    return 0;
}

Thank you for your help. But I still received the same error. My change is likr this : int main(void) {

int fd;
fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
    perror("open_port: Unable to open port ");
} else {
    fcntl(fd, F_SETFL, 0);
}

char a[] = "a";
char b[] = "b";

int n,m,cnt;
char in[50];

MYSQL *conn;

const char *localhost   = "127.0.0.1";
const char *user     = "root";
const char *password = "";
const char *database = "arduino1";

conn = mysql_init(NULL);

// Connect to database 
if (!mysql_real_connect(conn, localhost, user, password, database, 0, NULL, 0))
{
      fprintf(stderr, "%s\n", mysql_error(conn));
      exit(1);
} 


for(cnt=0; cnt<5; cnt++) 
{
    if (cnt < 1) {
        sleep(2);
        n = write(fd, a, sizeof(a));
        printf("Send : %s \n", a);

        //terima data gps dari port
        sleep(1);
        n = read(fd, in, 20);
        if (n < 0)
        {
            perror("read");
            break;
        }

        //query gps         
        char c_lat[10],c_lon[9];
        tokenizer(in,c_lat,c_lon);


        //Isi nilai gps ke database

        char query[255] = "INSERT INTO gps (latitude, longitude) VALUES (";
            strcat(query,c_lat);
            strcat(query,",");
            strcat(query,c_lon);
            strcat(query,")");

        if (mysql_query(conn, query));
        {
          printf("%s\n", query);
        }


 } else {
        m = write(fd, b, sizeof(b));
        printf("Send : %s \n", b);

        //terima data accelerometer dari port
        sleep(1);
        m = read(fd, in, 30);

        in[m] = '\0';   



        //query accelerometer   
        char c_nilai_x[8],c_nilai_y[8],c_nilai_z[8],c_teg[4];
        tokenizer_acm(in,c_nilai_x,c_nilai_y,c_nilai_z,c_teg);


        //Isi nilai accelerometer ke database


        char str[255] = "INSERT INTO highcharts_php (x_axis, y_axis, z_axis, tegangan) VALUES (";
            strcat(str,c_nilai_x);
            strcat(str,",");
            strcat(str,c_nilai_y);
            strcat(str,",");
            strcat(str,c_nilai_z);
            strcat(str,",");
            strcat(str,c_teg);
            strcat(str,")");

        if (mysql_query(conn, str));
        {
          printf("%s\n", str);
        }

    }


    // Close database connection
    mysql_close(conn);

}

return 0;

}

And the result when I runn the program is :

Send : a INSERT INTO gps (latitude, longitude) VALUES (-6.889760,107.619659) Send : b Segmentation fault (core dumped)

I need help.... Thank you

Upvotes: 0

Views: 899

Answers (2)

beyrem
beyrem

Reputation: 436

Maybe in the write you need sizeof(a)+1 to indicate the '\0' termination.

Also you have char in[30]; but m = read(fd, in, 100); The amount you read must be less than 30. when I read http://www.thinkage.ca/english/gcos/expl/c/lib/strcat.html . I'm wondering if tokenizer_acm terminate each parameters with a '\0'. by the way if you couldn't use a debugger try setting c_nilai_x, c_nilai_y,c_nilai_z,c_teg with static values.

Upvotes: 0

hmjd
hmjd

Reputation: 122001

This is an error:

char query[255];
strcat(query,"INSERT INTO gps (latitude, longitude) VALUES (");

as strcat() requires the destination buffer to be null terminated on entry, and it is uninitialized. This means that strcat() will search through query for a null character and who knows where it will find one, possibly beyond the bounds of query which will result in strcat() writing to memory it should not be. Change to:

char query[255] = "INSERT INTO gps (latitude, longitude) VALUES (";

Same error with str later in the code.

Instead of using multiple strcat() calls use the safer snprintf():

char query[255];
int result = snprintf(query,
                      255,
                      "INSERT INTO gps (latitude, longitude) VALUES (%s,%s)",
                      c_lat,
                      c_lon);

/* See following paragraph for explanation of this condition. */
if (result > 0 && result < 255)
{
}

snprintf() return value (from section 7.19.6.5 The snprintf function of the C99 standard):

The snprintf function returns the number of characters that would have been written had n been sufficiently large, not counting the terminating null character, or a negative value if an encoding error occurred. Thus, the null- terminated output has been completely written if and only if the returned value is nonnegative and less than n.

Upvotes: 5

Related Questions