[软件资料]

(分享)Linux上的C开发调试经验

[复制链接]
1882|25
手机看帖
扫描二维码
随时随地手机跟帖
七毛钱|  楼主 | 2023-5-10 14:42 | 显示全部楼层 |阅读模式
毕业超过十年了,感慨岁月无情。做了若干年后台开发(之前做电信领域),大致说一下常见的开发心得和调试手段。使用互联网这么多年,收获的很多,总结的很少。本着互联网的精神,希望可以帮到互联网另一端的你。由于本人是做 C 语言的开发,陈述的经验也是 C 常用的调试手段。

    调试这个蛋疼的事情,困扰着无数程序猿。很难有人保证自己写的代码一行错误都没有,有问题你就要查。怎么查?高手者,反汇编,看二进制;low 一点的就 gdb、看统计;再low就加打印。还可以再low 吗?可以,自己写bug,别人查。方法林林总总,长期掌握总可以找到适合自己的。

    而调试的目的是什么?找到 BUG。想当年一个高手比喻的好:你找 BUG 其实你就是福尔摩斯,那为啥是福尔莫斯呢?想想你看到 BUG 案发现场,合格的程序都有日志、dump 内存、计数等基本案发现场吧。嗯,什么都没有,找写代码的人自己查。找问题就是在众多信息中,抽丝剥茧,找到疑点、反复推演程序运行的代码,最终找到作案的那一行或者几行代码。

    这个过程是折磨人的地方,没有任何眉目时,令人茶不思饭不想。找到问题问题后,如打鸡血般兴奋,自己也会陶醉般飘飘然。真正受过折磨的人,才能体会到修改问题的滋味。

    开发的程序大致要经过两个阶段,最终才可以上线发布。

功能开发阶段               

    本阶段的主要目标是根据业务要求,开发程序。仅仅是 coder,仅仅是写 if else 吗?写程序真的是这样吗?如果是这样,那么 coder 会更加工厂化、枯燥化。

    做事情要未雨绸缪,做程序更应该这样。大学 C 语言经典教材中定义程序为:程序 = 数据结构 + 算法。而实际生产的过程中,将商业程序做如下的补充定义,我觉得更合适:程序 = 数据结构 + 算法 + 业务逻辑(计算逻辑)+ 框架;

    先说说为什么补充业务逻辑,有意义的程序本身就是某种业务逻辑(计算逻辑)的抽象。完成这个业务逻辑才是最终的目的,请不要拿一些算法研究的 code 和我抬杠。

    其实作为开发人员,测试驱动开发(TDD)很好思考问题的思路。也许有人听过,也许有同学用过,如果感觉使用不好的兄弟,我可以告诉大家:应该是测试场景 + 场景驱动开发。对,仅仅是里面融入“场景”这个宾语,大家在做开发的时候,就有目的性和针对性。

    任何一个业务逻辑,都可以拆分为多个业务场景。场景逐一解决,场景逐一测试,我们开发其实很简单。说的很简单,但是整个过程,需要 50%的时间思考解决问题场景, 20%的编码,30%的测试。其实思考问题的 50%的时间,可以放在任何时间去做(休息时,地铁上,班车上...),只要让自己足够的静,你就会将整个业务逻辑思考的很清楚,分解为多少个业务场景也很明确。对于复杂的业务场景,建议适当的做笔记,多从全局的业务逻辑考虑:自己细化的得到结论是否符合所有的业务场景。反复地修正,直到正确。

使用特权

评论回复
七毛钱|  楼主 | 2023-5-10 14:42 | 显示全部楼层
完成一个较大项目的若干需求,你可以一个需求一个需求的 code,也可以思考整个问题后再 code,往往后一种方式更容易得高分。

    具体的编码时候,经过我们前面的深思熟虑,每个细节都已经很清楚了,采用迭代的方式,批量的交付小的功能点就可以了哈。

    开发阶段的总结两个关键字:TDD + 迭代。需要详情的同学自行 baidu,google。

功能调试阶段               

    调试的手段很多,读代码、打日志、gdb、统计、coredump 等,如果有精力也可以搞搞白盒测试什么的。测试的意图也很明显,确认代码是否按照正确的编码意图在运行!其实自己写的代码,自己还是可以轻松驾驭调试的,原因就是自己清楚代码的本意该如何运行,现在出现了什么问题。

    程序猿的三大悲剧之一,就是不知道什么时候需要定位一个其他猿写的 bug。定位前也需要必须要理解另外一位程序猿写这段代码的意图是什么,否则没有办法定位。理解其他人写的代码的途径也就是通过阅读代码了解大致思路,通过日志、gdb、或者统计信息补充代码意图的更多细节,或者修正理解不对的思路。

    这个过程可能很枯燥,也可能很有挑战,试图通过种种迹象去了解另外一个猿写代码的初衷和意图,会不会有窥探人家隐私的赶脚!

    其实,上面说了这么多只是告诉大家调试好的前提,和调试的初衷。

    一个优秀的猿,你会发现他有很多调试技巧,也就是很多调试手段获取自己想得到的信息。信息获取的多,自然就很容易清楚程序本身的意图。

    调试工具的使用细节和说明,同学们可以自行baidu,google。

    我在这里简单的阐述一下自己是怎么调试程序的,怎么理解各种工具的,欢迎大虾们指点交流。

