程序中如何给自己设置硬件断点(通过程序代码设置数据断点而不使用JTAG)

本文介绍了如何在没有JTAG的情况下,通过程序代码为动态分配的内存设置硬件数据断点来解决内存踩踏问题。重点讨论了ARM架构中硬件断点的支持情况,以及在Linux系统中利用ptrace函数来操作调试寄存器实现硬件断点的设置方法。
摘要由CSDN通过智能技术生成

最近安卓项目中碰到一个踩内存导致死机的问题,通过分析Log找到了被踩的内存地址,但无法找到是谁踩掉的。一般踩内存的问题,可以通过下硬件数据断点来找到肇事者。但在这个项目中,踩内存是在安卓开机过程中发生的,来不及上JTAG,另外被踩的内存是动态分配出来的,每次开机都不同(但总是踩在这个被分配的地址的固定字节上),无法预先指定断点地址(如果是全局变量被踩的话,其地址一般是不变的,可以直接在被踩的地址上下数据断点),所以这种情况下只能通过程序来给自己下断点(self-host),程序分配内存后,马上给被踩的内存下个数据断点(已知踩内存肯定发生在这个地址上),当其它程序意外写入该内存时,就会发生异常中断,从而找到踩内存的肇事者。


不幸的是,百度后,几乎没有文章讲这个事情怎么做。翻了GDB的代码,也没看到ARM中如何下硬件断点(所用的GDB版本太旧了)。后来多方搜索,找到一些信息,记录在下:

1. 在ARM的架构文档中(ARM官网可下载),Cortext A8, A9, A15才支持硬件断点(通过协处理器CP14操作调试寄存器DBGWCR和DBGWVR来下数据断点(watchpoint),Processor和JTAG Debuger均可以操作它们)(现在跑安卓的机器一般都是A9以上的架构,所以基本都支持硬件断点)。

2. Linux内核要在2.6.37以后的版本才支持对ARM添加硬件断点。

3. GDB要在7.3以后的版本才支持对ARM添加硬件断点(最新版本是7.8.1,2014年10月)。


如果是自己的ARM系统,可以写汇编,通过MCR协处理器指令操作CP14,从而读写DBGWCR和DBGWVR来下硬件断点。

如果是Linux系统(2.6.37版本以上),就简单了,可以通过ptrace函数来操作DBGWCR和DBGWVR,下硬件断点。

以下是从GDB 7.8.1中截取的下硬件断点的部分代码:

  for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++)
    if (arm_lwp_info->bpts_changed[i])
      {
        errno = 0;
        if (arm_hwbp_control_is_enabled (bpts[i].control))
          if (<span style="color:#ff0000;"><strong>ptrace (PTRACE_SETHBPREGS, pid,
              (PTRACE_TYPE_ARG3) ((i << 1) + 1), &bpts[i].address)</strong></span> < 0)
            perror_with_name (_("Unexpected error setting breakpoint"));

        if (bpts[i].control != 0)
          if (<span style="color:#ff0000;"><strong>ptrace (PTRACE_SETHBPREGS, pid,
              (PTRACE_TYPE_ARG3) ((i << 1) + 2), &bpts[i].control)</strong></span> < 0)
            perror_with_name (_("Unexpected error setting breakpoint"));

        arm_lwp_info->bpts_changed[i] = 0;
      }

  for (i = 0; i < arm_linux_get_hw_watchpoint_count (); i++)
    if (arm_lwp_info->wpts_changed[i])
      {
        errno = 0;
        if (arm_hwbp_control_is_enabled (wpts[i].control))
          if (<span style="color:#ff0000;"><strong>ptrace (PTRACE_SETHBPREGS, pid,
              (PTRACE_TYPE_ARG3) -((i << 1) + 1), &wpts[i].address)</strong></span> < 0)
            perror_with_name (_("Unexpected error setting watchpoint"));

        if (wpts[i].control != 0)
          if (<span style="color:#ff0000;"><strong>ptrace (PTRACE_SETHBPREGS, pid,
              (PTRACE_TYPE_ARG3) -((i << 1) + 2), &wpts[i].control)</strong></span> < 0)
            perror_with_name (_("Unexpected error setting watchpoint"));

        arm_lwp_info->wpts_changed[i] = 0;
      }
  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值