调试 dpdk 应用程序的coredump整理

摘要:
您可以通过自己的_ Mbuf结构封装dpdk的结构;模仿上述示例,并在应用时记录状态1;释放时,检查其是否处于状态1,设置状态2,记录释放的功能并释放;如果有另一个版本,则它已经处于状态2,检查失败;无法稳定循环核心转储打开大页面内存/proc/PID/coredump_过滤器参数的核心转储设置;当程序崩溃或使用gcore工具生成进程的核心文件时,可以通过设置内核转储掩码来过滤需要转储的内存部分。

稳定复现的 coredump
打开 dpdk 相关的 debug开关,重新编译
mbuf debug
malloc debug 
mempool debug
给 dpdk 源码加检查或日志,重新编译
无法稳定复现的 coredump
打开大页内存的 coredump
案例
字节序导致取地址不对,从而踩内存
多线程竞争资源导致

稳定复现的 coredump

打开 dpdk 相关的 debug开关,重新编译

# grep -i "DEBUG" common_base  | grep -Ei "malloc|mbuf|mempool"
CONFIG_RTE_MALLOC_DEBUG=n
CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
CONFIG_RTE_LIBRTE_OCTEONTX_MEMPOOL_DEBUG=n
CONFIG_RTE_LIBRTE_MBUF_DEBUG=n

mbuf debug

malloc debug 

mempool debug

当开启RTE_LIBRTE_MEMPOOL_DEBUG时,申请mempool中的一个元素时,比如mbuf, 在mbuf的申请和释放出都会调用rte_mempool_check_cookies这个函数,对mbuf的cookie值进行校验。

其校验原理可以理解为:

1)在申请mbuf时,校验是否为cookie2,是,则对其打上cookie1的标记,不是,则panic;

2)对释放mbuf是对其校验是否为cookie1,是,则打上cookie2,不是则 panic;

简单的理解即mbuf的申请和释放处于两种状态,当任何一种动作(申请或释放)做了两次,都会产生panic;

调试 dpdk 应用程序的coredump整理第1张

调试 dpdk 应用程序的coredump整理第2张

这个开关的存在,正好可以解决我们这个多线程重复free mbuf的问题。

给 dpdk 源码加检查或日志,重新编译

比如 对于 dpdk 从 mempool 中申请 的  mbuf 的相关的 core;

(1)有可能是一个 mbuf 被多个线程给释放了?

针对这种情况,可以自己封装 dpdk 的 struct rte_mbuf,添加一个 core_id,core_id 是申请 mbuf 时的线程的 core_id;

释放的时候,比较下释放的 core_Id 和 申请的 core_id 是否是同一个;

(2)一个mbuf 被一个线程的多处给释放了?

可以自己封装  dpdk 的 struct rte_mbuf 结构;仿造上面的例子,申请的时候记录状态1;

释放的时候,检查处于状态1,则设置状态2,记录释放的函数(通过函数宏的方式进行释放,可以记录上层函数),进行释放;

如果存在再次释放,则已经处于状态2,检查失败;

无法稳定复现的 coredump

打开大页内存的 coredump

设置 /proc/PID/coredump_filter 的参数;

程序崩溃 或 使用gcore工具 生成进程的core文件时,可以通过设定内核转储掩码来筛选需要dump的部分内存。

可以设置为 000000ff 来打印大页内存相关;

支持以下7种内存:
 
  - (bit 0) anonymous private memory(匿名私有内存段)
  - (bit 1) anonymous shared memory(匿名共享内存段)
  - (bit 2) file-backed private memory(file-backed 私有内存段):文件映射的内存
  - (bit 3) file-backed shared memory(file-bakced 共享内存段)
  - (bit 4) ELF header pages in file-backed private memory areas (it is
            effective only if the bit 2 is cleared)(ELF 文件映射,只有在bit 2 复位的时候才起作用)
  - (bit 5) hugetlb private memory(大页面私有内存) :mmap 映射的MAP_HUGETLB类型数据
  - (bit 6) hugetlb shared memory(大页面共享内存)
  - (bit 7) DAX private memory
  - (bit 8) DAX shared memory
 
可以通过修改文件/proc/<pid>/coredump_filter来筛选需要dump的内存段。
/proc/<pid>/coredump_filter中的值为16进制,默认值是0x33,二进制为 0011 0011;
也即发生coredump时会将所有anonymous内存、ELF头页面、hugetlb private memory内容保存。

