3

I use sqlite3 in C with ubuntu 14.04. In my process I update the db every 20 minutes.

Here is my function :

int update_alive_state(uint64_t ieee,bool isAlive)
{
    char *error_report = NULL;
    char sql[100];
    int result = -1;
    UpdateAliveStateSql(sql,ieee,isAlive);
    if(result = sqlite3_exec(db_event, sql, 0, 0, &error_report))
    {
        printf( "\t> CMD: %s , Error: %s\n" , sql , error_report );
        sqlite3_free(error_report);
    }

    return result;
}

When sqlite3_exec() return error and print error message, I get the segmentation fault message and the process terminated.

ERROR: signal 11 was trigerred:
  Fault address: 0xae703f1b
  Fault reason: address not mapped to object
Stack trace folows:
./main.bin(segmentation_fault_handler+0xd5)[0x419e9f]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x10330)[0x7fa386f20330]
/lib/x86_64-linux-gnu/libc.so.6(_IO_vfprintf+0x1d03)[0x7fa386257943]
/lib/x86_64-linux-gnu/libc.so.6(_IO_printf+0x99)[0x7fa3862603d9]
./main.bin(update_alive_state+0x15d)[0x43ca78]
./main.bin(EventScanThread+0x2af)[0x442c21]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x8184)[0x7fa386f18184]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7fa38630637d]
Executing original handler...

If I comment out printf and sqlite3_free, segmentation fault message would be disappeared. Why can I not print the error message?

Please help me.


Edit: I changed my code like this

if(result = sqlite3_exec(db, sql, 0, 0, &error_report))
{
    printf( "[ERR] : \t> CMD: %s , Error: %d\n" , sql , result );
    if ( error_report )
    {
        printf( "[ERR] : Error msg: %s\n", error_report );
        sqlite3_free(error_report);
    }
}

But I still get a segmentation fault message.

ERROR: signal 11 was trigerred:
  Fault address: 0x7f3dc490cf1b
  Fault reason: address not mapped to object
Stack trace folows (partial):
./main.bin(segmentation_fault_handler+0xd5)[0x419e9f]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x10330)[0x7fab749ac330]
/lib/x86_64-linux-gnu/libc.so.6(_IO_vfprintf+0x1d03)[0x7fab73ce3943]
/lib/x86_64-linux-gnu/libc.so.6(_IO_printf+0x99)[0x7fab73cec3d9]
./main.bin(update_last_receive_time+0x166)[0x43d60e]
./main.bin(attr_process_attribute_report_ind+0x97)[0x4222dc]
./main.bin(si_gateway_incoming_data_handler+0xa3)[0x41b6b1]
./main.bin(tcp_socket_event_handler+0x558)[0x41c316]
./main.bin(polling_process_activity+0xde)[0x41a4e1]
./main.bin(main+0x150)[0x41a0f4]
Executing original handler...

The error address points to the first printf function

printf( "[ERR] : \t> CMD: %s , Error: %d\n" , sql , result );

Why? Please help me. Thanks.

4
  • And if you catch the crash in a debugger, what is the value or error_report? Is it perhaps a null pointer? Commented Jul 3, 2017 at 8:28
  • sqlite3_exec expects a double pointer to a char as last parameter, but you're printing it (error_report) as if it was a normal string. Commented Jul 3, 2017 at 8:29
  • 1
    @FedericoklezCulloca The sqlite3_exec function expected a pointer to a pointer (to char) as a way to emulate pass-by-reference, so it can set the original pointer to point to a string. And the OP is passing the correct thing to sqlite3_exec (a pointer to a pointer to char) and since it should be a string it is printed as a string which is also correct. The problem is probably, as I mentioned in my previous comment, that there is no error message and sqlite3_exec leaves error_report as a null pointer. Commented Jul 3, 2017 at 8:36
  • Thanks @Some programmer dude , I suppose every sqlite3_exec() error code has error message. I will try to check if (error_report) is NULL or not. Commented Jul 3, 2017 at 8:50

1 Answer 1

2

The documentation states:

If the 5th parameter to sqlite3_exec() is not NULL and no errors occur, then sqlite3_exec() sets the pointer in its 5th parameter to NULL before returning.

So it is possible that there is no error messsage at all and you should do:

if (result = sqlite3_exec(db_event, sql, NULL, NULL, &error_report))
{
   if (error_report)
   {
      printf( "\t> CMD: %s , Error: %s\n" , sql , error_report );
      sqlite3_free(error_report);
   }
}

to check if it was set to NULL.


I changed my code like this [...]
But I still get segmentation fault message. [...]
The error address points to the first printf function:

printf( "[ERR] : \t> CMD: %s , Error: %d\n" , sql , result );

If you print a character array with %s, printf needs a null terminated '\0' C-string. As you dont provide your UpdateAliveStateSql function I can't see if the sql string is null terminated. To ensure that by writing a '\0' at the end of the buffer you could do:

sql[sizeof(sql) - 1] = '\0';

after calling the UpdateAliveStateSql function.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @Andre Kampling , I will try then.
@FrazierChang: I extend my answer as I saw that you edited your question. Please tell the status.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.