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

開發(fā)一個Linux調(diào)試器(八):堆棧展開

系統(tǒng) Linux
有時你需要知道的最重要的信息是什么,你當(dāng)前的程序狀態(tài)是如何到達(dá)那里的。有一個 backtrace 命令,它給你提供了程序當(dāng)前的函數(shù)調(diào)用鏈。這篇文章將向你展示如何在 x86_64 上實現(xiàn)堆棧展開以生成這樣的回溯。

[[205544]]

有時你需要知道的最重要的信息是什么,你當(dāng)前的程序狀態(tài)是如何到達(dá)那里的。有一個 backtrace 命令,它給你提供了程序當(dāng)前的函數(shù)調(diào)用鏈。這篇文章將向你展示如何在 x86_64 上實現(xiàn)堆棧展開以生成這樣的回溯。

系列索引

這些鏈接將會隨著其他帖子的發(fā)布而上線。

  1. 準(zhǔn)備環(huán)境
  2. 斷點
  3. 寄存器和內(nèi)存
  4. ELF 和 DWARF
  5. 源碼和信號
  6. 源碼級逐步執(zhí)行
  7. 源碼級斷點
  8. 堆棧展開
  9. 讀取變量
  10. 之后步驟

用下面的程序作為例子:

  1. void a() { 
  2.     //stopped here 
  3. void b() { 
  4.      a(); 
  5. void c() { 
  6.      a(); 
  7. int main() { 
  8.     b(); 
  9.     c(); 

如果調(diào)試器停在 //stopped here' 這行,那么有兩種方法可以達(dá)到:main->b->a或main->c->a`。如果我們用 LLDB 設(shè)置一個斷點,繼續(xù)執(zhí)行并請求一個回溯,那么我們將得到以下內(nèi)容:

  1. * frame #0: 0x00000000004004da a.out`a() + 4 at bt.cpp:3 
  2.   frame #1: 0x00000000004004e6 a.out`b() + 9 at bt.cpp:6 
  3.   frame #2: 0x00000000004004fe a.out`main + 9 at bt.cpp:14 
  4.   frame #3: 0x00007ffff7a2e830 libc.so.6`__libc_start_main + 240 at libc-start.c:291 
  5.   frame #4: 0x0000000000400409 a.out`_start + 41 

這說明我們目前在函數(shù) a 中,a 從函數(shù) b 中跳轉(zhuǎn),b 從 main 中跳轉(zhuǎn)等等。***兩個幀是編譯器如何引導(dǎo) main 函數(shù)的。

現(xiàn)在的問題是我們?nèi)绾卧?x86_64 上實現(xiàn)。最穩(wěn)健的方法是解析 ELF 文件的 .eh_frame 部分,并解決如何從那里展開堆棧,但這會很痛苦。你可以使用 libunwind 或類似的來做,但這很無聊。相反,我們假設(shè)編譯器以某種方式設(shè)置了堆棧,我們將手動遍歷它。為了做到這一點,我們首先需要了解堆棧的布局。

  1.     High 
  2. |   ...   | 
  3. +---------+ 
  4. |  Arg 1  | 
  5. +---------+ 
  6. |  Arg 2  | 
  7. +---------+ 
  8. Return  | 
  9. +---------+ 
  10. |Saved EBP| 
  11. +---------+ 
  12. |  Var 1  | 
  13. +---------+ 
  14. |  Var 2  | 
  15. +---------+ 
  16. |   ...   | 
  17.     Low 

如你所見,***一個堆棧幀的幀指針存儲在當(dāng)前堆棧幀的開始處,創(chuàng)建一個鏈接的指針列表。堆棧依據(jù)這個鏈表解開。我們可以通過查找 DWARF 信息中的返回地址來找出列表中下一幀的函數(shù)。一些編譯器將忽略跟蹤 EBP 的幀基址,因為這可以表示為 ESP 的偏移量,并可以釋放一個額外的寄存器。即使啟用了優(yōu)化,傳遞 -fno-omit-frame-pointer 到 GCC 或 Clang 會強制它遵循我們依賴的約定。

我們將在 print_backtrace 函數(shù)中完成所有的工作:

  1. void debugger::print_backtrace() { 

首先要決定的是使用什么格式打印出幀信息。我用了一個 lambda 來推出這個方法:

  1. auto output_frame = [frame_number = 0] (auto&& func) mutable { 
  2.     std::cout << "frame #" << frame_number++ << ": 0x" << dwarf::at_low_pc(func) 
  3.               << ' ' << dwarf::at_name(func) << std::endl; 
  4. }; 

打印輸出的***幀是當(dāng)前正在執(zhí)行的幀。我們可以通過查找 DWARF 中的當(dāng)前程序計數(shù)器來獲取此幀的信息:

  1. auto current_func = get_function_from_pc(get_pc()); 
  2.     output_frame(current_func); 

接下來我們需要獲取當(dāng)前函數(shù)的幀指針和返回地址。幀指針存儲在 rbp 寄存器中,返回地址是從幀指針堆棧起的 8 字節(jié)。

  1. auto frame_pointer = get_register_value(m_pid, reg::rbp); 
  2. auto return_address = read_memory(frame_pointer+8); 

現(xiàn)在我們擁有了展開堆棧所需的所有信息。我只需要繼續(xù)展開,直到調(diào)試器*** main,但是當(dāng)幀指針為 0x0 時,你也可以選擇停止,這些是你在調(diào)用 main 函數(shù)之前調(diào)用的函數(shù)。我們將從每幀抓取幀指針和返回地址,并打印出信息。

  1. while (dwarf::at_name(current_func) != "main") { 
  2.         current_func = get_function_from_pc(return_address); 
  3.         output_frame(current_func); 
  4.         frame_pointer = read_memory(frame_pointer); 
  5.         return_address = read_memory(frame_pointer+8); 
  6.     } 

就是這樣!以下是整個函數(shù):

  1. void debugger::print_backtrace() { 
  2.     auto output_frame = [frame_number = 0] (auto&& func) mutable { 
  3.         std::cout << "frame #" << frame_number++ << ": 0x" << dwarf::at_low_pc(func) 
  4.                   << ' ' << dwarf::at_name(func) << std::endl; 
  5.     }; 
  6.     auto current_func = get_function_from_pc(get_pc()); 
  7.     output_frame(current_func); 
  8.     auto frame_pointer = get_register_value(m_pid, reg::rbp); 
  9.     auto return_address = read_memory(frame_pointer+8); 
  10.     while (dwarf::at_name(current_func) != "main") { 
  11.         current_func = get_function_from_pc(return_address); 
  12.         output_frame(current_func); 
  13.         frame_pointer = read_memory(frame_pointer); 
  14.         return_address = read_memory(frame_pointer+8); 
  15.     } 

添加命令

當(dāng)然,我們必須向用戶公開這個命令。

  1. else if(is_prefix(command, "backtrace")) { 
  2.     print_backtrace(); 

測試

測試此功能的一個方法是通過編寫一個測試程序與一堆互相調(diào)用的小函數(shù)。設(shè)置幾個斷點,跳到代碼附近,并確保你的回溯是準(zhǔn)確的。

我們已經(jīng)從一個只能產(chǎn)生并附加到其他程序的程序走了很長的路。本系列的倒數(shù)第二篇文章將通過支持讀寫變量來完成調(diào)試器的實現(xiàn)。在此之前,你可以在這里找到這個帖子的代碼。 

責(zé)任編輯:龐桂玉 來源: Linux中國
相關(guān)推薦

2017-06-28 14:21:22

Linux調(diào)試器斷點

2017-06-22 10:44:55

Linux調(diào)試器準(zhǔn)備環(huán)境

2017-10-09 10:56:49

Linux調(diào)試器處理變量

2017-10-12 18:20:44

Linux調(diào)試器高級主題

2017-09-25 08:04:31

Linux調(diào)試器源碼級斷點

2017-08-28 14:40:57

Linux調(diào)試器源碼和信號

2017-07-25 10:30:32

Linux調(diào)試器Elves和dwarv

2017-07-05 14:37:07

Linux調(diào)試器寄存器和內(nèi)存

2017-08-28 15:29:19

Linux調(diào)試器源碼級逐步執(zhí)行

2024-03-13 08:00:00

Linux調(diào)試器應(yīng)用程序

2017-04-19 21:35:38

Linux調(diào)試器工作原理

2011-08-25 16:34:27

Lua調(diào)試器

2020-03-16 10:05:13

EmacsGUDLinux

2010-03-01 11:06:52

Python 調(diào)試器

2009-12-14 10:57:34

Ruby調(diào)試器

2011-08-31 16:51:12

Lua調(diào)試器

2016-09-21 12:34:10

Chrome瀏覽器插件

2019-12-06 14:30:41

GNU調(diào)試器GDB修復(fù)代碼

2023-02-28 11:39:55

CMake腳本項目

2011-08-24 11:08:09

Lua
點贊
收藏

51CTO技術(shù)棧公眾號

91亚洲国产成人精品一区二区三| 亚洲丝袜美腿一区| 国产精品国产三级国产三级人妇| 国产精品99导航| 亚洲天堂网一区| h视频在线免费| 精品系列免费在线观看| 欧美成aaa人片在线观看蜜臀| 在线视频一二区| 97caopron在线视频| 成人av午夜影院| 欧美综合第一页| www成人啪啪18软件| 国产麻豆精品| 偷偷要91色婷婷| 97久久夜色精品国产九色| 日韩成人免费在线视频| 伊人成综合网yiren22| 日韩欧美在线国产| 亚洲欧美久久234| 午夜精品久久久久久久99| 国产视频一区欧美| 最近中文字幕mv在线一区二区三区四区| 99久久99精品| 涩涩视频在线| 亚洲色图制服丝袜| 久久av一区二区三区亚洲| 中国精品一区二区| 亚洲国产片色| 色哟哟网站入口亚洲精品| 精品无码av一区二区三区不卡| 在线天堂资源| 亚洲你懂的在线视频| 国产成人免费电影| 亚洲天堂网在线观看视频| 最新亚洲视频| 欧美成人合集magnet| 精品少妇人妻一区二区黑料社区 | 美日韩一级片在线观看| 欧美成人一区在线| 波多野结衣影院| 91麻豆精品| 色成年激情久久综合| 亚洲小视频在线播放| 国产青青草在线| 不卡的av在线播放| 成人激情黄色网| 中文字幕在线天堂| 99精品国产在热久久| 久久九九亚洲综合| 日本一区二区视频在线播放| 精品久久ai| 日韩视频一区二区三区| 另类小说色综合| 亚洲成人一区在线观看| 精品福利在线视频| 日韩精品一区二区三区四| 欧美边添边摸边做边爱免费| 国产欧美日韩在线看| 精品乱子伦一区二区三区| 国产精品久久影视| 美女久久久精品| 国产精品igao视频| 国产亚洲欧美在线精品| 国产日韩综合| 欧美日韩国产成人| 精品97人妻无码中文永久在线 | 色就是色欧美| 黄色av网站在线看| 久久精品亚洲国产奇米99| 含羞草久久爱69一区| 老司机午夜福利视频| 国产成人99久久亚洲综合精品| 国产精品一区二区三区久久| 国产乱码77777777| 热久久一区二区| 国产精品嫩草影院久久久| 欧美日韩a v| 青青草精品视频| 国产精品久久久久久久午夜| 在线观看xxxx| 国产真实乱对白精彩久久| 国产日产久久高清欧美一区| 波多野结衣家庭主妇| 日韩avvvv在线播放| 国产精品爽爽ⅴa在线观看| 国产免费www| 美女视频网站黄色亚洲| 成人性生交大片免费看视频直播| 91欧美日韩麻豆精品| 免费看黄裸体一级大秀欧美| 国产成+人+综合+亚洲欧洲| 中文字幕av第一页| 久久精品一本| 国产日韩中文字幕| 国产女人高潮的av毛片| 国产精品亚洲午夜一区二区三区| 成人在线免费网站| 欧美一级淫片aaaaaa| 26uuu久久天堂性欧美| 日本精品一区二区| 国产三区在线观看| 亚洲国产成人91porn| 中文字幕乱码人妻综合二区三区| 欧美日韩激情电影| 6080亚洲精品一区二区| wwwxxxx在线观看| 青草久久视频| 精品国产依人香蕉在线精品| 精品无码久久久久久久| 亚洲精品美女| 国产精品色悠悠| 99热这里只有精品66| av资源站一区| 欧美日韩在线精品一区二区三区| 日本亚洲精品| 午夜久久电影网| 黑森林精品导航| 亚洲一区二区三区四区电影| 亚洲精品小视频| 国产黄色的视频| 性欧美videos另类喷潮| 亚洲r级在线观看| 理论视频在线| 一区二区三区四区激情| 国产免费999| 粉嫩av一区二区| 亚洲欧美精品伊人久久| 波多野结衣亚洲色图| 久久裸体视频| 国产精品日韩欧美一区二区| 日韩美女网站| 欧美日韩亚洲精品一区二区三区| 天美一区二区三区| 国产永久精品大片wwwapp| 欧美激情亚洲激情| 国产精品玖玖玖| 日本一区二区视频在线观看| 亚洲色欲久久久综合网东京热| 国产91欧美| 亚洲精品福利免费在线观看| 色老板免费视频| 青青草原综合久久大伊人精品优势| 韩日午夜在线资源一区二区| 菠萝菠萝蜜在线视频免费观看| 欧美午夜在线一二页| 亚洲黄色免费在线观看| 黄色成人精品网站| 成人在线视频网| 欧美另类自拍| 五月婷婷欧美视频| www.美色吧.com| 欧美99在线视频观看| 国产精品专区一| 国产精品一区在线看| 性久久久久久久久久久久| 日韩欧美理论片| 99热精品久久| 国产精品一区二区三区免费视频 | 免费影视亚洲| 7777精品伊人久久久大香线蕉的 | 岛国一区二区三区高清视频| 精品国产99久久久久久| 欧美日韩亚洲综合一区二区三区| 超碰97在线资源站| 亚洲精华国产欧美| 精品亚洲欧美日韩| 国产伦子伦对白在线播放观看| 精品粉嫩aⅴ一区二区三区四区| 1024手机在线视频| 国产成人免费xxxxxxxx| 欧美激情亚洲天堂| 国产在线播放精品| 精品自拍视频在线观看| jizz国产视频| 亚洲国产成人高清精品| 国产午夜在线一区二区三区| 国产一区日韩欧美| 国产伦精品一区二区三区| 激情视频网站在线播放色| 亚洲国模精品私拍| 国产污片在线观看| 不卡影院免费观看| www黄色av| 日韩毛片视频| 亚洲综合在线做性| 国产丝袜视频在线播放| 精品一区二区三区三区| 久久夜色精品国产噜噜亚洲av| 久久免费偷拍视频| 手机在线成人免费视频| 7777久久香蕉成人影院| 亚洲综合中文字幕在线| 国产无遮挡裸体视频在线观看| 亚洲另类激情图| 97精品久久人人爽人人爽| 一区二区三区四区高清精品免费观看| youjizz.com日本| 久久天堂精品| 99re8这里只有精品| 成功精品影院| 国产精品极品尤物在线观看| 中文日本在线观看| 精品少妇一区二区三区在线视频| 青草视频在线观看免费| 亚洲国产精品精华液ab| 福利片一区二区三区| 在线成人av| 午夜精品一区二区在线观看| 欧美大片91| 午夜精品久久久久久久久久久久久| 三级在线视频| 欧美精品123区| 日本在线视频中文字幕| 国产欧美一区二区三区在线看蜜臀| 99国产精品久久久久久| 在线视频亚洲| 国产日本欧美在线| 1204国产成人精品视频| 国产福利成人在线| 好久没做在线观看| 中文字幕免费精品一区高清| 国产99久一区二区三区a片| 欧美日韩综合视频网址| 四虎精品免费视频| 国产成人综合在线| 国产wwwxx| 日韩午夜一区| 热这里只有精品| 嫩草影视亚洲| 国产精品免费一区二区三区| 欧美美女福利视频| 日本成人免费在线| 丁香花在线观看完整版电影| 色综合伊人色综合网| 天天射天天色天天干| 欧美视频在线一区二区三区 | 日韩**中文字幕毛片| 日韩av毛片| 最好看的2019年中文视频| 五月婷婷深深爱| 欧美草草影院在线视频| 久久久黄色大片| 亚洲国产乱码最新视频| 日韩成人短视频| 国产精品国产自产拍高清av| 久久成人激情视频| 久久久久久久综合色一本| 国产情侣久久久久aⅴ免费| 麻豆精品一二三| 国产97色在线 | 日韩| 99成人在线| 免费一级特黄毛片| 国产精品豆花视频| www.69av| 午夜激情一区| 91社在线播放| 91精品久久久久久久久久不卡| 亚洲免费视频一区| 日韩国产综合| 亚洲精品在线免费| 日韩中文首页| 亚洲午夜精品一区二区三区| 欧美午夜精品一区二区三区电影| 日本精品国语自产拍在线观看| 伊人春色之综合网| 日本午夜精品电影| 久久99免费视频| 明星裸体视频一区二区| 国产成人3p视频免费观看| 亚洲成人蜜桃| 欧美成熟视频| 亚洲 自拍 另类小说综合图区| 亚洲综合日本| 亚洲欧美国产中文| 高清视频一区二区| 狠狠人妻久久久久久综合蜜桃| 国产欧美日韩另类一区| 欧美大片xxxx| 日韩欧美在线观看视频| 国产精品国产一区二区三区四区| 欧美电影免费提供在线观看| 亚洲色图狠狠干| www.色综合| 欧美aaaaa性bbbbb小妇| 国产精品久久久久国产a级| 日韩成人视屏| 欧美日韩在线精品| 欧美日韩91| 久久婷婷国产91天堂综合精品| 国模娜娜一区二区三区| 亚洲久久久久久| 中文字幕在线观看一区| 国内免费精品视频| 777亚洲妇女| 精品无人乱码| 欧美另类高清videos| 免费观看亚洲| 产国精品偷在线| 日韩激情免费| 国产乱子夫妻xx黑人xyx真爽| 另类中文字幕网| 色天使在线视频| 一区二区三区视频在线观看| 精品在线播放视频| 91麻豆精品91久久久久同性| 嫩草在线播放| 久久久综合av| 粉嫩av国产一区二区三区| 欧美另类网站| 亚洲看片一区| 手机看片国产精品| 国产精品人妖ts系列视频| 91九色丨porny丨肉丝| 91精品国产综合久久精品麻豆 | 久久影视电视剧免费网站清宫辞电视 | 久久久91精品| 色综合天天色| 欧美成人免费在线| 亚洲激情午夜| 日批免费观看视频| 亚洲免费高清视频在线| 亚洲第一区av| 亚洲欧美日韩图片| 三级在线看中文字幕完整版| av一区二区三区在线观看| 97精品在线| 91极品视频在线观看| 久久久久国产免费免费 | 在线亚洲人成电影网站色www| 天堂网2014av| 国内成人精品视频| 亚洲高清999| 五月天综合婷婷| 精品一区二区三区久久| 青青操在线播放| 欧美日韩一区二区三区在线 | 久久久亚洲欧洲日产| 日本aa在线观看| 国产.欧美.日韩| 国产无码精品视频| 精品国产91洋老外米糕| а_天堂中文在线| 国产伦精品一区二区三区免费视频| 黄色成人91| 中文字幕影片免费在线观看| 亚洲成人你懂的| 天天躁日日躁狠狠躁伊人| 97国产真实伦对白精彩视频8| jizzjizzjizz欧美| 久久久亚洲国产精品| 99国产精品一区| 中文字幕第四页| 亚洲午夜av电影| 日韩av黄色| 国产av不卡一区二区| 国产精品一区二区男女羞羞无遮挡| avove在线播放| 亚洲精品电影网| 成人日韩在线| 一区二区三区四区在线视频| 国产一区视频网站| 激情五月婷婷小说| 日韩精品免费在线观看| 成人免费直播| 亚洲欧美成人一区| 国产高清成人在线| 亚洲精品1区2区3区| 亚洲天堂网在线观看| 四虎视频在线精品免费网址| 亚洲区成人777777精品| 99免费精品在线观看| 丰满熟女人妻一区二区三| 久热精品视频在线观看| 成人精品毛片| 少妇高清精品毛片在线视频| 久久九九影视网| 国产精品乱码久久久| 高清一区二区三区日本久| 怕怕欧美视频免费大全| 网站在线你懂的| 亚洲福利国产精品| 精品欧美不卡一区二区在线观看| 成人动漫网站在线观看| 最新国产拍偷乱拍精品| 91无套直看片红桃在线观看| 欧美α欧美αv大片| 久久天堂av| 免费特级黄色片| 国产女人18毛片水真多成人如厕| aaa级黄色片| 欧美在线观看视频| 亚洲影视一区| 精品无人区无码乱码毛片国产| 欧美高清一级片在线| 涩涩涩视频在线观看| 国产精品久久成人免费观看| 26uuu国产一区二区三区| 国产伦精品一区二区三区视频痴汉 | 麻豆changesxxx国产|