昨天碰到一个棘手的问题,项目生成Release版本,本地运行Release都没有问题,到了用户那边提示dll文件加载不成功,初步判断dll文件导入失败。于是换了几台电脑测试,结果都可以运行。考虑到用户那边没有开发环境,在服务器上新建了一个新账户,没有任何开发环境,Release版本出现dll加载不成功。

初步判断是由于电脑却少某些开发组件导致程序运行异常,但通常碰到dll文件加载不成功的情况大多是文件路径错误。尝试了三种路径格式:
(1)Qt资源文件(.qrc)存储dll文件,开发环境下失败,貌似QLibrary不支持.qrc文件存储的dll文件;
(2)反斜杠方式(\),转义字符双斜杠,开发环境成功,普通PC失败;
(3)斜杠路径(/),开发环境成功,普通PC失败;推荐使用这种路径格式,不需要考虑转义!

尽管尝试失败,基本可以忽略路径这个不存在的bug,接下来我又考虑了相对路径,相对路径是相对工作目录而言,结果也没问题。

dll文件的bug确实没什么调试途径(过去认为),你不知道QLibrary导入的具体细节,无法知道这个过程到底发生了什么。忽然过去数据库编程时,QDatabase类含有LastError()方法,可以输出连接错误,发现QLibrary类有类似的方法——errorString(),程序运行异常提示如下:
QQ截图20141117163218.jpg

虽然问题还没解决,看到异常内容至少知道fix bug的方向了!Google “can't load library 程序的并行配置不正确...”,很容易找到解决方法——安装vcredist_x86.exe/vcredist_x64.exe(Microsoft Visual C++ 2010 Redistributable Package),现在开发环境是基于VS2010的Qt(qt5.1.1 for vs2010),安装时系统提示已安装vcredist。

Bug还存在,根据上图提示查阅应用程序事件日志或者使用sxstrace.exe命令,这两个工具非常有效,下面一一讲解:

1、应用程序事件日志

Notification Services 会将事件(包括错误、警告和信息性消息)写入可通过 Microsoft Windows事件查看器访问的应用程序日志中。下列过程说明如何在应用程序日志中查找 Notification Services 事件。

具体步骤:控制面板-管理工具-事件查看器,左侧Windows日志-应用程序,右边会列出详细事件。
QQ截图20141117185658.jpg

从错误的事件可以看出三点异常:
(1)VC90是VS2008,而不是VS2010(VC100),vcredist_x86对应VS2008版本;
(2)VS2010开发的程序为什么调用VS2008所属程序集?
(3)Release版本为什么涉及到DebugCRT?

第一个问题,安装08版本即可;
第二个问题,dll使用VS2008生成;
第三个问题,dll是Debug版本;

解决方案(VS2008):
(1)Debug dll
可以在目录C:Program FilesMicrosoft SDKsWindowsv6.0ABootstrapperPackagesvcredist_x86
下找到vcredist_x86.exe,拷贝到目标机器上安装即可,也可以从微软官网下载
http://www.microsoft.com/en-us/download/search.aspx?q=redistributable%20package%202008
(2)Release dll
C:Program FilesMicrosoft Visual Studio 9.0VCredistDebug_NonRedistx86Microsoft.VC90.DebugCRT
下拷贝四个文件到目标机器,与程序放在同一目录,并打开Microsoft.VC90.DebugCRT.manifest文件
找到version="" 改为错误日志中提示的版本号 version="9.0.21022.8"
以上路径根据VS版本自行,需要注意的是,Microsoft.VC90.DebugCRT目录内的四个文件必须和dll文件放在同一目录!

2、sxstrace.exe命令
Windows7平台上有一个强大的SxsTrace工具,可以跟踪调试应用程序运行时需要的动态库的版本和路径。

SxsTrace使用的方法:
(1)首先必须以Administrator用户身份登录,打开cmd命令行;也可以以其它用户登录,然后打开cmd命令行,执行:runas /user:administrator cmd,输入Administrator用户密码后,系统打开一个以Administrator用户登录的cmd命令行;
(2)继续执行命令:SxsTrace Trace -logfile:SxsTrace.etl,启动跟踪;
(3)执行目标程序,在弹出错误对话框后,对话框显示的是:
应用程序无法启动,因为应用程序的并行配置不正确,有关详细信息,请参阅应用程序事件日志,或使用命令行SxsTrace.exe工具
(4)关闭对话框后,回到命令行,点击回车;
(5)继续执行命令:SxsTrace Parse -logfile:SxsTrace.etl -outfile:SxsTrace.txt,解析跟踪信息为文本;
(6)打开SxsTrace.txt(Administrator目录下)就可以看到相关跟踪信息。
QQ截图20141117192058.jpg

3、拓展:Depends
查看dll导出函数及关联dll(黄色问号:却少的dll)
QQ截图20141117193250.jpg

4、总结
(1)高级调试工具:事件查看器、SxsTrace.exe;
(2)dll开发程序与主程序开发工具尽量一致;
(3)dll分Debug/Release两版本生成,类似OpenCV;

标签: 调试, dll, SxsTrace, 事件日志

评论已关闭