人生数字

这是一篇从班级校友录上摘录下来的文章,删节一部分,我擅自加了个题目“人生数字”,也不知恰当与否。

23岁的时候,你毕业了,你第一份工作的薪水是1500块,转正以后变成2000块。工资总花得一分钱不剩,盼着发薪的日子。过了一年你跳槽了,工资变成3000块,你穿的衣服开始变贵了,吃的东西开始变好了,不过有一样没有变,工资还是花得一分钱不剩。这时候你谈恋爱了,你为了交女朋友,一个月要向朋友借1000块,她还是嫌你钱少,把你揣了。好不容易找个邻家女孩,感情甚好,学会了生活,一个月居然能存1000块,没想到在你憧憬未来的时候,她家里人不同意,把你们拆了。于是你发奋图强,终于工资涨到了6000块,变成白领,开始泡酒吧,追美女,给人家100块的小费。某一天,在街上碰见甩你的前女友,很奇怪自己当初怎么会看上她,她是那么的没品味。30岁的时候,你有了10万块存款,不过你觉得很疲惫,想找个地方,可以踏实地睡。于是你结婚了,存款变成了贷款,每月还要还上4000块,不过你和妻子的工资加起来有1万块,你一点都不觉得累。一晃几年过去,你还清了贷款还存了5万块,你的孩子也长到六岁,你不希望他重复你的生活,于是想送他到外国,可是人家一张嘴就是20万,你心里暗骂“这帮黑心的老外“。愿望虽好,没钱也是白费,你的孩子还是在国内,一直长到22岁。60岁的时候,你退休了,儿子要结婚,向你要了40万块,你没嫌多,反到觉得花在自己儿子身上,比送给老外实在。过了一年又一年,你对数字不再敏感除了自己的年龄。有时候你躺在床上还在想,我怎么还这么结实,是因为我补了钙还是上帝希望我健在。 终于你安息了,墓碑上刻着你生活的年代“198x--2046”,这也是你最后的一串人生数字。

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

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! 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