天天看點

[轉] 靜态庫的PDB相關知識

本文轉自:http://blog.sina.com.cn/s/blog_41299a9701018bs8.html

今天遇到一個Crash,Crash在第三方庫中,由于好奇,就看了一下。發現代碼沒有,我們隻能看到頭檔案,隻有别人的Crash Call Stack,連Dump檔案也沒有,是以隻能手動模拟重制。

  發現Crash的目标子產品是A.dll它是我們自己的代碼,但是Crash的第三方庫是通過靜态連結到它裡面的。也就是說Crash的實際代碼是第三方庫寫的,沒有源碼,但是VS竟然能顯示出行号!反彙編竟然能顯示出檔案名,這就奇怪了,它的資訊哪裡來的?VS不可能自己産生,是以研究了一下。

  這裡有兩種可能

  1. 它用第三方提供的庫檔案的PDB,找了一下,還真有。但VS調試時,能删除這個檔案,說明沒有在被用。

  2. 它把這個PDB的内容拷貝到A.pdb裡了。實際也是這樣,找了一下A.pdb果然如此。問題又來了,那它拷貝的東西的來源是誰呢?我們知道lib包括代碼,那它裡面也包括PDB的資訊嗎?是不是PDB資訊也是Link的時候通過從Lib裡拷貝出來的嗎?查了一下Lib,裡面果然有源檔案資訊和PDB資訊,但還是不能肯定。

  準備做如下實驗證明PDB資訊到底在Lib自已,還是通過它找到庫的PDB,再從庫的PDB裡拷貝到A.pdb。把目标的PDB改名,重新編譯A工程,如果還帶第三方庫的PDB資訊,那就是在Lib裡。如果沒有,那就是在PDB裡。

  經過驗證,我想我已經找到答案了,通過lib找到PDB,再拷貝。

d.lib(1.obj) : warning LNK4099: PDB 'd.pdb' was not found with 'd.lib(1.obj)' or at 'C:\d.pdb'; linking object as if no debug info

  另外就是驗證了一下,如果在沒有源碼情況下,看出RCX代表哪個類,根據類型資訊,要加上子產品偏移量。然後根據虛表偏移,判斷出是幾第個虛函數,再配合頭檔案,找出函數名,或者直接F11,PDB資訊顯示的CALL Stack也會告訴我們這些,有些東西是互相印證的。