linux 下 C 编程和make的方法 (五:补充 怎么抓BUG)

抓BUG,几乎是程序员必须面对的事情。我没见过一次写通过,不需要改动的,这我承认,我野鬼见的人少,但我也必须说事实,就我本人还没有一次写就通过的 模块,且不说系统。已经有条件反射了,如果代码写写,没错,又写写,还是没错。立刻停下来,琢磨琢磨哪出问题了。有些人说“你已经变态到不是人的境界 了”。我只能说,每次停下来,发现,恩确实有问题。
    由此引发个支持IDE的理由。很多人说新手容易出BUG,DEBUG,IDE的工具很方便。难道你要教新手GDB吗?那不适合新手学。我只能说,GDB我也不会用啊。估计目前倒下、抽筋,呕吐的一片,还好我没收学费。
    很多年一直用VC,因为VC的debug我很熟练。后来发现不行了,怎么不行了,上板子就不行了。有人说,JTAG抓。抓回来看,这和VC也没关系啊。唯 一DEBUG看寄存器的是自己写汇编,那没办法。但这种情况,不在我讨论的范畴,我没说linux 下汇编的设计。这本身就是错误的命题,应该是什么硬件平台上汇编的设计。但即便是DEBUG汇编我也是在SIMU,模拟器上使用,上板子没办法玩。为什 么,不是JTAG坏了,而是大多数有如下两种情况:
    1、多进程或多核之间的连动工作。我设置端点,只要一停,这个核处于静态,那边过一秒没有底层响应就认为核死了,没办法动态跟踪。
    2、函数套函数,而且运行了不知道多少次以后才出现。运行个3分钟可能你还能忍受,如果一个系统运行1个小时,在足够多的任务下才存在,要么内存严重不足,要么指针跑飞,同志们倒是送我个合理化建议,如何通过设置断点,看寄存器来DEBUG。
    没办法,活还要干,如同饭还要吃一样,这样不行,只有换方法。什么方法?替换,检测,正向分析法。
    1、替换。模块的替换,替换模块一个好一个坏,那就是两个模块之间出现差异。这样缩小范围。
    2、LOG打印,检测不同情况下,存储单元的数值是否正常。怎么检测,批次输出,同时有正确版本也输出,对比找到出错位置。就可以知道那次输出的存储数据出错。
    3、错了就分析原因,谁引发的,然后锁定具体代码片,接着推倒重新设计。而不是反过来理解跟踪判断。
    哇塞,肯定有人说我第3条弱智。我要补充,既然是C代码,就要模块化,函数的目标要明确。如果你一个函数1000行,错了重新设计几乎还是错,那么就是你 组织代码,规划模块的问题了。如果一个函数调用,内部需要100个cycle,函数调用函数的费用平均10个cycle。就是使用子函数,还是有优势的。 即便这个函数占到整体计算量的20%(这已经很大了),多10%,也是整体计算量多2%。你有力气到处通过省去函数调用费用来提高速度,还不如重新规划下 系统结构,优化下CACHE的数据摆放和内容,看是否有改良的空间。
    上面的1,2,3还有个前提,就是原理性验证版本的正确性。这又回到了,怎么规划函数,的问题上了。因此,抓BUG,从你写代码的第一个单词开始,就已经 存在了。不要认为,等你所有代码都写完,再一一抓。程序设计,是迭代的 。模块与模块的迭代,原理与优化的迭代。不要希望自己的代码一次就达到高质量。什么是高质量,就是为你下一次迭代提供良好抓BUG的基础就叫高质量。一把 头设计写出来,就拿出用的,那是JAVA们干的应用软件的事情。和你做C没关系。你要做C就安心打铁把,你见过哪个铁匠就敲一下的?你如果说,“我要体面 的工作,体面的设计成果”。。。那我没话说,谁都想体面,就是因为谁都想体面,所以一群体面的人,都求着那几个不体面的底层师傅,你要看上去体面,还是实 际的体面呢?
    因此,新手不要认为盖高楼就没有脚手架你每天只要和楼板混凝土打交道,那是体面的人做内装潢时,交付给业主阶段才发生的。检测代码是一定要的。只不过是否 要在编译中存在,可以通过预编译处理掉。因此余下的C程序设计,我们把GDB丢弃掉。同时对新手说,IDE,你现在该没有任何利用使用它了。

你可能感兴趣的:(linux 下 C 编程和make的方法 (五:补充 怎么抓BUG))