visual studio和gdb的調試機制到底是怎麼樣的?
其實問題有點多,最近剛剛升級visual studio community2017,微軟爸爸大好人啊(好像跑題了),vs老是會報一些lib文件缺失,比如前幾天kernel32.lib,找了很久,不知道為什麼,迫不得已再裝sdk,後來又報了很多pdb缺失,但是可以debug(以前都把符號伺服器那個選項關了,因為太慢了_(:з」∠)_),問題總能找到簡單粗暴的解決辦法,但是究竟為什麼不知道,我很好奇,kernel32.lib或者其他lib還有.dll(我只知道它們類似於.a文件,我也會寫dll,但是我看不見啊,我怎麼知道它裡面寫了些啥?和我程序有什麼關係)裡面究竟有什麼?(為什麼經常缺失?(′⌒`?)我有沒有必要都知道他們有什麼用),還有為什麼同時要有dll和lib,動態庫文件和靜態庫文件,只有一個不好嗎?(ー_ー)!!,我可以通過看什麼書來學習這些東西呢?關於c++只看了c++ primer(還沒看完_(′□`」 ∠)_),用來寫演算法,pdb文件到底有什麼不為人知的真相(不太明白為什麼調試要這個東西),為什麼我用clion+MinGW(windows)寫cmake用gdb調試就沒有這麼多奇怪的調試問題?有時候看不懂為什麼程序終止了會跳轉到一個很陌生的庫文件,裡面有一些奇怪的函數停止了,每次都是靠斷點慢慢找,clion也是這樣,我是否需要學習彙編去看懂vs的彙編界面?vs和gdb到底在調試的時候都做了什麼?
dll是真正的代碼,lib是描述編譯器如何找到具體的每一個函數的,所以編譯的時候當然需要lib,運行時就不用了。pdb你當然要從Microsoft Symbol Server那裡下載,kernel32.dll又不是你編譯的。
pdb文件含有debug調試信息,你可以用16進位編輯器或dumpbin打開一個exe,往往能看見一個鏈接相應pdb的地址(X:/xxx這樣的)
lib是靜態庫,當鏈接的時候會把內容都拷貝到exe里。而之所以鏈接dll還需要lib,是因為這個dll導出了函數或變數一類的符號,而lib里有對應的符號表,指出具體的調用地址(dll和調用它的進程在一個地址空間)。但這個lib不是必須的,你可以使用loadlibraryex 和getprocaddress來使用dll中導出的符號,此時不需要鏈接lib。推薦看windows 核心編程關於dll的那幾章。以及Peering Inside the PE: A Tour of the Win32 Portable Executable File Format。
純憑記憶手機打字,若有錯誤,還望指出。推薦張銀奎的《軟體調試》,下圖是前言。
題主需要學習一下編譯原理,建議先看看《程序員的自我修養》。
ps. 看這本書需要一定的彙編基礎ps2.
這是我的個人博客:http://blog.csdn.net/chen892704067不定期更新一點自己的心得,希望能一起進步你缺少的是對於ELF或者PE/COFF的了解,編譯,鏈接,裝載知識的了解,總的來說就是編譯原理和操作系統的知識。
推薦書籍&<&<程序員的自我修養&>&>,不過這本書講的太淺顯了,看&<&<深入理解計算機系統&>&>比較好,是CMU的教材和大一基礎教程。在深入一些就是操作系統和編譯原理兩本書了。
目標文件裡面有什麼可以在unix上用objdump或者在Windows 上用dumpbin查看。
了解debug的話,請看dwarf格式。pdb裡面存儲了符號信息.就是你的函數名,函數在exe.dll中對應的地址.對應源代碼的文件名和行號.通過這些.調試器就可以把彙編和源碼關聯起來.從而實現源碼調試.gdb也是類似.只是gcc把這些符號信息直接放在exe.dll內部.
至於調試器本身如何運作.參考[原創]簡易調試器的原理_15PB-『軟體逆向』-看雪安全論壇,講的比較清楚了.
閱讀《程序員的自我修養—鏈接、裝載與庫》會有幫助。
推薦閱讀:
※C++不用工具,如何檢測內存泄漏?
※生物信息學需要掌握C++嗎?
※如何實現一個C++反射庫?
※如何勸說上級更新 GCC 和 VS 的版本,並把項目遷移至 C++11?
TAG:C | MicrosoftVisualStudio | 編譯原理 | CC | GDB |