You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MariaDB的C程序调用mysql_query触发SIGSEGV错误求助

问题排查与解决建议

以下是针对代码中导致SIGSEGV错误的关键问题分析及解决方法:

1. 全局变量类型不匹配引发参数传递错误

全局变量声明存在类型错误:

char * drawing_number, layoutID;

这里layoutID被声明为char类型,但在sprintf中使用了长整型格式符%ld:

sprintf(query,"SELECT name,wd,ht FROM pagelayouts WHERE drawing=%s AND handle=%ld;",drawing_number,layoutID);

将char类型作为long参数传递会打乱栈帧布局,直接破坏后续函数调用的内存结构,触发段错误。

修复:
修正layoutID的类型与格式符匹配:

char *drawing_number;
long layoutID;

2. 内存分配计算错误导致堆溢出

initialize_database函数中内存分配逻辑错误:

char * Dname=(char *)malloc(strlen(dBase+2));

strlen(dBase+2)是计算指针偏移2字节后的字符串长度,而非原字符串长度加2。这会导致分配的内存远小于实际需求,后续sprintf写入时会溢出堆内存,破坏堆结构,间接引发数据库操作时的内存访问异常。

修复:
正确计算所需内存大小:

// "prefix"共6个字符,加原字符串长度加终止符,总长度为strlen(dBase)+7
char *Dname = (char *)malloc(strlen(dBase) + 7);
snprintf(Dname, strlen(dBase)+7, "prefix%s", dBase);

3. 函数定义语法错误(可能破坏代码结构)

update_layout_database函数缺少起始大括号:

void update_layout_database()
  char query[255];

即便编译器未报错,也会导致函数内变量布局异常,引发未知内存错误。

修复:
补全函数起始大括号:

void update_layout_database() {
  char query[255];
  // 后续代码
}

4. 缓冲区溢出风险

query数组仅255字节,当drawing_number较长或浮点数字符串表示过长时,sprintf会溢出缓冲区,破坏栈上的sqlconnect等变量,导致调用mysql_query时访问非法内存。

修复:
改用snprintf限制写入长度:

snprintf(query, sizeof(query), "SELECT name,wd,ht FROM pagelayouts WHERE drawing=%s AND handle=%ld;", drawing_number, layoutID);

UPDATE语句同理:

snprintf(query, sizeof(query), "UPDATE pagelayouts SET X=%f, Y=%f,wd=%f,ht=%f WHERE drawing=%s AND handle=%ld", Extents[0], Extents[1], wd, ht, drawing_number, layoutID);

5. 未检查数据库操作返回值与资源泄漏

  • mysql_query调用后未检查返回值,若查询失败,mysql_store_result会返回NULL,后续mysql_fetch_row访问空指针会崩溃。
  • 未调用mysql_free_result释放结果集,长期运行会引发内存泄漏。

修复:
添加返回值检查与资源释放:

int res = mysql_query(sqlconnect, query);
if (res != 0) {
    fprintf(stderr, "Query failed: %s\n", mysql_error(sqlconnect));
    return;
}
MYSQL_RES *result = mysql_store_result(sqlconnect);
if (result == NULL) {
    fprintf(stderr, "Store result failed: %s\n", mysql_error(sqlconnect));
    return;
}
row = mysql_fetch_row(result);
// 业务逻辑
mysql_free_result(result); // 释放结果集

额外排查步骤

  1. 在GDB中mysql_query调用瞬间,再次确认sqlconnect指针的合法性,避免被溢出操作覆盖。
  2. 检查drawing_number是否为合法的以\0终止的字符串,排除野指针或非终止字符串导致的内存读取错误。
  3. 确认Extents数组未被越界访问,避免栈内存被破坏。

内容的提问来源于stack exchange,提问作者Dave Coventry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:57:38