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 |