同一程序交替运行输出不同的技术问题求助
排查C程序偶发的输出异常问题
这是我编写的一个用于统计计算的quick&dirty程序的一部分。有时程序会输出预期结果:
42 1 1 48 13 14 54 12 26 60 11 37 66 6 43 72 13 56 78 23 79 84 14 93 90 6 99 96 0 99 102 0 99 108 1 100
但约50%的运行次数中,输出的最后一行会变为:108 2 101。我使用gcc 7.3.0在Debian 64位系统编译,仅添加-o编译选项。我知道程序可以写得更优雅,但……
这种偶发的输出异常基本跑不开内存操作不当或者未定义行为——毕竟是快速写的代码,很容易忽略这类细节。给你几个实用的排查方向:
- 数组越界访问:如果最后一行输出的数据来自某个数组,大概率是其他地方的代码越界写入,覆盖了数组末尾的元素。比如循环条件写错(把
<写成<=),导致往数组外的内存区域写数据,而这块内存刚好存着最后一行要输出的内容,运气好没被覆盖就正常,运气差就出问题。 - 未初始化变量:看异常输出里的
2(预期是1),很可能是某个变量没初始化就被拿来用了。未初始化变量的值是随机的,所以有时候碰巧符合预期,有时候就乱掉。 - 缓冲区溢出:如果用了
strcpy这类不安全的字符串操作函数,或者输出缓冲区处理不当,也可能导致内存被意外覆盖。不过这种情况导致50%概率异常的可能性稍低,但也可以排查下。 - 用编译工具辅助排查:你现在只加了
-o,试试加上-Wall -Wextra编译,gcc会帮你揪出很多潜在问题,比如未初始化变量、疑似越界的提示。更狠一点的话,用-fsanitize=address编译运行,这个工具能直接检测内存越界、使用已释放内存等问题,对付这种偶发内存bug特别好用。
另外,50%的概率说明问题可能和某个随机分支有关?比如有没有用到随机数,或者用未初始化变量当判断条件,导致程序有时候走正确路径,有时候走到有bug的路径。
如果能把涉及最后一行输出的核心代码片段贴出来,定位问题会更精准。
内容的提问来源于stack exchange,提问作者EXIT_FAILURE
相关产品推荐
相关产品推荐

