以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

相关文章

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化

java中新生代和老生代的关系说明

《java中新生代和老生代的关系说明》:本文主要介绍java中新生代和老生代的关系说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、内存区域划分新生代老年代二、对象生命周期与晋升流程三、新生代与老年代的协作机制1. 跨代引用处理2. 动态年龄判定3. 空间分

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的

Maven中的profiles使用及说明

《Maven中的profiles使用及说明》:本文主要介绍Maven中的profiles使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录主要用途定义 Profiles示例:多环境配置激活 Profiles示例:资源过滤示例:依赖管理总结Maven 中的

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

Before和BeforeClass的区别及说明

《Before和BeforeClass的区别及说明》:本文主要介绍Before和BeforeClass的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Before和BeforeClass的区别一个简单的例子当运行这个测试类时总结Before和Befor

Python pip下载包及所有依赖到指定文件夹的步骤说明

《Pythonpip下载包及所有依赖到指定文件夹的步骤说明》为了方便开发和部署,我们常常需要将Python项目所依赖的第三方包导出到本地文件夹中,:本文主要介绍Pythonpip下载包及所有依... 目录步骤说明命令格式示例参数说明离线安装方法注意事项总结要使用pip下载包及其所有依赖到指定文件夹,请按照以

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis