以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来解决这个问题。

图解

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

参考

最近更新

  1. TCP协议是安全的吗?

    2024-06-15 17:14:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-15 17:14:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-15 17:14:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-15 17:14:03       18 阅读

热门阅读

  1. spring boot使用自定义注解做AOP

    2024-06-15 17:14:03       8 阅读
  2. 10个Python编程技巧,助你提高开发效率

    2024-06-15 17:14:03       7 阅读
  3. 富格林:正视欺诈阻挠交易被骗

    2024-06-15 17:14:03       5 阅读
  4. 低代码开发:智能财务系统开发应用

    2024-06-15 17:14:03       10 阅读
  5. Web 品质样式表

    2024-06-15 17:14:03       6 阅读
  6. 论徐州高防IP的作用有哪些?

    2024-06-15 17:14:03       8 阅读
  7. postgresql 创建函数

    2024-06-15 17:14:03       8 阅读