我有以下功能:
int get_tcounter(char *meterType, int *error) {
MYSQL *conn = mysql_init(NULL);
get_connection(conn, DB_HOST, DB_USER, DB_PW, DB);
MYSQL_STMT *stmt = mysql_stmt_init(conn);
if (!stmt) {
log_to_console("Init stmt failed: %s\n", mysql_error(conn));
exit(1);
}
prepare_stmt(conn, stmt, GET_TCOUNTER_SQL);
MYSQL_BIND param[1], res[1];
memset(param, 0, sizeof(param));
memset(res, 0, sizeof(res));
char *paramBuff;
int tcBuff;
my_bool isNullParam[] = {0}, isNullRes[] = {0};
paramBuff = meterType;
bind_string_param(¶m[0], strlen(meterType), paramBuff, &isNullParam[0], (unsigned long *) 0);
bind_result(&res[0], MYSQL_TYPE_LONG, (char *) &tcBuff, &isNullRes[0], (unsigned long *) 0);
execute_statement(stmt, param, res);
*error = TRUE;
int ret = 0;
if (!mysql_stmt_fetch(stmt)) {
ret = tcBuff;
*error = FALSE;
}
mysql_stmt_close(stmt);
mysql_close(conn);
return ret;
}
我第一次执行该函数时,all按预期工作,但第二次,mysql_init
行抛出Segmentation Fault。
这是核心转储:
Program terminated with signal 11, Segmentation fault.
#0 0x00007fe23ee22f08 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) down
Bottom (innermost) frame selected; you cannot go down.
(gdb) up
#1 0x00007fe23ee24536 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) up
#2 0x00007fe23ee270b5 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) up
#3 0x00007fe23fa951d2 in my_malloc () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
(gdb) up
#4 0x00007fe23fa788df in mysql_init () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
(gdb) up
#5 0x0000000000403ed4 in get_tcounter (meterType=0x24bcbd0 "M-9669-8", error=0x7fff6b57a8a8) at database/data_access.c:284
284 MYSQL *conn = mysql_init(NULL);
奇怪的是,第一次调用conn
在init之前是0x0,但第二次是一些任意的0x7fff ...地址。
绑定为conn分配NULL并在init之前释放conn无效。
答案 0 :(得分:0)
很有可能这是内存损坏,在MySQL中设置了一些不良状态。尝试在Valgrind下运行它,看看是否存在双free
或某种无效访问。
答案 1 :(得分:-1)
不要链接调试库(libmysqld.lib),我在win10 + mysql5.6 5.7 + vs2017上测试它,mysql_init总是返回NULL或崩溃。您应链接发布库(libmysql.lib)。