精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

精品国产精品一区二区夜夜嗨| 成人免费一区二区三区在线观看 | 国产直播在线| 久久久99精品免费观看不卡| 成人精品视频久久久久| 国产午夜久久久| 欧州一区二区| 亚洲成人网在线观看| 冲田杏梨av在线| 91在线三级| 国产精品福利在线播放| 精品在线一区| 国产白浆在线观看| 久久一二三四| 欧美成人激情视频免费观看| 国产精品毛片一区二区| caoporn成人| 欧美日韩国产大片| 国产成人a亚洲精v品无码| 国产原创精品视频| 国产喂奶挤奶一区二区三区 | 夜色77av精品影院| 91精品国产综合久久福利 | 久久久久免费看| 日韩专区精品| 亚洲无限av看| 国产 中文 字幕 日韩 在线| 中文成人在线| 欧美视频一区二区三区四区| 噜噜噜久久亚洲精品国产品麻豆| av观看在线| 亚洲欧洲成人自拍| 亚洲精蜜桃久在线| 国产在线视频资源| 26uuu欧美日本| 狠狠色综合色区| 国产综合无码一区二区色蜜蜜| 极品美女销魂一区二区三区免费 | 97视频久久久| 黄色在线看片| 亚洲精品美国一| 日韩人妻一区二区三区蜜桃视频| 北岛玲一区二区三区| 久久久三级国产网站| 久热国产精品视频一区二区三区| 丰满少妇高潮在线观看| 嫩草香蕉在线91一二三区| 亚洲成a人片| 亚洲国产aⅴ天堂久久| www国产免费| 性欧美1819sex性高清大胸| 中文字幕欧美一| 国产系列第一页| 大片免费在线观看| 亚洲乱码中文字幕| 国产精品igao激情视频| 91cn在线观看| 亚洲综合激情网| 黄色三级中文字幕| 里番在线播放| 天天影视涩香欲综合网| 亚洲熟妇av一区二区三区漫画| 678在线观看视频| 狠狠干狠狠久久| 国产精品人人妻人人爽人人牛| 在线观看精品| 欧美日韩国产一区| 中文写幕一区二区三区免费观成熟| 国内精品视频| 亚洲国产精品va| asian性开放少妇pics| 国产精品一区高清| 日韩在线www| 精品视频久久久久| aa国产精品| 国产精品女主播| 99国产精品久久久久久久成人| 国产精品538一区二区在线| 国产精品一区二区欧美黑人喷潮水| 黄色一级大片在线免费看国产一| 99re亚洲国产精品| 亚洲电影免费| 国产美女一区视频| 日本高清视频一区二区| 久久精品视频在线观看免费| 国产精品一区二区中文字幕| 国产一区二区三区视频| 天天操天天操天天操天天操天天操| 精品福利电影| 日韩免费在线免费观看| 亚洲性在线观看| 不卡一区中文字幕| 亚洲日本精品| 老色鬼在线视频| 欧美日韩精品综合在线| 亚洲av熟女高潮一区二区| 欧美一区2区| 久久久久久九九九| 亚洲av人无码激艳猛片服务器| 国产乱码精品一区二区三区五月婷| 狠狠干一区二区| 国产在线看片| 91成人看片片| 亚洲美女精品视频| 久久精品国产68国产精品亚洲| 久久久天堂国产精品女人| 中国老头性行为xxxx| 成年人国产精品| 91九色国产ts另类人妖| 欧美va在线观看| 精品乱人伦小说| 久久久久久久久久97| 国产日韩一区二区三区在线| 亚洲jizzjizz日本少妇| 国产小视频在线| 亚洲va欧美va天堂v国产综合| 波多野结衣天堂| 日本精品影院| 欧美国产极速在线| av网站在线免费看| 国产精品视频免费看| 久久9精品区-无套内射无码| 成人18夜夜网深夜福利网| 久久精品久久久久久| 91丨九色丨海角社区| 91亚洲永久精品| 欧美日韩不卡在线视频| 日韩一区二区三区精品| 俺也去精品视频在线观看| 在线播放精品视频| 国产日韩欧美在线一区| 国产免费毛卡片| 欧美理论电影在线精品| 久久久久这里只有精品| www.成人精品| 一区二区三区色| 91av免费观看| 韩国久久久久| 国产精品果冻传媒潘| 青草影视电视剧免费播放在线观看| 欧美精品自拍偷拍| 中文字幕观看av| 国产在线精品一区二区夜色| 伊人狠狠色丁香综合尤物| 久久久免费人体| 日韩网站免费观看高清| 国产伦理吴梦梦伦理| 中文字幕一区不卡| 九九热视频免费| 午夜日韩av| 成人一区二区三区四区| av老司机在线观看| 日韩av在线免播放器| 在线能看的av| 久久综合九色综合久久久精品综合| 乱妇乱女熟妇熟女网站| 综合国产视频| 国产精品久久久久久久久久尿| 成人影视在线播放| 欧美日韩精品免费观看视频| 潘金莲一级黄色片| 岛国av在线一区| 男人日女人bb视频| 欧美理论在线播放| 91亚洲精品久久久久久久久久久久| av在线免费网站| 精品国产成人在线影院| 亚洲日本视频在线观看| 国产欧美一区视频| 国产一级片中文字幕| 亚洲午夜电影| 欧美一区二区三区在线播放| 久久日本片精品aaaaa国产| 麻豆成人在线看| 日日躁夜夜躁白天躁晚上躁91| 欧美日韩黄色大片| 香蕉久久久久久久| 国产成a人无v码亚洲福利| 国产精品裸体瑜伽视频| 色综合五月天| 国产九色精品| 成人久久网站| 高清一区二区三区四区五区| 国产有码在线| 日韩一区二区三区电影在线观看| 日韩成年人视频| 国产精品热久久久久夜色精品三区| 深夜做爰性大片蜜桃| 亚洲一区日韩| 国产精品igao激情视频| 欧美精品尤物在线观看| 国产91视觉| 男人天堂久久| 18性欧美xxxⅹ性满足| 人人干在线视频| 日韩电视剧在线观看免费网站| 亚洲影院一区二区三区| 天天综合天天综合色| 97在线观看免费高| 国产日韩欧美一区二区三区乱码| 中文字幕一二三| 蜜臀av在线播放一区二区三区| 日本xxxxxxxxxx75| 中文字幕一区二区三区乱码图片 | 17c精品麻豆一区二区免费| 性活交片大全免费看| 久久国产精品一区二区| 亚洲色欲综合一区二区三区| 欧美国产三区| 亚洲欧美日韩精品综合在线观看 | 亚洲精品中字| 色老板在线视频一区二区| 亚洲永久免费观看| 色猫猫成人app| 欧美在线一区二区三区四| a视频在线观看免费| 中文字幕视频一区二区在线有码| 色欲av伊人久久大香线蕉影院| 欧美夫妻性生活| 免费黄色一级大片| 色综合网站在线| 影音先锋亚洲天堂| 午夜伊人狠狠久久| 校园春色 亚洲| 亚洲欧洲另类国产综合| 一级黄色录像毛片| 久久精品一区二区三区不卡牛牛| 师生出轨h灌满了1v1| 国产在线精品视频| 日韩av自拍偷拍| 经典三级在线一区| www.com污| 久久99久久99| 久久久精品高清| 九色综合国产一区二区三区| 亚洲人辣妹窥探嘘嘘| 日韩精品1区2区3区| 欧美 国产 小说 另类| 亚洲欧美久久| 色欲av无码一区二区人妻| 99国产精品| 欧美一级在线看| 欧美专区18| 国产精品wwwww| 三级久久三级久久| 亚洲成人av免费看| 美女mm1313爽爽久久久蜜臀| 亚洲免费看av| 精品一二三四区| 一级黄色片国产| 国产精品888| 久久久老熟女一区二区三区91| 成人18精品视频| 瑟瑟视频在线观看| 国产嫩草影院久久久久| 国产aaaaaaaaa| 亚洲欧洲成人自拍| 国产亚洲精品久久久久久打不开| 亚洲一区中文日韩| 精品成人av一区二区在线播放| 欧美午夜美女看片| 国产情侣小视频| 欧美电影一区二区| 国产福利第一视频| 亚洲精品v天堂中文字幕| 黄网在线免费| 精品国产美女在线| 丰满大乳少妇在线观看网站| 欧美亚洲第一页| 91精品国产66| 91福利视频导航| 亚洲制服欧美另类| 一区二区视频国产| 狠狠爱综合网| 草草草在线视频| 国产精品正在播放| 粉嫩av蜜桃av蜜臀av| 国产精品进线69影院| 久久久综合久久| 色香蕉成人二区免费| 国产免费久久久| 日韩成人激情视频| 免费观看成人高潮| 97超级碰在线看视频免费在线看| 日韩欧美少妇| 国产无套精品一区二区| 波多野结衣在线播放一区| 大桥未久一区二区三区| 久久高清国产| 色婷婷狠狠18禁久久| 久久婷婷国产综合精品青草| 神马久久精品综合| 精品久久久久久久久久国产| 一级黄色片免费看| 日韩精品www| 1区2区3区在线视频| 国产精品第七十二页| 国产成人一二片| 夜夜爽99久久国产综合精品女不卡| 午夜精品av| 亚洲熟妇av一区二区三区| 国产在线播放一区三区四| 日本三级日本三级日本三级极| 国产精品护士白丝一区av| 国内精品福利视频| 欧美va亚洲va香蕉在线| 免费a在线看| 国产成人综合亚洲| 欧美黄色影院| 黄色a级片免费看| 久久99热99| av在线播放中文字幕| 岛国av一区二区| 黄色一级a毛片| 欧美激情免费观看| 日韩高清二区| 亚洲 欧洲 日韩| 麻豆精品新av中文字幕| 欧美做受xxxxxⅹ性视频| 亚洲一区二区三区四区在线| 91国偷自产中文字幕久久| 亚洲香蕉av在线一区二区三区| 国产亚洲成av人片在线观看 | 国产探花一区在线观看| 亚洲国产成人精品无码区99| 国产成人精品亚洲777人妖| 91免费公开视频| 欧美精品 国产精品| 91福利在线视频| 国产精品久久久久久久久免费看| 日韩欧美黄色| 少妇性饥渴无码a区免费| caoporn国产一区二区| 国产一级片免费| 精品播放一区二区| 草美女在线观看| 国产乱码精品一区二区三区卡 | 亚洲视频你懂的| 91久久国语露脸精品国产高跟| 亚洲午夜精品久久久久久性色 | 在线日韩欧美| 国产免费一区二区三区最新6| 亚洲一区二区精品视频| 欧美熟妇交换久久久久久分类 | 99久久免费观看| 国产成人精品免费在线| 欧美人妻一区二区| 欧美videos大乳护士334| 国模私拍视频在线播放| 国产欧美韩日| 一区二区高清| caopeng视频| 欧美三级资源在线| 日本在线视频观看| 亚洲一区中文字幕在线观看| 伊人青青综合网| 欧洲熟妇的性久久久久久| 五月天婷婷综合| 黄色av网址在线免费观看| 国产精品青草久久久久福利99| 三上亚洲一区二区| 国产一级片中文字幕| 亚洲高清三级视频| 欧美在线观看在线观看| 国产日韩欧美黄色| 欧美欧美全黄| 亚洲做受高潮无遮挡| 欧美视频一区在线| 欧美aaa免费| 欧美成人一区二区在线| 奇米一区二区三区av| 青青青在线免费观看| 亚洲国产福利在线| 成人影院在线免费观看| 精品国产一区二区三区在线| av影院午夜一区| 国产裸体美女永久免费无遮挡| 日韩视频亚洲视频| 免费福利视频一区| 羞羞的视频在线| 亚洲国产sm捆绑调教视频| 国产露出视频在线观看| 亚洲综合中文字幕在线观看| 国产精品久久久一区二区| 免费看日本黄色片| 欧美精品一区二区三区蜜臀 | 欧美在线你懂得| 羞羞网站在线免费观看| 品久久久久久久久久96高清| 国产尤物一区二区在线| 影音先锋在线国产| 美日韩精品免费视频| 欧美女优在线视频| 中文字幕一区二区三区人妻在线视频 | 成人综合在线网站| 国产又粗又猛又爽又| 97久久精品人搡人人玩| 我不卡影院28| www.狠狠爱| 亚洲成在人线av|