问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何使用gdbserver调试一个daemon进程

发布网友 发布时间:2022-04-25 17:08

我来回答

1个回答

热心网友 时间:2022-04-07 18:40

  在2.5.60版Linux内核及以后,GDB对使用fork/vfork创建子进程的程序提供了follow-fork-mode选项来支持多进程调试。

  follow-fork-mode的用法为:

  set follow-fork-mode [parentchild]

  parent: fork之后继续调试父进程,子进程不受影响。
  child: fork之后调试子进程,父进程不受影响。
  因此如果需要调试子进程,在启动gdb后:

  (gdb) set follow-fork-mode child并在子进程代码设置断点。

  此外还有detach-on-fork参数,指示GDB在fork之后是否断开(detach)某个进程的调试,或者都交由GDB控制:

  set detach-on-fork [onoff]

  on: 断开调试follow-fork-mode指定的进程。
  off: gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态。
  注意,最好使用GDB 6.6或以上版本,如果你使用的是GDB6.4,就只有follow-fork-mode模式。

  follow-fork-mode/detach-on-fork的使用还是比较简单的,但由于其系统内核/gdb版本*,我们只能在符合要求的系统上才能使用。而且,由于follow-fork-mode的调试必然是从父进程开始的,对于fork多次,以至于出现孙进程或曾孙进程的系统,例如上图3进程系统,调试起来并不方便。

  Attach子进程
  众所周知,GDB有附着(attach)到正在运行的进程的功能,即attach <pid>命令。因此我们可以利用该命令attach到子进程然后进行调试。

  例如我们要调试某个进程RIM_Oracle_Agent.9i,首先得到该进程的pid

  [root@tivf09 tianq]# ps -efgrep RIM_Oracle_Agent.9i
  nobody 6722 6721 0 05:57 ? 00:00:00 RIM_Oracle_Agent.9i
  root 7541 27816 0 06:10 pts/3 00:00:00 grep -i rim_oracle_agent.9i通过pstree可以看到,这是一个三进程系统,oserv是RIM_Oracle_prog的父进程,RIM_Oracle_prog又是RIM_Oracle_Agent.9i的父进程。

  [root@tivf09 root]# pstree -H 6722通过 pstree 察看进程

  启动GDB,attach到该进程

  用 GDB 连接进程

  现在就可以调试了。一个新的问题是,子进程一直在运行,attach上去后都不知道运行到哪里了。有没有办法解决呢?

  一个办法是,在要调试的子进程初始代码中,比如main函数开始处,加入一段特殊代码,使子进程在某个条件成立时便循环睡眠等待,attach到进程后在该代码段后设上断点,再把成立的条件取消,使代码可以继续执行下去。

  至于这段代码所采用的条件,看你的偏好了。比如我们可以检查一个指定的环境变量的值,或者检查一个特定的文件存不存在。以文件为例,其形式可以如下:

  void debug_wait(char *tag_file)
  {
  while(1)
  {
  if (tag_file存在)
  睡眠一段时间;
  else
  break;
  }
  }当attach到进程后,在该段代码之后设上断点,再把该文件删除就OK了。当然你也可以采用其他的条件或形式,只要这个条件可以设置/检测即可。

  Attach进程方法还是很方便的,它能够应付各种各样复杂的进程系统,比如孙子/曾孙进程,比如守护进程(daemon process),唯一需要的就是加入一小段代码。

  GDB wrapper
  很多时候,父进程 fork 出子进程,子进程会紧接着调用 exec族函数来执行新的代码。对于这种情况,我们也可以使用gdb wrapper 方法。它的优点是不用添加额外代码。

  其基本原理是以gdb调用待执行代码作为一个新的整体来被exec函数执行,使得待执行代码始终处于gdb的控制中,这样我们自然能够调试该子进程代码。

  还是上面那个例子,RIM_Oracle_prog fork出子进程后将紧接着执行RIM_Oracle_Agent.9i的二进制代码文件。我们将该文件重命名为RIM_Oracle_Agent.9i.binary,并新建一个名为RIM_Oracle_Agent.9i的shell脚本文件,其内容如下:

  [root@tivf09 bin]# mv RIM_Oracle_Agent.9i RIM_Oracle_Agent.9i.binary
  [root@tivf09 bin]# cat RIM_Oracle_Agent.9i
  #!/bin/sh
  gdb RIM_Oracle_Agent.binary当fork的子进程执行名为RIM_Oracle_Agent.9i的文件时,gdb会被首先启动,使得要调试的代码处于gdb控制之下。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
虹口区东余杭路541弄算几号地块?12年下半年号称要拆,附近都在拆类,明... 我想知道新建路东余杭路这二年有没有拆迁规划? 手机通话变声器哪种好 变声器哪个好用 我准备7月底开始复习考研,还来得及吗 大四下学期考研还来得及吗 考研还来得及吗 ...在脊椎骨右边靠脊椎骨附近疼,是什么原因,大概有半个多月了,弯腰时... 电脑开着总是无缘无故蓝屏提示 电脑开着总是无缘无故蓝屏 电脑无缘无故蓝屏怎么回事探究电脑突然蓝屏的原因 gdb调试,如果一行有多个函数,如何指定步入哪一个 如何查询宽带账单 在Ubuntu Linux下用gdb调试程序,&lt;gdb&gt;list之后程序不从第一行开始显示... GCC,Gdb,Make,Vi分别起什么作用,学习嵌入式linux需要用到哪些,具体起什... 怎么自己查看家里的宽带账号 如何使用gdb查看函数的返回值 gdb调试必须是gdb a.out吗?如果一个程序有错误,不能生成a.out,我想用... 把gdb中的要素类导入到mdb中的要素集,为什么不行呢? 如何查看自己自己上的机子的宽带账号和密码 一本关于GDB调试的书籍,书中详细的介绍了,如何在LINUX中使用GDB及其... sim卡无效是什么原因? 使用路由器上网怎么查自己的宽带账号 gdb中怎样把一个数组中的元素全部显示出来 如何使用GDB调试Coredump文件 手机插入SIM卡显示SIM卡无效 gdb新手 第一个圈里的数字是什么意思 第二个圈里的$1是什么意思 如何系统的学习linux?最好能推荐比较好的入门级的书本! 手机屏幕上显示“无效SIM卡”是什么意思? 你好!我现在在学用Linux 的gdb。我想问一下,单步运行怎么看gdb运行到了... 手机上显示无效SIM卡是什么意思? 如何用gdb查找segmentation fault gdb加载动态库成功,但是不能显示动态库中的源码(gdb+gdbserver) 求助,gdb调试时,不显示行数 什么是gdb数据库 淘金币是用来付要买的东西? 淘宝使用淘金币付款退款后淘金币退吗 淘宝网淘金币全额付款在哪找 支付宝账户余额不足,可以用淘金币付吗?怎么付? 淘金币付款如果退款淘金币退回吗 合并报表中商誉是每年末调整吗,怎么调? 我也快去必胜客做兼职了,培训很繁琐吗?能不能学会啊? 用淘金币买衣服没看到淘金币付款的地方 学生做兼职千万不要去必胜客 淘金币为什么付款二遍不一样呢? 必胜客面试要注意什么呢? 用淘金币付款发生退款淘金币退吗 必胜客CHAMPS是什么意思呢? 必胜客最近有什么活动吗? 淘金币付款提醒领取 付款后忘记领取淘金币,如何补领? 我steam号被盗了更改密码搜索账户名称搜索不到这个要怎么办啊