---
title: 一次Keepalived的coredump问题定位-官方技术文章-鲲鹏社区
description: 本文记录一次Keepalived工作异常产生coredump文件的分析过程
keywords: Keepalived,一次,问题定位,官方技术文章,鲲鹏社区,对比分析,分析,文件
url: https://www.hikunpeng.com/developer/techArticles/20250422-1?envFlag=1
section: (其他)
---

# 一次Keepalived的coredump问题定位-官方技术文章-鲲鹏社区

URL: https://www.hikunpeng.com/developer/techArticles/20250422-1?envFlag=1
描述: 本文记录一次Keepalived工作异常产生coredump文件的分析过程
关键词: Keepalived,一次,问题定位,官方技术文章,鲲鹏社区,对比分析,分析,文件

官方技术文章 [了解详情](https://www.hikunpeng.com/zh/developer/techArticles)

一次Keepalived的coredump问题定位

一次Keepalived的coredump问题定位

coredump

发表于 2025/04/22

0

作者|张久同

问题现象

在某个项目中，Keepalived工作异常，无法正常启动。Keepalived的第三个进程pid一直在不停更换，查看messages日志：

会不断打印keepalived进程core dump信息。

应用信息

| 软件名称 | 版本 | 说明 |
| --- | --- | ---|
| 麒麟 | v10 sp1 | 操作系统 |
| Keepalived | 1.2.9 | Keepalived |

Keepalived是用来业务组件的做心跳探活，集群检查等工作的开源组件。

# 对比分析

*  X86+centos运行正常

*鲲鹏+centos运行正常

*鲲鹏+kylin运行core dump

推断是内核差异导致的core
dump，centos为4k页表，麒麟为64k页表。

实验室重新编译4k内核（openEuler 20.03）后运行正常。

推断是程序中存在与内核页表大小相关的变量导致core dump，同时对比。

问题定位

## 1. 分析core dump文件

打印函数调用栈，看到core dump位置

是在vrrp_parser.c文件的176行报错。

查看源码：https://github.com/acassen/keepalived/blob/v1.2.9/keepalived/vrrp/vrrp_parser.c [了解详情](https://github.com/acassen/keepalived/blob/v1.2.9/keepalived/vrrp/vrrp_parser.c)

访问vrrp->ifp->ifindex时报错。

该变量时从if_get_by_name函数返回。同时gdb打印vrrp->ifp为空，所以应该是访问了空指针导致的core dump。

该if_get_by_ifname函数逻辑就是遍历if_queue队列，如果找到了该name的对象，就返回该ifp，如果没找到就返回NULL。

在if_get_by_ifname中添加测试代码，打印出来if_queue的所有数据：

在实验室环境，指定的网口为enp4s0，但是只是循环打印以上内容，定位到原因是没找到enp4s0网口导致的core dump。

## 2. 定位为什么if_queue中缺少网卡数据

在源码中只有这部分是往if_queue队列中添加

该函数为netlink_if_link_filter，继续向上查看：

调用该函数的是netlink_interface_lookup，且该函数没有变量输入，为最上层函数，查看netlink_parse_info函数，结合message出现的报错：

该netlink_parse_info会有两种情况下出现该ERROR。如下所示：

## 3. 定位Netlink：error的原因

在两部分中添加printf函数分别打印两个不同的信息,来确认到底是那处报错，如下：

这里将不同触发条件写到指定文件中，运行后打印该文件：

发现是第二部分出现的error，也就是msg.msg_flags的标记为被标记为了MSG_TRUNC。

查看msg的赋值以及初始化:

msg变量是由recvmsg函数进行赋值修改的。通过（man recvmsg）查看recvmsg函数介绍

该标志位表示：由于数据报大于提供的缓冲区，因此丢弃了数据报的尾部。而buf是硬编码的4096。也就是说是由于buf太小导致recvmsg函数丢弃了数据包的尾部。导致网口信息解析失败。

## 4. core dump的根因

该进程core dump根因为buf数组设置过小，导致recvmsg函数丢弃了socket 数据包的尾部，导致部分网口信息解析失败，读不到指定网口，访问了空指针引起的core dump。

问题解决

查找相关patch，在debian的1.2.24版本中有一个对应的patch。#846292 -
keepalived: Fix netlink message truncation with large page sizes - Debian Bug
report logs [了解详情](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=846292)

这个patch的核心思想就是把这个4096通过netlink_set_recv_buf_size函数来初始化，初始化的逻辑：通过getpagesize函数得到当前系统的页表大小，如果超过8k，就设置成8k。可以将其patch的代码在1.2.9版本中实现重新编译后：

可以读到指定网卡。

本页内容
