關於MSVCR100.dll、MSVCR100d.dll、Msvcp100.dll、abort()R6010等故障模塊排查及解決方法


一、常見故障介紹  

  最近在開發相機項目(項目細節由於公司保密就不介紹了),程序運行5個來月以來首次出現msvcr100.dll故障等問題,於是乎開始了分析之路,按照度娘上的一頓操作,期間也是出現了各種不一樣的問題,現總結了遇到的問題如:

1、MSVCR100.dll/MSVCR100D.dll/MSVCP100.dll/MSVCP100D.dll問題

  問題事件名稱:        APPCRASH

  故障模塊名稱:        MSVCR100.dll

2、R6010錯誤

  現場遇到的情況基本都是這兩類

二、故障排查

1、靜心思考

  主要說一下我走過的歷程,心酸只有自己知道,排查問題難免浮躁,但一定要沉得住,浮躁主要有以下幾點:

  • 程序明明在自己機器上運行的好好的在客戶機器上就會出問題;
  • 程序明明試着好好的,可你一離開就出現問題;
  • 程序連續運行好幾個月版本都穩定了,可突然出問題,換電腦又復現不出來;
  • 連續處理一段時間后仍然沒有結果,客戶領導天天催。

2、檢查庫

  • 1、如果新打包的程序提示缺少MSVCR100.dll、MSVCP100.dll”或者“MSVCR100d.dll\MSVCP100d.dll”等類似錯誤信息,請從源機器或者網上下載該庫拷貝到目標機器,庫分32位和64位(跟自己操作系統有關),32拷貝到C:\Windows\System32,64位拷貝到C:\Windows\SysWOW64,記住庫一定要統一版本,不要從別的機器東拼西湊,以一個機器為准;
  • 2、程序發布時最好將所需要的庫也一並打包,在這我以vs編譯器為例,可以從vs安裝目錄里拷貝MSVCR100.dll等相關運行庫,記得區分32或者64位版本,目錄如下:

  • 3.如果以上兩步完成,程序重啟后,還會出現類似問題,則繼續往下排查,我給現場換完所有庫之后,出現了R6010問題引起程序宕機

         

3、排查代碼

1)、代碼層面檢查

  以上若還沒解決問題,此時一定不要再糾結庫(不要以為庫版本不對),一定是你代碼的問題,檢查代碼着重檢查

  • 1.非法指針訪問和內存泄漏
  • 2.設置的指針范圍跟你運行的不對
  • 3.指針訪問內存越界出現問題。
  • 4.因為不支持中文。
  • 5.內存不夠分配
  • 6.多線程訪問資源出的問題。
  • 7.檢查exe和dll是否混用的不同版本的crt

代碼檢查出異常更新版本后若問題解決皆大歡喜,若還沒有解決,請接着往下走(本人就屬於后者)。

2)、生成dump文件

  一定要正視你的代碼,C++系統崩潰無非就是內存訪問無效、無效對象、堆棧溢出、空指針調用等常見的問題,當然有些問題不是立馬能復現,它需要一定的條件,而這個條件它很復雜又由許多因素所制約;

  Dump文件是進程的內存鏡像。可以把程序的執行狀態通過調試器保存到dump文件中,Dump文件是用來給驅動程序編寫人員調試驅動程序用的,這種文件必須用專用工具軟件打開,比如使用WinDbg、VS打開,當程序崩潰時會生成dump文件,通過生成dump文件使用調試工具進行調試,還原程序崩潰時的狀態,能夠起到快速定位排查問題的作用,dump文件生成的方式如下:

(a)通過任務管理器生成

打開任務管理器,找到對應的進程,右擊,選擇創建轉儲文件

 

生成的文件路徑如下:

 

 

 

 

生成的轉儲文件可以通過VS打開,但是正常運行的程序生成.DMP文件並沒有什么大的作用,上述的方法要求在程序崩潰時並不直接退出時才可以使用,但是一般程序都是粗魯的退出,所以這種方法適用於特定場合。

  (b)編寫代碼生成

  一定要生成debug版本程序

  Windows提供了SetUnhandledExceptionFilter函數,MSDN中描述為:

Issuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process.

用於當程序遇到未經處理的異常(主要指非指針造成)導致程序崩潰宕機時的異常接受處理,該函數必須在異常可能發生之前調用才有效,我們可以在該函數中生成dump文件,以方便我們調試,代碼網上很多,我貼出一部分(大佬不嫌棄請留言),在程序崩潰后會生成dump文件

 1 int GenerateMiniDump(HANDLE hFile, PEXCEPTION_POINTERS pExceptionPointers, PWCHAR pwAppName)
 2 {
 3     BOOL bOwnDumpFile = FALSE;
 4     HANDLE hDumpFile = hFile;
 5     MINIDUMP_EXCEPTION_INFORMATION ExpParam;
 6 
 7     typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
 8         HANDLE,
 9         DWORD,
10         HANDLE,
11         MINIDUMP_TYPE,
12         PMINIDUMP_EXCEPTION_INFORMATION,
13         PMINIDUMP_USER_STREAM_INFORMATION,
14         PMINIDUMP_CALLBACK_INFORMATION
15         );
16 
17     MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
18     HMODULE hDbgHelp = LoadLibrary(L"DbgHelp.dll");
19     if (hDbgHelp)
20         pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
21 
22     if (pfnMiniDumpWriteDump)
23     {
24         if (hDumpFile == NULL || hDumpFile == INVALID_HANDLE_VALUE)
25         {
26             //TCHAR szPath[MAX_PATH] = { 0 };
27             TCHAR szFileName[MAX_PATH] = { 0 };
28             //TCHAR* szAppName = pwAppName;
29             TCHAR* szVersion = L"v1.0";
30             TCHAR dwBufferSize = MAX_PATH;
31             SYSTEMTIME stLocalTime;
32 
33             GetLocalTime(&stLocalTime);
34             //GetTempPath(dwBufferSize, szPath);
35 
36             //wsprintf(szFileName, L"%s%s", szPath, szAppName);
37             CreateDirectory(szFileName, NULL);
38 
39             wsprintf(szFileName, L"%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
40                 //szPath, szAppName, szVersion,
41                 szVersion,
42                 stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
43                 stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
44                 GetCurrentProcessId(), GetCurrentThreadId());
45             hDumpFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
46                 FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
47 
48             bOwnDumpFile = TRUE;
49             OutputDebugString(szFileName);
50         }
51 
52         if (hDumpFile != INVALID_HANDLE_VALUE)
53         {
54             ExpParam.ThreadId = GetCurrentThreadId();
55             ExpParam.ExceptionPointers = pExceptionPointers;
56             ExpParam.ClientPointers = FALSE;
57 
58             pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
59                 hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &ExpParam : NULL), NULL, NULL);
60 
61             if (bOwnDumpFile)
62                 CloseHandle(hDumpFile);
63         }
64     }
65 
66     if (hDbgHelp != NULL)
67         FreeLibrary(hDbgHelp);
68 
69     return EXCEPTION_EXECUTE_HANDLER;
70 }
71 
72 
73 LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
74 {
75     if (IsDebuggerPresent())
76     {
77         return EXCEPTION_CONTINUE_SEARCH;
78     }
79 
80     return GenerateMiniDump(NULL, lpExceptionInfo, L"test");
81 }

(c)調試dump文件

  終於在慢慢的等待中,現場程序崩潰,預期生成了dump文件,此時我們將dump文件拷貝到我們當時編譯的debug版本可執行程序的同級目錄下,注意pdb文件必須也在此目錄

 

 

 

 用vs打開dmp文件並點擊使用僅限本機進行調試

 

出現異常時的彈窗即UnhandledExceptionFilter為默認的異常處理器工作產生的會出現中斷的提示框,此時點擊中斷

 

 

右下角會彈出堆棧信息

 

 雙擊有問題的一行,會出現彈窗,再選擇代碼工程所在目錄(sln的目錄),即可定位到有問題的那一行

 

分析錯誤,加上異常保護,重新生成版本,問題解決,收工!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM