这个函数有一点复杂,我们将它拆开来看。
- auto func = get_function_from_pc(get_pc());
- auto func_entry = at_low_pc(func);
- auto func_end = at_high_pc(func);
at_low_pc 和 at_high_pc 是 libelfin 中的函数,它们能给我们指定函数 DWARF 信息条目标最小和最大年夜法度榜样计数器值。
- auto line = get_line_entry_from_pc(func_entry);
- auto start_line = get_line_entry_from_pc(get_pc());
- std::vector<std::intptr_t> breakpoints_to_remove{};
- while (line->address < func_end) {
- if (line->address != start_line->address && !m_breakpoints.count(line->address)) {
- set_breakpoint_at_address(line->address);
- breakpoints_to_remove.push_back(line->address);
- }
- ++line;
- }
我们须要移除我们设置的所有断点,以便不会泄漏出我们的慢慢履行函数,为此我们把它们保存到一个 std::vector 中。为了设置所有断点,我们轮回遍历行表条目直到找到一个不在我们函数范围内的。对于每一个,我们都要确保它不是我们当前地点的行,并且在这个地位还没有设置任何断点。
- auto frame_pointer = get_register_value(m_pid, reg::rbp);
- auto return_address = read_memory(frame_pointer+8);
- if (!m_breakpoints.count(return_address)) {
- set_breakpoint_at_address(return_address);
- to_delete.push_back(return_address);
- }
- continue_execution();
- for (auto addr : to_delete) {
- remove_breakpoint(addr);
- }
最后,我们持续履行直到射中它们中的个一一个断点,然后移除所有我们设置的临时断点。
它并不美不雅,但临时先如许吧。
当然,我们还须要将这个新功能添加到用户界面:
- else if(is_prefix(command, "step")) {
- step_in();
- }
- else if(is_prefix(command, "next")) {
- step_over();
- }
- else if(is_prefix(command, "finish")) {
- step_out();
- }
测试
我经由过程实现一个调用一系列不合函数的简单函数来进行测试:

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