标签 博客 下的文章

C程序员之“痛”

内存问题是C程序员永久的话题,也是最能让C程序员心痛的话题。内存bug即隐秘,危害又大,而且往往当你解决了它之后,你会发现你的错误是多么的低级。以我为例,看下面的两个case:

CASE1

背景: 配置信息读取
Bug现象: 通过打印语句观察到,在配置读取中间时刻,某一指针突然被置为NULL,出core。
耗时: 6小时
问题所在及分析: 经过6小时的不懈努力,终于发现了这一让我哭笑不得的低级错误。问题原因大致是这样的:
我定义了一个存储配置信息的结构体变量指针,并在初始化的时候给该指针在共享内存中分配空间,下面的代码就是我分配空间时的代码
xx_t *p;
…//

p = xx_malloc((void**)&p, sizeof(p));

正确的代码
p = xx_malloc((void**)&p, sizeof(xx_t));
我想我之所以花了那么长时间才找到这个问题,是被一些奇怪的现象所蒙蔽了,也是查找内存误操作问题经验不足所致。

CASE2

背景: Ftp客户端获取文件列表
Bug现象: 当Server端目录下文件个数很多时(如>=1000),以后的ftp操作全部失效,出现errno = 95、134等。
耗时: 7小时
问题所在及分析: 由于在文件少的时候,我们的ftp client工作一切正常,所以我们最开始怀疑的是接收数据缓冲区开得不够大。但是在加大缓冲区之后,问题依然存在。由于对FTP协议并不是很熟悉,导致在一些细节上又耽误了很多时间。之后我们看到一个奇怪的现象就是errno 95的出现,说明我们的ctrl channel socket已无效。我们使用最传统的调试方法使用打印语句,从创建Ctrl Socket开始,一直追踪到问题发生区域,并锁定一块区域的代码,在该代码之前ctrl socket为31, 之后ctrl socket居然变为1, 而且这段代码中并没有操作socket的语句。我们分析有两个可能:
1)这段代码运行时间过长,导致Ftp server关闭link;
2)该段代码有内存误操作,导致内存被污染;

我们使用排除法,首先注掉那段代码,取而待之的是sleep(30),我们想如果sleep 30秒,Ftp server不关闭link的话,那么就是第2种可能了,结果是的确有“内存误操作”,静态检查代码后,锁定在一个给指针数组赋值的语句上,察看上层代码后,发现这就是问题所在。用代码说明问题大致是这样的:
char *flist[200];

…//

int cnt = 0;
while (读取数据不为空) {
 p = malloc(…);
 …//
 flist[cnt] = p;
 cnt++; 
}

显然如果数据超过200条,数组必然越界。

总结:经过两个Case中,发现自己在找“内存误操作”问题上的经验不足,但同时经过这两个case,我总结一下几条,可能对以后的bug查找有所帮助。
a) 虽然“内存bug”不易查找和修改,但是一定要摆正心态,首先确定是“内存误操作”带来的bug;
b) “内存bug”绝大多数是极其低级的错误,所以首先要仔仔细细静态检查代码,可以按下面的顺序检查
 .搜索所有的malloc, memset, memcpy一类的内存操作函数,察看是否有“马虎”错误;
 .察看所有的数组变量,看是否有越界嫌疑
c) 打印语句是最简单,但是却是最有效的debug方法(我是这么认为的^_^),要利用好哟。

[注]:errno 95 — Socket operation on non-socket

重操旧业

2005年7月8日是我入司一周年纪念日,本想写篇Blog纪念一下,可是思维的小溪总是难以汇聚成大江大河,始终觉得无话可说,再加之最近的项目十分紧迫,So我放弃了。这周末公司去海边旅游放松,带着一身的疲惫回来后,坐在电脑前,突然觉得该写些东西了

纵然C语言是我通往软件开发世界的领路人,但曾经(大二)一度认为C已经是明日黄花,之后便不再认真钻研之。入司被分到C组,平时开发的方式和大部分刚入司的新员工一样"照猫画虎",事实证明这是最快捷的上手途径,这也并没有错。错就错在我对C的消极态度。代码写完了就写完了,几乎从来不去重构、优化,现在看来那些代码真是有些“不堪入目”,也许这个词包含些夸张成分^_^。由于长时间缺乏对C的钻研,我有时居然犯一些及其低级的错误。直到最近的这个项目我逐渐清醒了一些,在和leader的平时交流中他也一针见血的指出我的不足之处之一就是“杂而不专”,虽说一定的知识面是很重要的,但是作为作技术的,不能在一个方向上“露头”,又怎能让领导重视你呢,你的价值又体现在哪呢?“大家不可能因为某个人能学,就认可他”这是另一句触动我很深的话。曾经有段时间想过转移到Java方向,自己也在Java上面投入了大量的时间,阅读了大量的材料和书籍(我的时间没有浪费,只是没放在行上,就暂且将C定位本行吧^_^)。但由于多种原因没能走向Java,这个结果对于我来说意味着什么呢,我不能不承认我学到了很多东西,但失去的也同样很多,比如在本行“露头”的机会。最近的项目让我感到自己在C上的欠缺,不得不加班加点恶补。

相信很多公司的员工手册或文化手册中都有这么一点:“追求个人与公司的共同发展”,那么“重操旧业”就算是我“响应号召”的一个起点吧!

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats