关于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的目录),即可定位到有问题的那一行
分析错误,加上异常保护,重新生成版本,问题解决,收工!
上一篇: 序列类型可用的内置函数
下一篇: Python基础---控制执行流程