程序初始化失败解决方法 应用程序初始化失败怎么办

最近连续遇到两个由于变量未初始化引起的软件异常问题,本文详细讲述一下这两个问题的详细排查过程,通过这两个案例来说明变量初始化的重要性,希望大家能引起足够的重视 。

程序初始化失败解决方法 应用程序初始化失败怎么办


1、BOOL 型变量未初始化导致的软件运行行为不一致的问题
最近在按照新需求开发新功能,在调试某个功能时,出现一个诡异的现象:在运行通过 release 安装包安装的 exe程序时,某功能始终是有问题的,但是直接在 VS2017 中调试运行 release 程序,发现该功能居然是正常的!
两种场景下,exe 程序都是 release 版本,并且底层 dll 库都是一样的,两个版本表现居然截然不同,这太奇怪了!
软件代码中肯定是有 bug 的,于是继续进行排查 。想到这个问题在之前稳定版本是没有的,应该是最近开发新功能添加的代码引起的,于是用 svn 查看了最近的代码提交记录,找到相关代码模块仔细进行排查 。
结果发现是一个 BOOL 变量影响了代码的控制执行逻辑:

程序初始化失败解决方法 应用程序初始化失败怎么办


在程序运行的开始阶段,该变量应该是 FALSE 的,出问题的版本居然走到该控制变量为 TRUE 的分支中,导致代码的控制逻辑出了问题!继续看,该 BOOL 型控制变量竟然没有初始化,这就是问题所在了!
在变量没有初始化时,我们用的微软 Visual Studio 编译器在 debug 下为了方便调试,会对堆内存和栈内存自动进行初始化,比如 debug 下的栈内存会初始化为 0xCCCCCCCC,debug 下的堆内存会被初始化为 0xCDCDCDCD,如下图所示:

程序初始化失败解决方法 应用程序初始化失败怎么办


但编译器在 release 下是不会自动进行初始化 。release 下变量如果没有初始化,变量的值将会是一个随机值,那这个随机值和什么有关呢?是给该变量分配内存时内存中残存的值,所以是随机值,一旦出现了随机值,程序运行时会出现不可预知的结果 。
本例中,直接运行安装包安装的 exe 版本与 release 调试运行,因为未初始化的控制变量会得到随机值,所以导致两种情况下的不同表现!
另外,有点迷惑人的地方是,几乎每次直接运行安装包安装的 exe 版本时,该 BOOL 变量的随机值都是 TRUE,但在 release 下调试运行时该变量的值一直是 FALSE,这也许和两种情况的启动运行机制差异有关系吧!反正是变量没有初始化引起的!
2、回调函数指针变量未初始化导致程序“跑飞”,胡乱崩溃的问题
主程序在调用一个 dll 库时,会调用 dll 接口 SetConfigCallBackFunc 给 dll 设置了一个回调函数(地址),dll 内部会将该回调函数的地址保存到一个成员变量(保存回调函数地址的指针变量)m_CallBackFunc 中 。
在当前主程序的代码中,在调用 SetConfigCallBackFunc 接口之前,调用了该 dll 的另一个接口(在该接口调用之后,再去调用 SetConfigCallBackFunc 接口给 dll 设置回调函数地址):

程序初始化失败解决方法 应用程序初始化失败怎么办


触发了 dll 代码运行到执行回调函数的地方:
【程序初始化失败解决方法 应用程序初始化失败怎么办】 而此时还没调用 SetConfigCallBackFunc 给该 dll 设置回调函数,导致 dll 中的存放回调函数地址的 m_CallBackFunc 指针中的值还不是一个有效值,虽然做了指针是否为 NULL 的判断,但是因为 m_CallBackFunc 中是个随机值!

程序初始化失败解决方法 应用程序初始化失败怎么办

推荐阅读