关于日志
    如何打好日志绝对是门学问。日志打印多了,自然会影响后台程序的性能;同样打印的少了,没有办法定位问题;更苦逼的是打印到空指针,更有可能 coredump 掉自己的程序;

    所以日志的技巧就是:少,却内容丰富。

    如何少,其实就是汇聚。

    能不能将表达同一个意思的打印减少?

    能不能在关键异常的地方加上统计(输出统计)?

    能不能不打?

    能不能内存中记录关键信息,在想要的时候,控制其打印时机?

    如何丰富,其实就是少打描述性词汇,多打有用的程序运行信息。

    方法很多,大家多多思考。并且打印的优化,是反复优化的过程,不是一蹴而就的。曾经遇见一个大牛,测试部提问题了,这哥们从来不去定位。直接告诉测试的兄弟,帮忙执行以下软调,将收集的日志给他分析一下就可以解决问题。

关于gdb
    还有大牛说过:“我就是程序,程序就是我”。我常用 gdb 来检验自己对程序的理解。常用的 gdb 功能就是打印一些程序的运行信息,修改一些内部运行信息,构造复杂场景。

    其实很简单,程序在什么场景下应该有什么样的行为,我自己的必须清楚。必须知道关键变量的信息是否正确,周期 gdb 出来,确认变量的信息是否正确,然后决定程序是否符合预期在执行。

    可靠性的程序都有类似的保护机制,但是通常需要繁琐的构造测试条件,触发保护机制(如检测到丢包率很高,要告警等)。其实大多数的保护机制都是通过记录一些状态后,程序然后触发的保护机制。

    其实,可以 gdb 构造出异常状态,确认告警机制是否生效。gdb 很好的补充这方面的测试和验证工作。

关于统计
    统计信息,是关键信息汇集的最好的例子。数据少,且信息明了。

    电信软件中,很多模块都通过这样的信息:自证清白。也很容易发现问题出现哪里。

    统计的实质,就是通过全局变量,记录一些程序正常,异常点的统计信息。然后通过某种手段输出出来。

使用特权

评论回复
七毛钱|  楼主 | 2023-5-10 14:43 | 显示全部楼层
关于 coredump
    大家看到 coredump 都会头痛,其实 coredump 也是很好的定位手段。

    首先程序 coredump 后,会有详细的 coredump 文件,该文件详细地记录了程序在 core 之前的运行信息。gdb 这个 coredump 文件,你想看什么都可以。这只是简单的使用 coredump。

    如果碰到复杂的问题,难搞的问题,其实也可以使用 coredump 来定位。

    比如程序执行到一个十分不常见的代码分支,然后程序就 core 掉了,但是目前输出信息(日志等),根本没有办法进一步定位问题。

    怎么办?有没有想过在复现问题的环节,出个调试版本的程序,在异常分支上主动触发内存异常,产生 coredump,利用 coredump 信息,来确定程序是如何异常的呢 ?

关于代码修改
    这个也是我常用的手段之一,反复地对比修改前后的代码,确认修改代码的准确性,全面性,反思自己代码修改是否全面?其实这里面工具就是 beyondcompare。

使用特权

评论回复
AloneKaven| | 2023-5-10 22:27 | 显示全部楼层
哈哈哈,自己写bug让别人来查

使用特权

评论回复
guijial511| | 2023-5-13 23:09 | 显示全部楼层
MCU无法玩Linux

使用特权

评论回复
yangxiaor520| | 2023-5-14 09:23 | 显示全部楼层
喜欢玩嵌入式的现在都是用Linux环境开发了

使用特权

评论回复
tpgf| | 2023-6-7 13:10 | 显示全部楼层
Linux操作系统是基于UNIX操作系统发展而来的一种克隆系统

使用特权

评论回复
qcliu| | 2023-6-7 13:34 | 显示全部楼层
Linux是一款免费的操作系统,用户可以通过网络或其他途径免费获得,并可以任意修改其源代码

使用特权

评论回复
drer| | 2023-6-7 13:58 | 显示全部楼层
Linux同时具有字符界面和图形界面。在字符界面用户可以通过键盘输入相应的指令来进行操作。

使用特权

评论回复
coshi| | 2023-6-7 14:19 | 显示全部楼层
在Linux中,用户可以轻松实现网页浏览、文件传输、远程登陆等网络工作。并且可以作为服务器提供WWW、FTP、E-Mail等服务。

使用特权

评论回复
kxsi| | 2023-6-7 14:42 | 显示全部楼层
Linux采取了许多安全技术措施,其中有对读、写进行权限控制、审计跟踪、核心授权等技术,这些都为安全提供了保障。

使用特权

评论回复
wiba| | 2023-6-7 14:58 | 显示全部楼层
Linux的工作方式分为字符工作方式和图形工作方式。

使用特权

评论回复
szt1993| | 2023-12-22 14:43 | 显示全部楼层
测试驱动开发(TDD)很好思考问题的思路

使用特权

评论回复
中国龙芯CDX| | 2024-1-9 15:32 | 显示全部楼层
yangxiaor520 发表于 2023-5-14 09:23
喜欢玩嵌入式的现在都是用Linux环境开发了

这个确实是

使用特权

评论回复
自己写bug让别人来查

使用特权

评论回复
jf101| | 2024-1-27 14:30 | 显示全部楼层
C语言还是比较侧重实践的

使用特权

评论回复
AdaMaYun| | 2024-1-27 14:39 | 显示全部楼层
要常用 gdb 来检验程序的

使用特权

评论回复
AdaMaYun| | 2024-1-27 16:04 | 显示全部楼层
统计的实质,就是通过全局变量,记录一些程序正常,异常点的统计信息

使用特权

评论回复
OKAKAKO| | 2024-1-27 16:32 | 显示全部楼层
可以,自己写bug,别人查,这也可以?

使用特权

评论回复
LOVEEVER| | 2024-1-27 17:57 | 显示全部楼层
如何打好日志绝对是门学问

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

318

主题

2176

帖子

4

粉丝