2006年五月月 发布的文章

小心库函数调用的'陷阱'

下午一同事发现代码中的一处问题,问题的现象是这样的:这位同事调用了一部门基础库函数,当使用32位编译后,程序正常运行;而当使用64位编译后,系统运行dump core。让这位同事奇怪的是他所修改的程序中还有其他模块也使用了同样的基础库函数,为什么偏偏他这块儿出错呢?恰恰该程序的其他模块是我写的。

该程序调用的基础库函数大致是这样的:
typedef unsigned long my_size_t;
int my_socket_recv(my_socket_t socket, char *buf, my_size_t *len, int timeout);

而这个库函数的实现主要就是调用了系统的库函数:recv,通过man命令查到recv函数原型为:ssize_t recv(int s, void *buf, size_t len, int flags);

而my_socket_recv的实现如下:
int my_socket_recv (my_socket_t socket, char *buf, my_size_t *len, int timeout)
{
     int rv;
     … …
 
     rv = recv(socket, buf, (*len), 0);
     … …
}

使用gdb察看core文件,通过栈上信息看出(*len)值有问题,有经验的人可能基本就可以断定问题所在了,对了,应该类型长度不匹配的问题,导致内存访问越界。同事的代码也证实了这一点。原来我的这位同事在调用my_socket_recv时第三个参数传入一个unsigned int型的地址,而不是unsigned long型的地址,我们知道在64位编译下,long型已经升级到8个字节,而int型依旧是4个字节,而size_t也是unsigned long的typedef,所以当调用recv时,通过len指针,recv系统调用毫无顾忌的去取8个字节,而实际上在栈上只有前四个字节是合法的数据,从第5个字节开始已经是非法的了,出core也就在情理之中了。我们可以简单的模拟出这种情况,如下面的例子:

/* test.c */
#include

void print_long_int(unsigned long *i) {
        printf("i is %ld\n", *i);
}

int main() {
        unsigned int n = 1024;
        print_long_int(&n);

        return 0;
}

64位编译:
gcc -m64 -g test.c

执行a.out出core.

问题虽然解决了,但是思前想后,发现一个问题:即库函数调用暗藏的’陷阱’问题,像这样的问题实际上是基础库函数的接口设计的不够好,实际上它的正常运行依赖某些条件,而不是’无偿’的,但是这些条件又很难识别出来,特别是对于新手而言更是难上难。

想出两种办法解决:
1、不要设计像上面my_socket_recv这样的带有’隐含’条件的接口(recv系统调用接口就没有隐含条件);
2、调用接口的人不要想当然的随便传入不同类型的数据,应尽量保持实参数据类型与形参数据类型完全匹配(这块儿编译器可以帮你做检查),如果不这样,很有可能像我的这位同事一样,掉入了库函数调用的陷阱中。^_^

世界园艺博览会游记

沈阳世界园艺博览会开幕已经快一个月了,自从到沈城工作之后,沈城的景点可以说一个都没去过,也许这会被很多人说成'不懂得生活',也许就是这样吧。沈城进入夏天的速度那真叫一个快',上个周末已经让我们感受到了'盛夏'的威力了。也就是在上周末,我和GF去游了一次世博会。

听说五一黄金周世博会开幕期间接待了近200万游客,真是挺吓人,多亏五一加班,要不还不得不被'挤成饼'^_^。不过说实话,世博会的交通还是很方便的,铁路、公交专线、旅游专线、出租车任你挑选。我是在北站坐单程5元的公交线路去的世博园,赶上周末人还是很多,我们是一直站到世博园的。由于是周末,世博园加强了交通管制,不过恰恰是由于这些管制导致很宽阔的马路上居然堵车了,一些长得胖乎乎的交警趾高气扬的在那瞎指挥,车上是一片骂声,看来这些人在普通老百姓的心中名声并不太好呀。堵了近30多分钟,大巴终于驶入世博园。

世博园正门是一个很大的广场,一下车就看到一场集体婚礼正在那举行中,由于时间有限,不能驻足,所以在心里默默祝福这些新人百年好合吧。世博园正门的标志性建筑之一的'凤之翼'格外耀眼,经了解得知:凤之翼长210米,中间贯穿10根斜拉钢索,建筑整体造型如凤凰展翅,象征着沈阳振兴腾飞之势,主塔下方是1000平方米的大型音乐喷泉。这么棒的主景观怎能放过,不过由于'凤之翼'太过庞大,在其下范围内很难拍到全景,我尽力将塔身上部全部收入照片中。

欣赏到'风之翼'的壮观后,我们真正进入世博园,尽管已经过了高峰期,但是园中依然是人头攒动,密密麻麻,很多景点已经受到了人为破坏,环境卫生也并不理想。按照事先计划好的路线,我们开始了世博园之旅。从字面'世界园艺博览会'上我们也知道,园内多花草树木和一些有着地方特色的人造景观,如果按我的意图,我更想多看一些奇花异草,而不是那些人造景观。不过GF对花花草草毫无兴致,她专找人造景观合影,相机电力有限,只能顺着她来。

我们沿着西南方向路线行走,首先参观的是西北、西南园区,这个园区包括西安园、西宁园、兰州园、银川园、乌鲁木齐园、拉萨园等八个主题园区,每个园区都不大,但是特色都很鲜明。由于刚开始逛,体力充沛,对每个主题园游览的都很细致,照片拍得也是最多的,由于园区较多,以致回去后整理照片时居然记不清哪些照片是属于哪个园的了^_^。我把一些照片放在我的相册中了,其中我自己比较喜欢的有'卧瓶出水'、'威武秦俑'和'挺立的胡杨木'。

在西北、西南主题园区之后是另一个标志性景观'百花馆',这个馆号称建筑面积12000平方米,是国内最大的花卉室内展馆。不过我自己觉得这个馆比起'凤之翼'要相形见绌不少,起码我没有看出什么亮点,除了馆内的那幅国内最大的马赛克镶嵌壁画'和平鸽'。不过这里却是个休息的好场所,背着那么多零食和水,不早点消灭光可是累赘亚。

'水足食饱'之后,我们继续沿西南方向走,通过一道拉锁桥后,来到意大利园,这里的典型的哥特式建筑风格还是给我留下一些好感的,这里人不多,宁静淡雅,是青年人'发展感情'的好场所^_^。之后我们陆续路过牡丹园、美国园、俄罗斯园、英国园、韩国园、加拿大园,没有太多值得称道的地方,这里一笔带过。

转过来,向世博园中央走,那里聚集着一些表演类项目,诸如俄罗斯大马戏、东北二人转、马战表演、水上表演等,我和GF都对水上表演情有独钟,遂来到人工湖前看表演,看表演的人很多,毕竟很多人和我们一样都是第一次看到这样的现场表演。表演的节目包括'水上特技滑板'、'特技摩托艇表演'和最惊险刺激的'摩托车飞越23米宽的湖心岛'。首先出演的是一对金发澳洲女郎的特技水上滑板,两个人的特技表演均有瑕疵,一些动作都是以失败告终的,不过现场观众还是给予了热烈的掌声的;接下来的特技摩托艇波澜不惊;而压轴戏摩托车飞越则是十分的好看,由于没有什么安全措施,所以大家还都挺替表演者担心的,结果是有惊无险,两个澳洲小伙子让我们饱了眼福。

借着水上表演的余味未决,我和GF又继续参观国际园区,这里主要是东南亚和东亚国家的主题园区,和国内园区不同之处是这里好似杂货店,到处兜售所谓的'国外特色'产品,根据我的经验,好像除了尼泊尔园中的东西好像是真的,其余园里卖的感觉均是'赝品',特别是在泰国园和马来西亚园中居然卖一模一样的东西让我更加肯定了我的想法。这点不能不说让人有些扫兴。不过我还是买了几串'土耳其烤肉'吃了起来,味道还不错,只是价钱太贵,10元一串。

国内园区还没有走全呢,我们的相机的电池就已经坚持不住了,所以在国内园区少有留影,只一张'湖中小荷'还让我满意。国内园区是我们的最后一站。带着些许的遗憾,我们结束了这次世博园之旅。

最后用一组还算顺口的话来总结一下这次世园会之旅吧:
交管不利,车堵人怨,
凤之翼景,的确壮观,
百合塔身,未近谋面,
人造景观,略显粗糙,
游客如织,人多为患,
公德意浅,环境受难,
水上表演,有惊无险,
国际园区,赝品泛滥,
电池耗尽,难尽心愿,
世园会游,疲惫不堪。

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