mempool中存储的每一个对象的结构分3部分,首部,数据和尾部。每一部分都填充以做到字节对齐,在调试模式首部和尾部还可以加上cookie。

../../../_images/mempool_obj.png

#define RTE_MEMPOOL_HEADER_COOKIE2  0xf2eef2eedadd2e55ULL /**< Header cookie. */
COOKIe
static void
mempool_add_elem(struct rte_mempool *mp, void *obj, phys_addr_t physaddr)
{
    struct rte_mempool_objhdr *hdr;
    struct rte_mempool_objtlr *tlr __rte_unused;

    /* set mempool ptr in header */
    hdr = RTE_PTR_SUB(obj, sizeof(*hdr));
    hdr->mp = mp;
    hdr->physaddr = physaddr;
    STAILQ_INSERT_TAIL(&mp->elt_list, hdr, next);
    mp->populated_size++;

#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
    hdr->cookie = RTE_MEMPOOL_HEADER_COOKIE2;
    tlr = __mempool_get_trailer(obj);
    tlr->cookie = RTE_MEMPOOL_TRAILER_COOKIE;
#endif

    /* enqueue in ring */
    rte_mempool_ops_enqueue_bulk(mp, &obj, 1);
}
【DPDK17.11】记录一次由dpdk的野指针造成的coredump过程

免责声明:文章转载自《调试 dpdk 应用程序的coredump整理》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇bootstrap-图文混排 mediaTCP/IP 数据包报文格式(IP包、TCP报头、UDP报头)(转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

VS调试异常问题解决(一)

一、无法在web服务器上启动调试,您没有调试web服务器进程的权限 具体:无法在web服务器上启动调试,您没有调试web服务器进程的权限,您需要以web服务器的用户账户身份运行,或者具有管理员权限。 现象:手动修改网站项目的启动端口号,调试报错 原因:从Windows NT 6.1开始,既Windows Vista版本开始,增强了用户控制,尤其是Wind...

用Eclipse平台进行C/C++开发

我们将概述如何在 C/C++ 开发项目中使用 Eclipse 平台。尽管 Eclipse 主要是一个 Java 开发环境,但其体系结构确保了对其它编程语言的支持。在本文中,您将学习如何使用 C/C++ 开发工具箱(C/C++ Development Toolkit,CDT),它是可用于 Eclipse 的最佳 C/C++ 工具箱。 C 和 C++ 语言都是...

delphi 各新版本特性收集

增强的数据库浏览器 BDP 数据提供者相应的数据库浏览器已经在几个地方作了增强。 现在可以简单的将数据从一个BDP数据提供者迁移到另外一个,这个功能能够允许你将一个数据表从一个BDP数据提供者复制另外一个上面. 这样会复制和重新建立复制目标数据表的元数据, 即使这个数据根本就是来之不同的数据源, 如将Oracle的数据迁移到MSSQL上.这和BdpCopy...

chromium浏览器开发系列第四篇:如何调试最新chromium源码

附上上几篇文章地址,方便大家查看: 下载源码 编译源码 目录结构 接二连三的事情,时间比较紧张,但是还是没有把这个系列的文章丢掉,因为这也是对自己知识的总结吧。提倡大家多写写,以后再看的时候会有种莫名的小激动。 上周写的是chromium的目录结构,好像大家不太感兴趣,在我看来这部分很重要。开头有链接地址,大家想看可以再看看。 从源码下载到编译,到目录结构...

WPF入门-使用C#创建简单应用

本文,你将熟悉在使用VS2019开发应用程序时可使用的许多工具、对话框和设计器。将创建一个“Hello World”应用程序、UI设计器、添加代码并调试错误。 先决条件: 安装Visual Studio 2019(16.3或者更高版本)。本文环境是16.8 一、创建项目   1、打开VS2019,   2、在‘开始’窗口,选择‘创建新项目’:      3...

Shell脚本调试技术

一. 前言 shell编程在unix/linux世界中使用得非常广泛,熟练掌握shell编程也是成为一名优秀的unix/linux开发者和系统管理员的必经之路。脚本调试的主要工作就是发现引发脚本错误的原因以及在脚本源代码中定位发生错误的行,常用的手段包括分析输出的错误信息,通过在脚本中加入调试语句,输出调试信息来辅助诊断错误,利用调试工具等。但与其它高级语...