程序崩溃的定位
1.程序要有PDB文件和MAP文件,兩者都是符號集,PDB是共調試用的,MAP文件是可讀信息符號集(記事本就可以打開)
2.程序崩潰時要及時產生相應的dump文件,這個是程序運行的信息,堆棧、寄存器、出錯代碼等信息
3.PDB文件、MAP文件、dump文件、exe文件最好在同目錄
4.調試dump文件可以用windbg或者VS。使用windbg時輸入命令!analyze -v 查看程序運行信息。使用VS直接點擊運行就可以看堆棧信息
5.windbg有時可以定位到源碼,有時不可以,這是因為:1.PDB文件、MAP文件、dump文件、exe文件可能不是一套(不統一)2.程序在哪一臺編譯的最好在那一臺電腦調試 3.編譯之后工程目錄不能改變(PDB里面有原文件的絕對路徑,調試時會去找源碼)4.符號信息不全(有很多頭文件庫文件需要從網上下載PDB文件)
6.windbg有時雖然不能定位到源文件到時能定位到程序崩潰的地址,這個時候MAP問價就派上用場了,有了地址map文件就能定位到源碼,先定位到是哪個函數,再定位到具體哪一行。比如崩潰地址是:ertg+113d2,就可以推算出崩潰絕對地址是0x004113d2,看下面的map,找不大于崩潰地址中的最大那個地址,可以推算出這個地址在crashtest函數里面,它相對于函數的偏移是0x004113d2-0x004113b0=0x22,接著定位具體行,有的MAP文件有行信息有的沒有。
?Address???????? Publics by Value????????????? Rva+Base?????? Lib:Object
?0000:00000000?????? ___safe_se_handler_table?? 00000000???? <absolute>
?0000:00000000?????? ___safe_se_handler_count?? 00000000???? <absolute>
?0000:00000000?????? ___ImageBase?????????????? 00400000???? <linker-defined>
?0001:00000000?????? __enc$textbss$begin??????? 00401000???? <linker-defined>
?0001:00010000?????? __enc$textbss$end????????? 00411000???? <linker-defined>
?0002:000003b0?????? ?crashtest@@YAHHH@Z???????? f?? ertg.obj
?0002:000003f0?????? _main????????????????????? 004113f0 f?? ertg.obj
7.MAP文件沒有行信息也是可以定位到源代碼的,方式是:VS有個查看反匯編的功能,查看方法是先進入調試模式,再右鍵查看反匯編,如果現在的原文件和當時發布的源文件差異不是很大(最少崩潰函數不是差異不是很大),這時就可以清晰的看到代碼相對于函數起始的偏移(如果整體源碼都沒有改變則可以跳過查看MAP文件的那一步,直接根據崩潰地址定位到源碼)
int crashtest(int a,int b)
{
00E613B0? push??????? ebp ?
00E613B1? mov???????? ebp,esp
00E613B3? sub???????? esp,0CCh
00E613B9? push??????? ebx ?
00E613BA? push??????? esi ?
00E613BB? push??????? edi ?
00E613BC? lea???????? edi,[ebp-0CCh]
00E613C2? mov???????? ecx,33h
00E613C7? mov???????? eax,0CCCCCCCCh
00E613CC? rep stos??? dword ptr es:[edi]
?? ?int c;
?? ?c = a/b;
00E613CE? mov???????? eax,dword ptr [a]
00E613D1? cdq???????????? ?
00E613D2? idiv??????? eax,dword ptr [b]
00E613D5? mov???????? dword ptr [c],eax
?? ?return c;
00E613D8? mov???????? eax,dword ptr [c]
}
程序崩潰查找注意點:
1.是否必現 必現的話極容易多了,調試運行程序,程序崩潰時源碼有提示,點擊中斷就可看到崩潰代碼行,或者使用后LOG文件
2.確定有PDB文件和dump文件
3.源碼能否回退到當時發布的源碼
4.若果源碼可以回退,其實PDB文件和MAP文件都是次要的,只要有dump文件和exe文件就可以定位到崩潰地址,有了地址通過反匯編就可以看到源碼位置
5.windbg分析dump文件不一定絕對準確,但是能分析到大概位置
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
2.程序崩潰時要及時產生相應的dump文件,這個是程序運行的信息,堆棧、寄存器、出錯代碼等信息
3.PDB文件、MAP文件、dump文件、exe文件最好在同目錄
4.調試dump文件可以用windbg或者VS。使用windbg時輸入命令!analyze -v 查看程序運行信息。使用VS直接點擊運行就可以看堆棧信息
5.windbg有時可以定位到源碼,有時不可以,這是因為:1.PDB文件、MAP文件、dump文件、exe文件可能不是一套(不統一)2.程序在哪一臺編譯的最好在那一臺電腦調試 3.編譯之后工程目錄不能改變(PDB里面有原文件的絕對路徑,調試時會去找源碼)4.符號信息不全(有很多頭文件庫文件需要從網上下載PDB文件)
6.windbg有時雖然不能定位到源文件到時能定位到程序崩潰的地址,這個時候MAP問價就派上用場了,有了地址map文件就能定位到源碼,先定位到是哪個函數,再定位到具體哪一行。比如崩潰地址是:ertg+113d2,就可以推算出崩潰絕對地址是0x004113d2,看下面的map,找不大于崩潰地址中的最大那個地址,可以推算出這個地址在crashtest函數里面,它相對于函數的偏移是0x004113d2-0x004113b0=0x22,接著定位具體行,有的MAP文件有行信息有的沒有。
?Address???????? Publics by Value????????????? Rva+Base?????? Lib:Object
?0000:00000000?????? ___safe_se_handler_table?? 00000000???? <absolute>
?0000:00000000?????? ___safe_se_handler_count?? 00000000???? <absolute>
?0000:00000000?????? ___ImageBase?????????????? 00400000???? <linker-defined>
?0001:00000000?????? __enc$textbss$begin??????? 00401000???? <linker-defined>
?0001:00010000?????? __enc$textbss$end????????? 00411000???? <linker-defined>
?0002:000003b0?????? ?crashtest@@YAHHH@Z???????? f?? ertg.obj
?0002:000003f0?????? _main????????????????????? 004113f0 f?? ertg.obj
7.MAP文件沒有行信息也是可以定位到源代碼的,方式是:VS有個查看反匯編的功能,查看方法是先進入調試模式,再右鍵查看反匯編,如果現在的原文件和當時發布的源文件差異不是很大(最少崩潰函數不是差異不是很大),這時就可以清晰的看到代碼相對于函數起始的偏移(如果整體源碼都沒有改變則可以跳過查看MAP文件的那一步,直接根據崩潰地址定位到源碼)
int crashtest(int a,int b)
{
00E613B0? push??????? ebp ?
00E613B1? mov???????? ebp,esp
00E613B3? sub???????? esp,0CCh
00E613B9? push??????? ebx ?
00E613BA? push??????? esi ?
00E613BB? push??????? edi ?
00E613BC? lea???????? edi,[ebp-0CCh]
00E613C2? mov???????? ecx,33h
00E613C7? mov???????? eax,0CCCCCCCCh
00E613CC? rep stos??? dword ptr es:[edi]
?? ?int c;
?? ?c = a/b;
00E613CE? mov???????? eax,dword ptr [a]
00E613D1? cdq???????????? ?
00E613D2? idiv??????? eax,dword ptr [b]
00E613D5? mov???????? dword ptr [c],eax
?? ?return c;
00E613D8? mov???????? eax,dword ptr [c]
}
程序崩潰查找注意點:
1.是否必現 必現的話極容易多了,調試運行程序,程序崩潰時源碼有提示,點擊中斷就可看到崩潰代碼行,或者使用后LOG文件
2.確定有PDB文件和dump文件
3.源碼能否回退到當時發布的源碼
4.若果源碼可以回退,其實PDB文件和MAP文件都是次要的,只要有dump文件和exe文件就可以定位到崩潰地址,有了地址通過反匯編就可以看到源碼位置
5.windbg分析dump文件不一定絕對準確,但是能分析到大概位置
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結