如今我们可以打印出源码了,我们须要将这些经由过程钩子添加到我们的调试器。实现这个的一个好处所是当调试器年腋荷琐断点或者(最终)慢慢履行获得一个旌旗灯号时。到了这里,我们可能想要给我们的调试器添加一些更好的旌旗灯号处理。
更好的旌旗灯号处理
我们欲望可以或许得知什么旌旗灯号被发送给了过程,同样我们也想知道它是若何产生的。例如,我们欲望可以或许得知是否因为射中了一个断点大年夜而获得一个 SIGTRAP,照样因为慢慢履行完成、或者是产生了一个新线程等等导致的。荣幸的是,我们可以再一次应用 ptrace。可以给 ptrace 的一个敕令是 PTRACE_GETSIGINFO,它会给你被发送给过程的最后一个旌旗灯号的信息。我们类似如许应用它:
- siginfo_t debugger::get_signal_info() {
- siginfo_t info;
- ptrace(PTRACE_GETSIGINFO, m_pid, nullptr, &info);
- return info;
- }
这会给我们一个 siginfo_t 对象,它能供给以下信息:
我只须要应用 si_signo 就可以找到被发送的旌旗灯号,应用 si_code 来获取更多关于旌旗灯号的信息。放置这些代码的最好地位是我们的 wait_for_signal 函数:
- void debugger::wait_for_signal() {
- int wait_status;
- auto options = 0;
- waitpid(m_pid, &wait_status, options);
- auto siginfo = get_signal_info();
- switch (siginfo.si_signo) {
- case SIGTRAP:
- handle_sigtrap(siginfo);
- break;
- case SIGSEGV:
- std::cout << "Yay, segfault. Reason: " << siginfo.si_code << std::endl;
- break;
- default:
- std::cout << "Got signal " << strsignal(siginfo.si_signo) << std::endl;
- }
- }
如今再来处理 SIGTRAP。知道当射一一个断点时会发送 SI_KERNEL 或 TRAP_BRKPT,而慢慢履行停止时会发送 TRAP_TRACE 就足够了:
这里有一大年夜堆不合风格的旌旗灯号你可以处理。查看 man sigaction 获取更多信息。
因为当我们收到 SIGTRAP 旌旗灯号时我们已经修改了法度榜样计数器的值,我们可以大年夜 step_over_breakpoint 中移除这些代码,如今它看起来类似:
- void debugger::step_over_breakpoint() {
- if (m_breakpoints.count(get_pc())) {
- auto& bp = m_breakpoints[get_pc()];
- if (bp.is_enabled()) {
- bp.disable();
- ptrace(PTRACE_SINGLESTEP, m_pid, nullptr, nullptr);
- wait_for_signal();
- bp.enable();
- }
- }
推荐阅读
概述秦人不暇自哀,而后人哀之;后人哀之而不鉴之,亦使后人而复哀后人也! –论面向文档编程的重要性如不雅想看见识一小我写代码的功力,注释其实是区分老司机和小鲜肉的一个明显的分界线(有没有不雅察碘晾髑公司的>>>详细阅读
地址:http://www.17bianji.com/lsqh/36965.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示