C++异常分析使用Process Explorer和Dependency Walker定位dll库动态启动失败的问题
Posted dvlinker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++异常分析使用Process Explorer和Dependency Walker定位dll库动态启动失败的问题相关的知识,希望对你有一定的参考价值。
近日测试同事反馈,我们的C++客户端软件登录后显示一直连不上会议服务器,于是使用一些软件工具详细地分析了一下,最终发现是底层dll库版本不一致导致的。今天就分享一下这个问题的详细排查过程。
1、初步分析
软件登录后显示一直连不上会议服务器,如下所示:
查看了底层的打印日志,软件一直没有调用注册服务器的接口,所以一直显示连不上服务器。
这个有点奇怪,查看上层的打印,已经调用注册的接口了,为啥底层打印中没有调用最终的注册接口呢?软件从上到下有多个模块,有多个逻辑分层,应该是中间模块出问题了,没有将最终的注册请求投递下去。
初步怀疑是与注册相关的rtcservice.dll库在软件启动时没有加载起来导致的,注册服务器的消息要经过这个库投递到底层去的,如果这个库没启动起来,注册服务器流程就会中断的。
2、使用Process Explorer查看到rtcservice.dll没有启动起来
于是使用Process Explorer工具查看了一下我们软件进程加载的dll库列表,看看rtcservice.dll库到底有没有加载起来。
将Process Explorer启动起来后,点击工具栏中的View Dlls/View Handles按钮,切换到查看dll的模式,查看程序加载的dll列表中有没有rtcservice.dll库,如下:
确实列表中没有找到rtcservice.dll库,所以这个库确实没有启动起来。
3、使用Dependency Walker查看rtcservice.dll库的依赖情况
估计是rtcservice.dll依赖的底层库有问题,可能是rtcservice.dll调用的接口在底层库中找不到。一般对于静态链接的库(非LoadLibrary动态加载),exe主程序加载到进程空间之前会将依赖的库先加载到进程空间中,如果要加载的库依赖的底层库有问题,会弹出报错提示框,提示在某库中找不到某个接口,如下所示:
但动态加载的库,在加载失败时不会弹出这样的提示框,具有较强的掩蔽性。之所以将不同的主业务模块做成动态加载,是为了按需要去加载自己需要的模块,不去加载自己不需要的业务模块,这样能节约进程对系统资源的占用。
于是使用Dependency Walker工具查看rtcservice.dll库的依赖情况,看看到底有哪些问题。
Dependency Walker工具主要有三个用处:
1)查看目标库到底依赖了哪些库;
2)查看依赖的库是否存在,如果不存在会显示黄色的问号;
3)调用依赖的库中的接口是否存在,如果不存在,则会显示红色标记。
如下图所示:
rtcservice.dll库依赖的rtcadapter.dll和pfc.dll库前面的图标颜色有异常。然后再看右边,看到一个红色图标标记,含义是mtrtcservice.dll中调用了rtcadapter.dll库中的RtcRegStart接口,但rtcadapter.dll库中并没有RtcRegStart接口。
4、查看svn上的库发布记录,找到了问题所在
软件前两天编译的版本,运行还是正常的,这两天就出问题了,估计是底层模块最近发布库过来了,导致rtcadapter.dll、pfc.dll和rtcservice.dll不匹配了。
于是到源代码目录中查看SVN上的记录,查看rtcadapter.dll和pfc.dll库的发布记录:
果然查出了问题,我们当前版本是封闭流(稳定版本)的,结果协议组最近一次发布的库是每日流(开发版本)上的,应该是从他们的封闭流发布过来的,即rtcadapter.dll、pfc.dll与rtcservice.dll
库的版本不一致导致了本问题。
解决办法是,让协议组发布封闭流对应的库过来就可以了。
以上是关于C++异常分析使用Process Explorer和Dependency Walker定位dll库动态启动失败的问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 Process.Start 打开资源管理器窗口会创建过多的 explorer.exe 进程
使用Process Explorer和Clumsy定位软件高CPU占用问题
process explorer和process monitor有啥不同