LINUX进程启动时自动挂载调试

对于某些多进程的应用,子进程是有主进程拉起来的,此时想对子进程的启动流程打断点就比较麻烦。如果在子进程启动时调试器自动挂载就完美了。网上找到了gdbhelpers的开源工具库,其对gdb的现有命令集做了扩展,有一个工具是实现预挂载的,原理也比较简单,就是对系统接口加探测回调,然后做进程名称的匹配,若匹中自动调用GDB的attach命令,挂载到该进程。 源码路径如下:

GitHub - tromey/gdb-helpers: GDB helper scripts

下载解压后,放到某个路径下,最好是跟其他命令放在同路径。进入源码路径,切换到MakeFile所在文件夹,执行如下命令:

make hack-gdbinit

执行后,会做两件事:

1)  生成gdb启动时执行的脚本文件load-helpers.py

2)  在$HOME路径下创建.gdbinit文件,并将1)中的文件路径写入到该文件中。

从而实现gdbhelpers中的扩展命令注册。注意,移动了gdbhelpers的文件夹路径会导致load-helpers.py文件找不到,扩展命令失效。此时,要删掉load-helpers.py及.gdbinit文件,退出gdb,再次执行上述步骤完成工具部署。

由于这个工具集依赖SystemTap实现接口捕获,所以先要用apt get命令装一下。否则找不到stap命令。此外,扩展命令都是Python实现的,由于python3.4到3.8的语法变化,preattach执行中会遇到字符串拼接的解析错误,此时只要改一下preattach.py中的代码实现:

# preattach

import gdb, re
import os
import subprocess

class Preattach(gdb.Command):
    """Attach to the next instance of a program.
Usage:
    preattach BASENAME
This runs a SystemTap script that watches for the next time a program
that has the given basename is invoked.  Then, a SIGSTOP is delivered
to that process, and gdb attaches to it."""

    def __init__(self):
        super(Preattach, self).__init__("preattach", gdb.COMMAND_RUNNING,
                                        gdb.COMPLETE_NONE)

    def invoke(self, arg, from_tty):
        script = os.path.join(os.path.dirname(__file__), 'preattach.stp')
        pid = subprocess.check_output(['stap', '-g', script, arg.strip()])
        pids = re.findall(r"\d+", str(pid))
        if pids:
            gdb.execute('attach ' + pids[0], from_tty)

Preattach()

接下来是挂在过程:

1) sudo gdb启动调试器,一定要以root权限启动,否则stap命令执行报错;

2) set solib-search-path设置可执行文件的检索路径,break设置pending的断点;

3) preattach YOUR_PROCESS_NAME,注意是进程名字,不是绝对路径。

4) 启动程序,触发子进程加载。挂在后可能会收到多次SIG_STOP信号,导致进程执行中止,直接点c,继续执行就可以。顺利的话会命中刚设置的断点。

剩下的就是常规的调试命令了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值