精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

開發一個Linux調試器(六):源碼級逐步執行

系統 Linux
在前幾篇博文中我們學習了 DWARF 信息以及它如何使我們將機器碼和上層源碼聯系起來。這一次我們通過為我們的調試器添加源碼級逐步調試將該知識應用于實際。

[[201417]]

在前幾篇博文中我們學習了 DWARF 信息以及它如何使我們將機器碼和上層源碼聯系起來。這一次我們通過為我們的調試器添加源碼級逐步調試將該知識應用于實際。

系列文章索引

隨著后面文章的發布,這些鏈接會逐漸生效。

  1. 準備環境
  2. 斷點
  3. 寄存器和內存
  4. Elves 和 dwarves
  5. 源碼和信號
  6. 源碼級逐步執行
  7. 源碼級斷點
  8. 調用棧展開
  9. 讀取變量
  10. 下一步

揭秘指令級逐步執行

我們正在超越了自我。首先讓我們通過用戶接口揭秘指令級單步執行。我決定將它切分為能被其它部分代碼利用的 single_step_instruction 和確保是否啟用了某個斷點的 single_step_instruction_with_breakpoint_check 兩個函數。

  1. void debugger::single_step_instruction() { 
  2.     ptrace(PTRACE_SINGLESTEP, m_pid, nullptr, nullptr); 
  3.     wait_for_signal(); 
  4. void debugger::single_step_instruction_with_breakpoint_check() { 
  5.     //首先,檢查我們是否需要停用或者啟用某個斷點 
  6.     if (m_breakpoints.count(get_pc())) { 
  7.         step_over_breakpoint(); 
  8.     } 
  9.     else { 
  10.         single_step_instruction(); 
  11.     } 

正如以往,另一個命令被集成到我們的 handle_command 函數:

  1. else if(is_prefix(command, "stepi")) { 
  2.     single_step_instruction_with_breakpoint_check(); 
  3.     auto line_entry = get_line_entry_from_pc(get_pc()); 
  4.     print_source(line_entry->file->path, line_entry->line); 
  5.  } 

利用新增的這些函數我們可以開始實現我們的源碼級逐步執行函數。

實現逐步執行

我們打算編寫這些函數非常簡單的版本,但真正的調試器有 thread plan 的概念,它封裝了所有的單步信息。例如,調試器可能有一些復雜的邏輯去決定斷點的位置,然后有一些回調函數用于判斷單步操作是否完成。這其中有非常多的基礎設施,我們只采用一種樸素的方法。我們可能會意外地跳過斷點,但如果你愿意的話,你可以花一些時間把所有的細節都處理好。

對于跳出 step_out,我們只是在函數的返回地址處設一個斷點然后繼續執行。我暫時還不想考慮調用棧展開的細節 - 這些都會在后面的部分介紹 - 但可以說返回地址就保存在棧幀開始的后 8 個字節中。因此我們會讀取棧指針然后在內存相對應的地址讀取值:

  1. void debugger::step_out() { 
  2.     auto frame_pointer = get_register_value(m_pid, reg::rbp); 
  3.     auto return_address = read_memory(frame_pointer+8); 
  4.     bool should_remove_breakpoint = false
  5.     if (!m_breakpoints.count(return_address)) { 
  6.         set_breakpoint_at_address(return_address); 
  7.         should_remove_breakpoint = true
  8.     } 
  9.     continue_execution(); 
  10.     if (should_remove_breakpoint) { 
  11.         remove_breakpoint(return_address); 
  12.     } 

remove_breakpoint 是一個小的幫助函數:

  1. void debugger::remove_breakpoint(std::intptr_t addr) { 
  2.     if (m_breakpoints.at(addr).is_enabled()) { 
  3.         m_breakpoints.at(addr).disable(); 
  4.     } 
  5.     m_breakpoints.erase(addr); 

接下來是跳入 step_in。一個簡單的算法是繼續逐步執行指令直到新的一行。

  1. void debugger::step_in() { 
  2.    auto line = get_line_entry_from_pc(get_pc())->line; 
  3.     while (get_line_entry_from_pc(get_pc())->line == line) { 
  4.         single_step_instruction_with_breakpoint_check(); 
  5.     } 
  6.     auto line_entry = get_line_entry_from_pc(get_pc()); 
  7.     print_source(line_entry->file->path, line_entry->line); 

跳過 step_over 對于我們來說是三個中最難的。理論上,解決方法就是在下一行源碼中設置一個斷點,但下一行源碼是什么呢?它可能不是當前行后續的那一行,因為我們可能處于一個循環、或者某種條件結構之中。真正的調試器一般會檢查當前正在執行什么指令然后計算出所有可能的分支目標,然后在所有分支目標中設置斷點。對于一個小的項目,我不打算實現或者集成一個 x86 指令模擬器,因此我們要想一個更簡單的解決辦法。有幾個可怕的選擇,一個是一直逐步執行直到當前函數新的一行,或者在當前函數的每一行都設置一個斷點。如果我們是要跳過一個函數調用,前者將會相當的低效,因為我們需要逐步執行那個調用圖中的每個指令,因此我會采用第二種方法。

  1. void debugger::step_over() { 
  2.     auto func = get_function_from_pc(get_pc()); 
  3.     auto func_entry = at_low_pc(func); 
  4.     auto func_end = at_high_pc(func); 
  5.     auto line = get_line_entry_from_pc(func_entry); 
  6.     auto start_line = get_line_entry_from_pc(get_pc()); 
  7.     std::vector<std::intptr_t> to_delete{}; 
  8.     while (line->address < func_end) { 
  9.         if (line->address != start_line->address && !m_breakpoints.count(line->address)) { 
  10.             set_breakpoint_at_address(line->address); 
  11.             to_delete.push_back(line->address); 
  12.         } 
  13.         ++line; 
  14.     } 
  15.     auto frame_pointer = get_register_value(m_pid, reg::rbp); 
  16.     auto return_address = read_memory(frame_pointer+8); 
  17.     if (!m_breakpoints.count(return_address)) { 
  18.         set_breakpoint_at_address(return_address); 
  19.         to_delete.push_back(return_address); 
  20.     } 
  21.     continue_execution(); 
  22.     for (auto addr : to_delete) { 
  23.         remove_breakpoint(addr); 
  24.     } 

這個函數有一點復雜,我們將它拆開來看。

  1. auto func = get_function_from_pc(get_pc()); 
  2. auto func_entry = at_low_pc(func); 
  3. auto func_end = at_high_pc(func); 

at_low_pc 和 at_high_pc 是 libelfin 中的函數,它們能給我們指定函數 DWARF 信息條目的最小和***程序計數器值。

  1. auto line = get_line_entry_from_pc(func_entry); 
  2. auto start_line = get_line_entry_from_pc(get_pc()); 
  3. std::vector<std::intptr_t> breakpoints_to_remove{}; 
  4. while (line->address < func_end) { 
  5.     if (line->address != start_line->address && !m_breakpoints.count(line->address)) { 
  6.         set_breakpoint_at_address(line->address); 
  7.         breakpoints_to_remove.push_back(line->address); 
  8.     } 
  9.     ++line; 

我們需要移除我們設置的所有斷點,以便不會泄露出我們的逐步執行函數,為此我們把它們保存到一個 std::vector 中。為了設置所有斷點,我們循環遍歷行表條目直到找到一個不在我們函數范圍內的。對于每一個,我們都要確保它不是我們當前所在的行,而且在這個位置還沒有設置任何斷點。

  1. auto frame_pointer = get_register_value(m_pid, reg::rbp); 
  2.     auto return_address = read_memory(frame_pointer+8); 
  3.     if (!m_breakpoints.count(return_address)) { 
  4.         set_breakpoint_at_address(return_address); 
  5.         to_delete.push_back(return_address); 
  6.     } 

這里我們在函數的返回地址處設置一個斷點,正如跳出 step_out。

  1. continue_execution(); 
  2. for (auto addr : to_delete) { 
  3.     remove_breakpoint(addr); 

***,我們繼續執行直到***它們中的其中一個斷點,然后移除所有我們設置的臨時斷點。

它并不美觀,但暫時先這樣吧。

當然,我們還需要將這個新功能添加到用戶界面:

  1. else if(is_prefix(command, "step")) { 
  2.     step_in(); 
  3. else if(is_prefix(command, "next")) { 
  4.     step_over(); 
  5. else if(is_prefix(command, "finish")) { 
  6.     step_out(); 

測試

我通過實現一個調用一系列不同函數的簡單函數來進行測試:

  1. void a() { 
  2.     int foo = 1; 
  3. void b() { 
  4.     int foo = 2; 
  5.     a(); 
  6. void c() { 
  7.     int foo = 3; 
  8.     b(); 
  9. void d() { 
  10.     int foo = 4; 
  11.     c(); 
  12. void e() { 
  13.     int foo = 5; 
  14.     d(); 
  15. void f() { 
  16.     int foo = 6; 
  17.     e(); 
  18. int main() { 
  19.     f(); 

你應該可以在 main 地址處設置一個斷點,然后在整個程序中跳入、跳過、跳出函數。如果你嘗試跳出 main 函數或者跳入任何動態鏈接庫,就會出現意料之外的事情。

你可以在這里找到這篇博文的相關代碼。下次我們會利用我們新的 DWARF 技巧來實現源碼級斷點。 

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2017-09-25 08:04:31

Linux調試器源碼級斷點

2017-08-28 14:40:57

Linux調試器源碼和信號

2017-06-28 14:21:22

Linux調試器斷點

2017-06-22 10:44:55

Linux調試器準備環境

2017-10-09 10:26:01

Linux調試器堆棧展開

2017-10-09 10:56:49

Linux調試器處理變量

2017-10-12 18:20:44

Linux調試器高級主題

2017-07-25 10:30:32

Linux調試器Elves和dwarv

2017-07-05 14:37:07

Linux調試器寄存器和內存

2022-05-23 09:22:20

Go語言調試器Delve

2017-04-19 21:35:38

Linux調試器工作原理

2011-08-25 16:34:27

Lua調試器

2010-03-01 11:06:52

Python 調試器

2020-03-16 10:05:13

EmacsGUDLinux

2009-12-14 10:57:34

Ruby調試器

2011-08-31 16:51:12

Lua調試器

2019-12-06 14:30:41

GNU調試器GDB修復代碼

2023-02-28 11:39:55

CMake腳本項目

2024-03-13 08:00:00

Linux調試器應用程序

2009-06-23 11:05:05

Mircosoft C
點贊
收藏

51CTO技術棧公眾號

青椒成人免费视频| 欧洲亚洲视频| 一区二区三区欧美亚洲| 精品国产一区二区三区四区精华 | 国产一区网站| 欧美精品18+| 狠狠干 狠狠操| 自拍视频在线免费观看| 韩国视频一区二区| 91av在线不卡| 国产稀缺精品盗摄盗拍| 色哟哟精品丝袜一区二区| 欧美疯狂做受xxxx富婆| 北条麻妃在线视频观看| 黄网页免费在线观看| 91在线看国产| 99高清视频有精品视频| 亚洲性猛交富婆| 日韩图片一区| 欧美成在线视频| 久久精品三级视频| 小说区图片区色综合区| 日韩一二三区不卡| 一区二区免费av| 日本精品另类| 丁香五六月婷婷久久激情| 午夜精品一区二区三区在线观看| 亚洲黄色精品视频| 久久99国内精品| 国产精品草莓在线免费观看| 日韩欧美激情视频| 欧美99在线视频观看| 亚洲人成毛片在线播放| 日本国产在线视频| 亚洲国产欧美国产第一区| 欧美影院午夜播放| 人妻无码视频一区二区三区| 爱情岛亚洲播放路线| 亚洲色图视频网站| 亚洲精品日韩在线观看| 亚州男人的天堂| 成人毛片在线观看| 国产不卡一区二区在线观看 | 亚洲成人久久网| 中文 日韩 欧美| 中文字幕日韩亚洲| 337p亚洲精品色噜噜| xx欧美撒尿嘘撒尿xx| 三上悠亚亚洲一区| 欧美性一区二区| 老司机午夜av| 澳门av一区二区三区| 91久久人澡人人添人人爽欧美| 久久久久久久中文| 久久久男人天堂| 欧美日韩综合视频| www.亚洲天堂网| 国产精品扒开腿做爽爽爽视频软件| 精品av在线播放| 免费黄色日本网站| 成人午夜精品| 欧美精品在线视频| 成年人看片网站| 风间由美性色一区二区三区四区| 精品国产亚洲在线| 国产又黄又粗又猛又爽的视频| 开心激情综合| 亚洲欧美日韩精品久久| 丁香激情五月少妇| 久久久久av| 欧美极品少妇xxxxⅹ免费视频 | 丝袜美腿成人在线| 国产精品日韩久久久久| 国产一区二区三区在线观看| 国产一区不卡精品| 国产欧美一区二区在线播放| 亚洲欧美日韩精品永久在线| 久久精品亚洲乱码伦伦中文| 日韩欧美在线一区二区| eeuss影院在线观看| 中文字幕欧美一| 欧美日韩dvd| 成人免费观看在线观看| 欧美在线你懂的| 天堂av手机在线| 日韩精品丝袜美腿| 日韩一级黄色av| 久久精品国产亚洲av高清色欲| 国产精品女主播一区二区三区| 国产999精品久久久影片官网| 在线免费观看一级片| 国产成人av一区二区三区在线 | 99精品在线直播| 天堂资源最新在线| 中文字幕一区二区在线播放| 国产69精品久久久久久久| 91精品影视| 欧美一级久久久久久久大片| 添女人荫蒂视频| 天天av综合| 7777精品视频| 99热这里只有精品66| 91网站最新网址| 99热一区二区三区| 香蕉久久免费电影| 精品国产不卡一区二区三区| 夫妇交换中文字幕| 99亚洲一区二区| 成人在线观看视频网站| 九色视频在线观看免费播放 | 日韩有码片在线观看| 日韩欧美亚洲一区二区三区| 久久精品国产久精国产爱| 久久99久久99精品蜜柚传媒| 成人无遮挡免费网站视频在线观看| 懂色aⅴ精品一区二区三区蜜月| 91小视频在线播放| 国产最新精品| 久久免费视频这里只有精品| 国产精品久久久久久69| 国产性做久久久久久| 免费看日本黄色| 日本午夜精品久久久久| 亚洲视频免费一区| 一区二区三区视频免费看| 国产麻豆午夜三级精品| 一区二区不卡在线| 免费观看成人性生生活片 | 亚洲伊人第一页| 在线视频二区| 欧美午夜精品久久久久久孕妇 | 中文字幕中文字幕精品| 久久久久久91| 国精品人妻无码一区二区三区喝尿| 最新国产成人在线观看| 日韩av在线中文| 欧美系列电影免费观看| 国产盗摄xxxx视频xxx69| 日本1级在线| 日韩欧美中文第一页| 国产精品久久AV无码| 亚洲久色影视| 精品免费日产一区一区三区免费| 97天天综合网| 亚洲第一福利网站| 91在线看视频| 成人av免费观看| 久久国产亚洲精品无码| 狼人天天伊人久久| 欧美最猛性xxxxx(亚洲精品)| 污视频软件在线观看| 欧美日韩国产影院| 精品少妇一区二区三区免费观| 亚洲中午字幕| 日韩欧美电影一区二区| 97精品国产综合久久久动漫日韩| 国产亚洲在线播放| 中文字幕在线播放av| 国产精品久久久久久久久久免费看| 国产一级做a爰片久久| 欧美疯狂party性派对| 国产在线视频2019最新视频| 欧美r级在线| 日韩一二在线观看| 中日韩黄色大片| 久久亚洲一级片| 成年网站在线播放| 888久久久| 国产美女精品久久久| 国产黄大片在线观看| 亚洲色在线视频| 888奇米影视| 亚洲一二三专区| 亚洲精品乱码久久久久久不卡| 午夜在线a亚洲v天堂网2018| 色一情一区二区三区四区| 97久久网站| 欧美激情视频网址| 青青久草在线| 欧美人体做爰大胆视频| 久久国产露脸精品国产| 久久久亚洲精品石原莉奈 | 美女日韩一区| 欧美亚洲国产精品| 黄色网址免费在线观看| 亚洲国产成人久久综合一区| 亚洲第一网站在线观看| 日韩码欧中文字| 91精品人妻一区二区三区蜜桃2| 国产精品社区| 一区二区日本| 欧美性生活一级片| 成人欧美一区二区三区黑人孕妇| 国产精品蜜臀| 色哟哟网站入口亚洲精品| 草草视频在线播放| 欧美中文字幕久久| 亚洲精品在线观看av| 国产精品天天看| 午夜男人的天堂| 久久99精品久久久久久动态图| 霍思燕三级露全乳照| 婷婷综合在线| 欧美一二三区| 欧美色图婷婷| 成人在线观看网址| 国产成人77亚洲精品www| 国内自拍欧美激情| 菠萝蜜视频国产在线播放| 亚洲欧美资源在线| 蜜臀久久久久久999| 欧美日韩国产美女| www.色国产| 亚洲成人免费看| 在线观看亚洲网站| 欧美激情在线看| 人人妻人人澡人人爽人人精品| 国产精品一区二区黑丝| 日本xxxx黄色| 日韩电影在线一区| 国产成人a亚洲精v品无码| 亚洲视频狠狠| 97在线免费视频观看| 99久久久久| 亚洲成人网上| 精品国产乱码久久久久久1区2匹| 国语精品免费视频| 91蝌蚪精品视频| 91丨九色丨国产| 99久久这里有精品| 国产日韩综合一区二区性色av| 欧美粗大gay| 国产脚交av在线一区二区| 在线免费av资源| 午夜精品福利电影| 第一福利在线视频| 午夜精品一区二区三区在线视频 | 91日韩在线| 亚洲精品成人自拍| 成人写真视频| 亚洲午夜精品久久久中文影院av| 欧美男同视频网| 茄子视频成人在线观看 | 国产精品av免费| 久久在线免费| 欧美日韩在线免费观看视频| 日韩亚洲一区在线| 亚洲一区二区在线免费观看| 欧美日韩性在线观看| 亚洲春色在线视频| 97精品97| 欧美交换配乱吟粗大25p| 欧美在线视屏| 国产主播自拍av| 国产日韩一区二区三区在线播放 | 国产一本一道久久香蕉| 黄色aaaaaa| 国产宾馆实践打屁股91| 一级欧美一级日韩片| 久久久三级国产网站| 能直接看的av| 亚洲人精品午夜| 国产真实乱人偷精品视频| 欧美日韩加勒比精品一区| 国产精品suv一区| 精品视频一区 二区 三区| 91在线观看喷潮| 精品毛片乱码1区2区3区| 男人天堂综合网| 亚洲欧美在线播放| 秋霞午夜理伦电影在线观看| 色综合久综合久久综合久鬼88| а_天堂中文在线| 国产不卡精品视男人的天堂| 久久久久久久性潮| 国产精华一区二区三区| 影视先锋久久| 午夜啪啪福利视频| 夜夜嗨网站十八久久| 91精品无人成人www| 国产成人精品一区二区三区网站观看| 国产极品一区二区| 日本一区二区不卡视频| 日韩女优一区二区| 狠狠色噜噜狠狠狠狠97| 国产免费一区二区三区免费视频| 亚洲精品一线二线三线| 成人精品一区二区三区校园激情| 欧美成人免费大片| 伊伊综合在线| 成人三级在线| 久久国产影院| 97超碰青青草| 国产一区二区精品在线观看| 五月开心播播网| 亚洲精品成人悠悠色影视| 怡红院av久久久久久久| 日韩欧美黄色影院| 成人在线免费视频| 午夜精品久久久久久久白皮肤 | 精品欧美一区二区在线观看| 韩国三级在线观看久| 欧美人与性动交a欧美精品| 欧美成人性网| 精品日本一区二区| 综合激情网站| 中文av字幕在线观看| 2017欧美狠狠色| 伊人国产在线观看| 538prom精品视频线放| 大乳在线免费观看| 欧美一级片一区| 国产精品毛片av| 国产精品88久久久久久妇女 | 欧美老女人bb| 中文字幕亚洲不卡| chinese国产精品| 亚洲国产高潮在线观看| 97caopron在线视频| 国产精选久久久久久| 精品国产一区二区三区av片| 内射国产内射夫妻免费频道| 高清av一区二区| 国产黄在线免费观看| 欧美日韩激情一区二区三区| 日本一卡二卡四卡精品| 97高清免费视频| 都市激情亚洲| 欧美黑人在线观看| 国内成人自拍视频| chinese全程对白| 欧美日韩国产免费一区二区| 成人在线免费视频| 国产精品高清在线| 精品久久久久久久| 黄色国产精品视频| 26uuu亚洲| 色av性av丰满av| 亚洲欧洲国产一区| 欧美人体一区二区三区| 欧美一级日本a级v片| 久久综合影视| 日本高清黄色片| 欧美日韩在线综合| 午夜毛片在线| 亚洲free性xxxx护士白浆| 欧美日韩国产免费观看| 久久久久久婷婷| 岛国av一区二区| 国产精品久久一区二区三区不卡 | 人妻精品无码一区二区三区| 99久久久免费精品国产一区二区| 日韩美女视频网站| 亚洲女成人图区| 精品视频一区二区三区四区五区| 水蜜桃一区二区三区| 免费高清在线一区| 成人在线观看免费完整| 日韩精品在线网站| av中文在线资源库| 欧洲精品一区色| 蜜桃在线一区二区三区| 欧美第一页在线观看| 欧美成人国产一区二区| 国产精品高颜值在线观看| 欧美重口乱码一区二区| 看电视剧不卡顿的网站| 久久久久久久久久网站| 日韩www在线| 国产第一亚洲| 欧美中文字幕在线观看视频| 99久久99久久精品国产片果冻| 无码人妻精品一区二区50| 日韩在线激情视频| 亚洲亚洲一区二区三区| 色综合av综合无码综合网站| 国产精品成人免费| 亚洲精品成人电影| 日本精品中文字幕| 女人香蕉久久**毛片精品| 爱爱免费小视频| 在线成人免费视频| 两个人看的在线视频www| 夜夜爽www精品| 99re8在线精品视频免费播放| 中文字幕无码乱码人妻日韩精品| 欧美成人sm免费视频| 天天久久夜夜| 亚洲在线观看网站| 欧美午夜视频一区二区| 国产激情视频在线观看| 另类欧美小说| 国产乱国产乱300精品| 亚洲精品男人的天堂| 久久成人在线视频| 久久av综合| 欧美xxxxx精品| 8x8x8国产精品| 亚洲国产福利| 成人小视频在线观看免费|