Description:
When you create a thread that's indirectly call's to mysql_query() funtion with an specifical SQL Select to access and connected embedded database, the programs causes segmentation fault.
We tryed doing it with fork, and it worked ok. The problem looks like is with threads.
We test this program on I386 and ARM arquitectures, and fail in the same way.
Some help would be apreciated.
Thanks.
How to repeat:
Compile and Run this:
#include <pthread.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <mysql.h>
#define DEFAULT_QUERY "SELECT DISTINCT varCounter FROM HistoricFlowHourly WHERE (varCounter MOD 35) = 1"
#define DB_NAME "myefm"
#define DB_HOST "localhost"
#define DB_USER "root"
#define DB_PASS NULL
int startMysql();
int closeMysql();
void *doQuery(void *query);
MYSQL *db;
const char *server_groups[] = {"embedded", "server", NULL};
char *server_args[] = {"nada","--defaults-file=/etc/my.cnf"};
int main (int argc, char **argv) {
void *status;
pthread_t tHandle;
char *query, aux[300];
printf("Starting Mysql engine...\n");
startMysql();
if (argc < 2) {
printf("No args, using default query...\n");
sprintf(aux,"%s",DEFAULT_QUERY);
query = aux;
}
else {
query = argv[1];
}
if (pthread_create(&tHandle, NULL, doQuery, (void *) query)) {
printf("Error: Failed to create thread.\n");
return 1;
}
pthread_join(tHandle, &status);
printf("Stopping Mysql...\n");
closeMysql();
printf("That's all folks...\n");
return 0;
}
int startMysql() {
mysql_server_init(sizeof(server_args)/sizeof(char *),server_args,(char**)server_groups);
db = mysql_init(NULL);
if (!mysql_real_connect(db, DB_HOST, DB_USER, DB_PASS, DB_NAME, 0, NULL, 0)) {
printf("Connection to Mysql failed...\n");
return 1;
}
return 0;
}
int closeMysql() {
mysql_close(db);
mysql_server_end();
return 0;
}
void *doQuery(void *query) {
MYSQL_RES *resultSet;
int fieldCount = 0, field = 0, count = 0, rowCount = 0;
printf("Sending query: [%s].\n",(char *) query);
if (mysql_query(db,(char *) query)) {
printf("Error: %s\n",mysql_error(db));
return NULL;
}
printf("Query Success...\n");
if (mysql_field_count(db) > 0) {
MYSQL_ROW rows;
if (!(resultSet = mysql_store_result(db))) {
printf("Error: %s\n",mysql_error(db));
return NULL;
}
fieldCount = mysql_num_fields(resultSet);
while ((rows = mysql_fetch_row(resultSet))) {
for (field = 0; field < fieldCount; field++) {
if ((char *) *rows) {
printf("%s ",(char *) *rows);
}
else {
printf("(null) ");
}
rows++;
}
printf("\n");
count++;
}
}
else {
printf("Affected rows [%ld]",(long) mysql_affected_rows(db));
return NULL;
}
rowCount = mysql_num_rows(resultSet);
printf("rowCount = [%d].\n",rowCount);
return NULL;
}
Suggested fix:
don't have a clue.