You need to enable JavaScript to run this app. 使用DPDK库编写的发包程序运行触发Segmentation fault段错误问题
优惠活动
大模型
产品
解决方案
定价
更多

使用DPDK库编写的发包程序运行触发Segmentation fault段错误问题

段错误触发原因

  • 同名变量作用域错误+释放逻辑位置错误导致mbuf持续泄漏耗尽
    你在函数开头定义了uint16_t sent_packets = BURST_SIZE;,又在do-while循环内部重新定义了同名的const uint16_t sent_packets = rte_eth_tx_burst(...),内部定义的变量仅在循环体内部有效。同时你的未发送包释放逻辑放在了整个do-while循环结束之后,每一轮发送后未发完的mbuf都无法及时释放,直到循环结束才会执行一次释放逻辑,且判断条件sent_packets < BURST_SIZE实际用的是函数开头初始值为256的变量,永远不会触发释放,内存池很快被耗尽,后续rte_pktmbuf_alloc返回NULL后直接操作空指针触发段错误。
  • mbuf分配未做空指针校验
    rte_pktmbuf_alloc在内存池耗尽时会返回NULL,代码中没有对分配结果做校验,直接操作返回的空指针必然触发段错误。
  • payload赋值语法错误
    *my_pkt->payload = 'Hello2021';存在两处语法问题:一是C语言中单引号仅能包裹单个字符,多字符常量属于未定义行为,字符串必须用双引号包裹;二是解引用payload数组拿到的是首个char类型元素,无法容纳长度为9的字符串,直接赋值会引发内存访问异常。
  • 计数变量类型不匹配
    循环计数变量j是int类型,而传入的max_packets是uint64_t类型,当发送量超过int最大值时会出现整数溢出,导致循环逻辑异常,持续分配mbuf加速内存耗尽。
  • 潜在野指针风险
    main函数中定义struct rte_mempool *mbuf_pool;后直接传入my_send,如果EAL初始化逻辑中没有正确创建内存池并给mbuf_pool赋值,会传入野指针,调用rte_pktmbuf_alloc时直接触发段错误。

修复方案

  1. 删除循环内部的sent_packets重复定义,复用函数开头的变量,避免作用域问题:
// 去掉const uint16_t修饰,直接给外层变量赋值
sent_packets = rte_eth_tx_burst(port, 0, bufs, BURST_SIZE);
  1. 将未发送mbuf的释放逻辑移到do-while循环内部,每一轮发送完成后立即释放本轮未发送的mbuf,避免持续泄漏。
  2. 增加mbuf分配判空逻辑,分配失败及时处理:
bufs[i] = rte_pktmbuf_alloc(mbuf_pool);
if (bufs[i] == NULL) {
    // 释放本轮已分配的mbuf后可选择重试或退出
    for (int k = 0; k < i; k++) {
        rte_pktmbuf_free(bufs[k]);
    }
    return;
}
  1. 修复payload赋值逻辑,用内存拷贝写入字符串:
// 用rte_memcpy拷贝字符串,确保不超过数组长度
rte_memcpy(my_pkt->payload, "Hello2021", sizeof(my_pkt->payload));
  1. 将计数变量j的类型改为uint64_t,和max_packets类型匹配,避免整数溢出:
uint64_t j = 0;
  1. 确认EAL初始化逻辑中正确创建了mbuf内存池,给mbuf_pool指针赋值后再传入my_send函数。

内容的提问来源于stack exchange,提问作者Resting Platypus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 03:12:00