当前位置:   article > 正文

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

perf设置breakpoint

最近安卓项目中碰到一个踩内存导致死机的问题,通过分析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中截取的下硬件断点的部分代码:

  1. for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++)
  2. if (arm_lwp_info->bpts_changed[i])
  3. {
  4. errno = 0;
  5. if (arm_hwbp_control_is_enabled (bpts[i].control))
  6. if (<span style="color:#ff0000;"><strong>ptrace (PTRACE_SETHBPREGS, pid,
  7. (PTRACE_TYPE_ARG3) ((i << 1) + 1), &bpts[i].address)</strong></span> < 0)
  8. perror_with_name (_("Unexpected error setting breakpoint"));
  9. if (bpts[i].control != 0)
  10. if (<span style="color:#ff0000;"><strong>ptrace (PTRACE_SETHBPREGS, pid,
  11. (PTRACE_TYPE_ARG3) ((i << 1) + 2), &bpts[i].control)</strong></span> < 0)
  12. perror_with_name (_("Unexpected error setting breakpoint"));
  13. arm_lwp_info->bpts_changed[i] = 0;
  14. }
  15. for (i = 0; i < arm_linux_get_hw_watchpoint_count (); i++)
  16. if (arm_lwp_info->wpts_changed[i])
  17. {
  18. errno = 0;
  19. if (arm_hwbp_control_is_enabled (wpts[i].control))
  20. if (<span style="color:#ff0000;"><strong>ptrace (PTRACE_SETHBPREGS, pid,
  21. (PTRACE_TYPE_ARG3) -((i << 1) + 1), &wpts[i].address)</strong></span> < 0)
  22. perror_with_name (_("Unexpected error setting watchpoint"));
  23. if (wpts[i].control != 0)
  24. if (<span style="color:#ff0000;"><strong>ptrace (PTRACE_SETHBPREGS, pid,
  25. (PTRACE_TYPE_ARG3) -((i << 1) + 2), &wpts[i].control)</strong></span> < 0)
  26. perror_with_name (_("Unexpected error setting watchpoint"));
  27. arm_lwp_info->wpts_changed[i] = 0;
  28. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/152426
推荐阅读
相关标签
  

闽ICP备14008679号