一次程序崩溃问题排查的反思

版权声明:本文为博主原创文章,不需博主允许即可随意转载。 https://blog.csdn.net/a_dev/article/details/89325866

事由

接手一个兄弟部门快要收尾的软件开发项目,已经集成了功能,运行的时候,在某一台机器上频繁崩溃,且是在系统登录后过那么一两秒便会出现。由于是单机版软件,用户信息使用Microsoft Access数据库MDB文件保存。系统也支持其他类型的数据库连接,切换到Oracle数据库登录后,正常启动,无崩溃情况。在我的电脑上,不管使用何种类型的数据库,均无崩溃情况。两台电脑都安装了Access数据库驱动程序。

分析

一开始就想,代码哪里出错了。于是使用会出现崩溃的机器打断点调试。发现有几次是崩溃在获取时间写日志的方法上,怀疑是多处同时调用一个方法导致的崩溃。但这个不是必然的。继续调试,发现在其他地方也会崩溃。崩溃时抛出的异常,类型均为“AccessViolationException:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”

这个系统在开发的时候,采用的是Windows操作系统,Visual Studio 2017作为IDE,语言为C#,依赖最新版本的.Net Framework(版本号4.7.2),更引入了第三方皮肤库组件DevExporess(版本号18.2.6,和谐版)。这更令我想到,可能是环境的差异导致的崩溃。跟进代码,未能找到原因。

解决

老将出马,了解问题情况之后,看到是访问冲突异常,一言断定是Access数据库连接的问题(虽然AccessViolationException中的Access,与Access数据库中的Access,意义不同)。调试代码发现,在登录时创建了一个数据库连接,用于验证登录信息,登录成功后未释放掉。由于软件设计的问题,后续的一些系统表、数据表也都存储在这个MDB文件中,再次建立数据库连接参数时,会导致崩溃。添加关闭方法后,问题解决。但凡使用了类似OpenConnection方法的地方,必然要对应一个CloseConnection操作。

思考

姜还是老的辣。“老姜”说,以前他做开发的时候,遇到过类似的莫名其妙的崩溃问题,也是针对MDB的读取操作,未进行关闭连接的原因。大家都知道,Oracle数据库本来就支持并发多个连接的,所以不会有此问题。我一想,是啊,这是常识!

那么,在解决这个崩溃问题的过程中,我又有哪些思考和收获呢?我想,最重要的当属以下两点:

一是要一针见血地直面问题的关键,找出问题最根本的原因所在。比如这一案例中,环境的差异、对第三方组件的依赖、代码体量和质量,都可能造成对分析问题的干扰,但我不应该忽略最重要的一点,即使用Oracle数据库是可以登录的,就Access不行。所以,这才是问题的关键所在,是最应当关注的点,其他都是干扰项。

二是要学会冷静和客观地分析问题,利用已有的经验,不慌不忙,不偏不倚。我想,分析问题的思路与态度,加之常识与经验,可能比解决问题的能力更重要。

猜你喜欢

转载自blog.csdn.net/a_dev/article/details/89325866