linux 源码 调试,开发一个Linux调试器(六):源码级逐步执行
我們計算編寫這些函數異常簡單的版本,但真正的調試器有 thread plan 的概念,它封裝了所有的單步信息。例如,調試器可能有一些復雜的邏輯去決定斷點的地位,然后有一些回調函數用于斷定單步操作是否完成。這個中有異常多的基本舉措措施,我們只采取一種樸實的辦法。我們可能會心外埠跳過斷點,但如不雅你愿意的話,你可以花一些時光把所有的細節都處理好。
系列文┞仿索引
跟著后面文┞仿的宣布,這些鏈接會逐漸生效。預備情況
斷點
存放器和內存
Elves 和 dwarves
源碼和旌旗燈號
源碼級慢慢履行
源碼級斷點
調用棧展開
攫取變量
下一步
揭秘指令級慢慢履行
在前幾篇博文中我們進修了 DWARF 信息以及它若何使我們將機械碼和上層源碼接洽起來。這一次我們經由過程為我們的調試器添加源碼級慢慢調試將該常識應用于實際。
我們正在超出了自我。起首讓我們經由過程用戶接口揭秘指令級單步履行。我決定將它切分為能被其它部分代碼應用的 single_step_instruction 和確保是否啟用了某個斷點的 single_step_instruction_with_breakpoint_check 兩個函數。void?debugger::single_step_instruction()?{
ptrace(PTRACE_SINGLESTEP,?m_pid,?nullptr,?nullptr);
wait_for_signal();
}
void?debugger::single_step_instruction_with_breakpoint_check()?{
//起首,檢查我們是否須要停用或者啟用某個斷點
if?(m_breakpoints.count(get_pc()))?{
step_over_breakpoint();
}
else{
single_step_instruction();
}
}
正如以往,另一個敕令被集成到我們的 handle_command 函數:elseif(is_prefix(command,"stepi"))?{
single_step_instruction_with_breakpoint_check();
auto?line_entry?=?get_line_entry_from_pc(get_pc());
print_source(line_entry->file->path,?line_entry->line);
}
應用新增的┞封些函數我們可以開端實現我們的源碼級慢慢履行函數。
實現慢慢履行
對于彪炳 step_out,我們只是在函數的返回地址處設一個斷點然后持續履行。我臨時還不想推敲調用棧展開的細節 - 這些都邑在后面的部分介紹 - 但可以說返回地址就保存在棧幀開端的后 8 個字節中。是以我們會攫取棧指針然后在內存相對應的地址攫取值:void?debugger::step_out()?{
auto?frame_pointer?=?get_register_value(m_pid,?reg::rbp);
auto?return_address?=?read_memory(frame_pointer+8);
bool?should_remove_breakpoint?=?false;
if?(!m_breakpoints.count(return_address))?{
set_breakpoint_at_address(return_address);
should_remove_breakpoint?=?true;
}
continue_execution();
if?(should_remove_breakpoint)?{
remove_breakpoint(return_address);
推薦閱讀
run(getData) 在 JavaScript 的世比賽,所有代碼都是單線程履行的,因為這個“缺點”,導致 JavaScript 的所有收集操作,瀏覽器事宜,都必須是異步履行。異步操作會在將來的某個>>>詳細閱讀
地址:http://www.17bianji.com/lsqh/36973.html
總結
以上是生活随笔為你收集整理的linux 源码 调试,开发一个Linux调试器(六):源码级逐步执行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux sysconf函数,linu
- 下一篇: linux apt qt下载,Linux