作家
登录

开发一个Linux调试器(二):断点

作者: 来源: 2017-06-28 16:04:46 阅读 我要评论

return m_enabled; } 
  •     auto get_address() const -> std::intptr_t { return m_addr; } 
  • private: 
  •     pid_t m_pid; 
  •     std::intptr_t m_addr; 
  •     bool m_enabled; 
  •     uint64_t m_saved_data; //data which used to be at the breakpoint address 
  • }; 
  • 这里的大年夜部分代码都是跟踪状况;真正神奇的处所是 enable 和 disable 函数。

    正如我们膳绫擎学到的,我们要用 int 3 指令 - 编码为 0xcc - 调换当前指定地址的指令。我们还要保存该地址之前的值,以便后面恢复该代码;我们不想忘了履行用户(本来)的代码。

    我前面说软件断点是经由过程修改┞俘在履行的代码实现的,那么问题就来了:

    • 我们若何修改代码?
    • 为了设置断点我们要做什么修改?
    • 若何告诉调试器?
    1. void breakpoint::enable() { 
    2.     m_saved_data = ptrace(PTRACE_PEEKDATA, m_pid, m_addr, nullptr); 
    3.     uint64_t int3 = 0xcc; 
    4.     uint64_t data_with_int3 = ((m_saved_data & ~0xff) | int3); //set bottom byte to 0xcc 
    5.     ptrace(PTRACE_POKEDATA, m_pid, m_addr, data_with_int3); 
    6.     m_enabled = true

    PTRACE_PEEKDATA 请求告诉 ptrace 若何攫取被跟踪过程的内存。我们给它一个过程 ID 和一个地址,然后它返回给我们该地址当前的 64 位内容。 (m_saved_data & ~0xff) 把这个数据的低位字节置零,然后我们用它和我们的 int 3 指令按位或(OR)来设置断点。最后我们经由过程 PTRACE_POKEDATA 用我们的新数据覆盖那部分内存来设置断点。

    disable 的实现比较简单,我们只须要恢复竽暌姑 0xcc 所覆盖的原始数据。

    1. void breakpoint::disable() { 
    2.     ptrace(PTRACE_POKEDATA, m_pid, m_addr, m_saved_data); 
    3.     m_enabled = false

    在调试器中增长断点

    为了支撑经由过程用户界面设置断点,我们要在 debugger 类修改三个处所:

    1. 给 debugger 添加断点存储数据构造
    2. 添加 set_breakpoint_at_address 函数
    3. 给我们的 handle_command 函数添加 break 敕令

    总结

    我会将我的断点保存到 std::unordered_map<std::intptr_t, breakpoint> 构造,以便能简单快速地断定一个给定的地址是否有断点,如不雅有的话,取回该 breakpoint 对象。

    1. class debugger { 
    2.     //... 
    3.     void set_breakpoint_at_address(std::intptr_t addr); 
    4.     //... 
    5. private: 
    6.     //... 
    7.     std::unordered_map<std::intptr_t,breakpoint> m_breakpoints; 

    在 set_breakpoint_at_address 函数中我们会新建一个 breakpoint 对象,启用它,把它添加到数据构造里,并给用户打印一条信息。如不雅你爱好的话,你可以重构所有的输出信息,大年夜而你可以将调试器作为库或者敕令行对象应用,为了简便,我把它们都整合到了一路。

    1. void debugger::set_breakpoint_at_address(std::intptr_t addr) { 
    2.     std::cout << "Set breakpoint at address 0x" << std::hex << addr << std::endl; 
    3.     breakpoint bp {m_pid, addr}; 

    4.   推荐阅读

        央行印发《中国金融业信息技术“十三五”发展规划》

      《筹划》强调,“十三五”时代金融业要周全支撑深化改革,积极对标国际先辈,推动立异普惠成长,保持安然与成长并重,并环绕兼顾监管体系重要性金融机构、兼顾监管金融控股公司>>>详细阅读


      本文标题:开发一个Linux调试器(二):断点

      地址:http://www.17bianji.com/lsqh/35948.html

    关键词: 探索发现

    乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

    网友点评
    自媒体专栏

    评论

    热度

    精彩导读
    栏目ID=71的表不存在(操作类型=0)