以keepalived为例说明程序不能正常被gdb调试的原因

2024-06-15 17:20

本文主要是介绍以keepalived为例说明程序不能正常被gdb调试的原因,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

现象

通过gdb att $keepalived_pid发起对当前运行keepalived的调试;

在放行keepalived继续执行后,想通过Ctrl+C按键中断执行,观察下被调试程序的当前内部状态,
但是,在终端输入Ctrl+C后,导致keepalived被调试进程退出。

gdb无法对keepalived进行正常的调试交互!

结论先行

  • gdbinferior process之间通过ptrace系统调用,以及对signal信号的拦截、传递进行调试交互过程
  • 由终端触发的signal会首先被Kernel路由到inferior process,然后再被gdb截获
  • Linux Kernel针对inferior process信号存在特别的路由机制,会导致某些应用使用了特别信号捕获机制,例如,sigwait or signalfd,并处理了SIGINT信号,则不能被gdb正常调试

缘由

以前就了解到,如果被调试程序使用到类似sigwait特殊的信号捕捉机制,将会导致gdb调试程序遇到麻烦,特别是无法正常使用Ctrl+C按键,中断暂停被调试程序,进行正常的交互操作。

最近遇到keepalived一些问题, 就想用调试的方法看看它的运行时逻辑,在这时就遭遇了现象一样的调试失败。

先搜索了下keepalived源码,并无sigwait的使用过程,因为以前看那篇介绍比较粗,不知道除了sigwait使用方式外,还有signalfd使用方式,也会导致GDB调试遭遇类似问题。
而且,当时觉得keepalived作为比较出名的开源软件,应该不会不支持被调试,所以,并没有在第一时间发现原因。

分析

采用了分掘挖进的方法:

  • 用不同的keepalived版本
  • 用不同的linux部署环境、不同的gdb版本

来分析、验证这个问题,结果发现表象却出奇的一致!

最后,懒得继续研究下去其中到底为什么了,就向keepalived社区提出了Keeppalived不能被正常调试的issue。

社区解决方案

keepalived社区称之为Linux Kernel signal bug,但Linux社区保持这样的信号处理特性,有其原因。

最终,keepalived社区用新增启动参数项--ignore-sigint来解决这个问题。

图解

调试模型
信号调试交互序列图

参考

  • Keeppalived不能被正常调试的issue
  • 社区新增–ignore-sigint option的commit
  • E文 Linux信号路由特殊机制导致GDB正常Ctrl+C却调试失败
  • E文 调试的信号传递过程
  • E文 GNU GDB 信号处理相关命令

这篇关于以keepalived为例说明程序不能正常被gdb调试的原因的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1064087

相关文章

MySQL双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

Linux samba共享慢的原因及解决方案

《Linuxsamba共享慢的原因及解决方案》:本文主要介绍Linuxsamba共享慢的原因及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux samba共享慢原因及解决问题表现原因解决办法总结Linandroidux samba共享慢原因及解决

Tomcat版本与Java版本的关系及说明

《Tomcat版本与Java版本的关系及说明》:本文主要介绍Tomcat版本与Java版本的关系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat版本与Java版本的关系Tomcat历史版本对应的Java版本Tomcat支持哪些版本的pythonJ

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

Java报NoClassDefFoundError异常的原因及解决

《Java报NoClassDefFoundError异常的原因及解决》在Java开发过程中,java.lang.NoClassDefFoundError是一个令人头疼的运行时错误,本文将深入探讨这一问... 目录一、问题分析二、报错原因三、解决思路四、常见场景及原因五、深入解决思路六、预http://www

Nginx指令add_header和proxy_set_header的区别及说明

《Nginx指令add_header和proxy_set_header的区别及说明》:本文主要介绍Nginx指令add_header和proxy_set_header的区别及说明,具有很好的参考价... 目录Nginx指令add_header和proxy_set_header区别如何理解反向代理?proxy

如何用java对接微信小程序下单后的发货接口

《如何用java对接微信小程序下单后的发货接口》:本文主要介绍在微信小程序后台实现发货通知的步骤,包括获取Access_token、使用RestTemplate调用发货接口、处理AccessTok... 目录配置参数 调用代码获取Access_token调用发货的接口类注意点总结配置参数 首先需要获取Ac

JAVA SE包装类和泛型详细介绍及说明方法

《JAVASE包装类和泛型详细介绍及说明方法》:本文主要介绍JAVASE包装类和泛型的相关资料,包括基本数据类型与包装类的对应关系,以及装箱和拆箱的概念,并重点讲解了自动装箱和自动拆箱的机制,文... 目录1. 包装类1.1 基本数据类型和对应的包装类1.2 装箱和拆箱1.3 自动装箱和自动拆箱2. 泛型2