2009/11

一个典型的 off-by-one bug

今天美国人民过节,所以我今天上班基本上没啥事做。闲得发慌时无意中看到有人在邮件列表中报告 hexdump 有一个 bug,重现方法很简单,你只要通过 -s 把 skip 设置成该文件的大小就可以了,你可以用你手头上的 hexdump 试试,你会发现你可以看到全部文件的内容。这一下子激起了我的兴趣。

我一开始的想法是,hexdump 是个老命令了,虽然不能说像 ls 那些命令经过“千锤百炼”吧,但说“基本上不可能有bug”还是可以的。于是我抱着这个心态去翻源代码,虽然我在此之前从来没看过 hexdump 的源代码,但我还是信心满怀地找到了下面这么一句:skip -= sbuf.st_size; ,恩,看来是知道这种情况了,只是把它“折回”处理了,所以我回答说可能是一个 feature 而不是 bug。

但那个人后来的回复一下子惊醒了我,把 skip 再多加上一就是另一种结果了,什么都没有。所以这确实是一个 bug!当时我绕着源代码转了半天也没头绪,而且被里面那么多的全局变量和 static 变量给绕晕了,思考方向走错了。后来等我回到家做完晚饭一想,我靠,多一个或少一就没有 bug,这不就是 off-by-one 的症状嘛!肯定是哪里少算或者多算了一个临界值!抱着这个想法去找就简单了,很快就可以定位到问题所在,于是补丁自然而然地出来了

以前我们学C语言时不经常被提醒一定要注意 off-by-one 嘛,可能都没遇到过多么好的例子,现在这个就是现实中活生生的,非常典型的一个例子。作为反面教材放这里了。

现在再来回头看,问题其实很简单了,但当时分析这个 bug 时怎么就没想到这个原因值得深思:首先是心态不对,要面对现实,哪怕现实再残酷再不符合你的逻辑也要勇于否定自己,不要尝试找理由去否定现实,而是要接受现实去分析原因;其次,没有对“现象”进行深入思考,没有掌握到“现象”中表现出来的隐含规律,而这才是解决这个问题的关键!所以啊,不管在哪里多思考都是有好处的!

我很早以前就有这么个想法啊:作为程序员做 debug 工作,其实在很大程度上和侦探做破案工作是一样的。都要根据“凶案现场”(bug 症状)留下的蛛丝马迹顺藤摸瓜地去找“杀人凶手”(bug 所在);同样都是靠严密的逻辑去推理,唯一不同的是,侦探的逻辑和线索是事情发展的过程和顺序,而程序员的逻辑和线索是源代码;侦探在破案毫无头绪时会想更多的办法去搜集证据和证词等等,而程序员在毫无头绪时可以通过调试器等获取更多 debug 信息,总之都是获取更多的信息量,因为信息更多意味着分析出来的东西会更多。

这让我想起多年前上高中时上课都偷看的《福尔摩斯探案集》来了,里面福尔摩斯老师的那几句话真是饱含哲理,牛逼轰轰,金光闪闪啊:

当你把决不可能的因素排除后,不管剩下的是什么——-不管多么难以置信——那就是真相。

没有掌握全部证据以前,先作出假设,这是决大的错误,那样会使判断产生偏差。

猜想是很不好的习惯,它有害于作逻辑推理。

内牛满面地把这几句话收藏起来作为 debug 时的座右铭…… T_T

kbuild 更换维护者

Sam Ravnborg 作为 Linux 内核 kbuild 子系统的维护者已经很长时间。因为提交过相关补丁的原因,和他有过电子邮件来往。如果我没记错的话,他应该是意大利人,这位老大英语不是一般差,他的英语我每次读都比较费劲。无论如何,他对内核社区的贡献是有目共睹的,感谢多年来他的努力,现在 kbuild 系统已经很完善了。

昨天晚上的一封电子邮件中,Sam 突然宣布放弃继续维护 kbuild,因为家庭和工作的原因,时间不够用了。他维护 kbuild 也都是在业余时间来做,确实比较辛苦。 kbuild 作为内核中比较特殊的一部分,它几乎纯粹是用户层的东西,但和最后生成的内核二进制文件又息息相关,总体上感觉有点儿“鸡肋”,而且一般人是不会乱碰那些很多人看不懂的 Makefile 的。而且编译不光涉及简单的直接编译,还涉及到各个平台之间的交叉编译,涉及二进制文件格式等等,维护这些东西确实很麻烦。不管谁接手这个活儿都不容易。

目前谁将继续维护 kbuild 还未确定,主要还是要看 lkml 社区的认可程度,毕竟开源社区就是靠声望运作的。在私下的讨论中,Debian 开发者 Aníbal Monsalve Salazar 表示对此感兴趣,希望能接手,但不知为何并没有抄送到 lkml。最后如何我们只能拭目以待了。

BTW:正是靠这么多业余爱好者的努力,Linux 才成长如此迅速。感谢那些默默无闻,常年奋战在自由软件开发第一线的 geek 们!他们是互联网上最可爱的人!geek 万岁!8-) 姑娘们,给你们十个理由去嫁给 geek 男!恩哼~!

单身杯具

一年一度的传统节日又到了。。。(作者省略数千字感慨)

事实证明,搞Linux的geek注定是单身杯具。证据如下:

% whatis girl
girl: nothing appropriate.

% which girl
girl not found

% give me a girl
zsh: command not found: give

% find girls
find: `girls’: No such file or directory

% killall boring
boring: no process found

川滇之行游记(二)

丽江古城大体上分为两部分,一个是大研古城,一个束河古城。前者比后者大得多,所以前者热闹,后者安静。喜欢安静的可以考虑去束河住。我们住在大研古城边上,到的时候正好天黑,可以去看丽江古城的夜景。小佳说丽江古城在晚上和清晨最好看,我说那就今晚和明天一早把古城逛逛吧。

进古城不收任何费用,说收古城维护费的都是骗你的,不过倒是听说去黑龙潭公园门票里会包含古城维护费,这个貌似是真的,我没去。古城有很多入口,我们进去的那个比较偏僻,进去绕了好久才绕到一条灯火通明的主路上。走在古城的路上,路边全都是店铺,各种各样,琳琅满目,恨不得每个都进去逛一下逛。因为来之前答应几个朋友带礼物,所以很留心地看了看买纪念品的小店,发现不少东西以前见过,因为上大学时宿舍一哥们去丽江带回去不少东西。走到一家卖T-shirt的店时终于忍不住买了件有丽江味的Tee,可以在我的照片上看到我穿,才20¥,比起在北京买的那件50¥的TBBT的Tee来说便宜多了。

古城很大,街道纵横交错,我们又没有地图,我早就走晕了,还好有小佳在前面带路。好不容易才走到四方街,那边太热闹了,歌舞升平,酒吧很多,酒吧里人也很多,里面很热闹。当时听到有人在唱《我只在乎你》,在这样的丽江的夜晚听到这首歌别有一番风味,我很喜欢。丽江古城里到处都有水流过,到了晚上在灯光下感觉尤其惬意。四方街那里有卖河灯的,作成荷花状,中间放着蜡烛,看着它放到水里一直漂下去很有意思。有几个地方还可以看到水车,有大的有小的,很符合古城的风格。

逛累了走累了,找一家店吃饭。本来想吃丽江腊排骨火锅的,不过我在北京吃过了,小佳也吃过,遂作罢。于是我们就找了家小吃多的店,点了好几种小吃,丽江粑粑,竹筒饭,炒米线等等。我记得小佳点的炒米线很不错,我点的那份甜的丽江粑粑也还好,以前不喜欢吃丽江粑粑的小佳也说这次这个不错,但我不喜欢吃那个米灌肠。

吃完饭想去酒吧的,毕竟这里酒吧比北京的热闹多了。但小佳有些感冒,于是就陪她回去休息了,约好第二天一早起来去看清晨的古城。

清晨的古城是另一番景象。虽然我们起来收拾好出门都已经九点多了,但古城里开始营业的店铺仍然很少。这就是丽江的生活,晚上睡得早,早上起得晚,盼完天黑盼天明,悠哉悠哉~!在清晨的阳光下,古城里的水流,水车显得分外漂亮,有的地方还有小桥,偶尔还会有鲜花,走在其中感觉无比舒服。好想好想留住这样的清晨,好想好想留在那里不走……

走到四方街时看到了一群少数民族的大妈们在跳舞,人挺多的,很热闹,我也加入了她们,完全不会跳,跟着瞎跳,让小佳一起来她还不来。离四方街不远有一个邮局,昨天晚上就看到了,今天特意记着给北京的朋友同事们寄明信片,我买了一整套明信片,还让他们给盖了丽江的邮戳,然后就是一个个发短信问地址,写地址,贴邮票,最后寄出,说是一周之后到,我想那时我人都到北京了。

然后我准备做旅店老板的车去拉什海骑马,小佳因为上次去被晒黑了,所以这次说什么也不去了,我只好自己去。到了那里发现骑马的人很多,门票贵,我想去的那条线280¥一张,不过可以让旅店老板帮你讲价。牵马的大哥很有意思,他是纳西族人,说话带有浓重的口音,他让我叫他胖金哥。胖金哥会教你如何骑马,在路上他还会给你讲沿途的一些景点,比如茶马古道的来历,偶尔没话说了他会唱当地的山歌。这是我第一次骑马,感觉很累,尤其是马跑起来的时候。

骑完马就去喝茶,倒茶的是个纳西族的姑娘,她不光会介绍各种茶的由来和作用,还会介绍纳西族的生活习俗。最让我震惊的是,在纳西族,男女角色和我们是完全反过来的:男人在家几乎什么都不干,女人几乎什么都干,什么重活累活全是女人的,男人就负责传孙接代。这正好解释了为什么我在路上看到那么多上了年纪的女的还在下地干活。我问他们是不是也有走婚,她告诉我说现在虽然还有但已经越来越少了。

喝完茶去划船。虽然拉什海很大,但是能让你划过去的地方很小,绕一小圈就完了。在船上是听到旁边的船上有人唱山歌,于是我们船上的姑娘们要求和他们对,但是我们谁也不会唱……

从拉什海回来就让旅店老板带着小佳一起去束河那边。束河古镇和丽江古城差不多,就是比它要安静很多,人相对来说比较少,酒吧也少。但是随着最近几年的发展,束河也变得越来越商业化。因为中午没吃饭,所以在路边找了一家老奶奶开的小店吃点儿东西,尝了尝冰粉,凉宵,味道不错的说。束河不大,但都逛完也挺不容易,记得在一条路上绕了好久在走出去。在束河古镇的正门口有到丽江古城的车,一个人2¥就够了,坐满人就走。

回到旅店天色已暗,洗了个澡出来吃饭。去了对面的一家饭店吃鱼,我们还特意要了两瓶啤酒,四川妹子就是豪爽,酒量也不错,不像北京的姑娘们,怎么让也不喝,好不容易劝下去一杯,还得羞羞答答,吞吞吐吐才喝下去,还得再来一句:“人家不好意思嘛……” 吃完饭再回古城逛,今天晚上就是要去酒吧,来丽江怎么能不去酒吧呢!丽江的酒吧消费特贵,很多地方比北京的还要贵,太黑了。我来之前兔兔说让我去小吧黎,我们好不容易才找到,正好人也不多。问了问消费没其它地方那么贵,就坐下来接着喝酒,边喝酒边看乐队演出,正好听到有一首张震岳的《再见》,非常符合此情此景。因为第二天要去香格里拉,又和小佳商量了一下第二天怎么走,去了怎么安排。

川滇之行游记(一)

回来好几天了,一直没空写游记。今天有美女说应该写写,一是对旅行的总结,二是方便以后要去的人。那就写写吧!

首先,你要计划出远门之前必须提前至少一个月就开始做准备。比如该请的假提前请了,该倒休的提前倒了,到了日子跟前再做就麻烦了。还有一个问题就是机票,提前买折扣很多的,我这次去云南的机票是提前接近一个月买的,基本上3折,北京飞重庆加上昆明回北京,加起来不到1200¥。

还有就是做功课的问题。提前一个月开始就得做功课,仔细上网研究哪些地方要去,哪些景点要看,路线怎样,吃住如何等等。路线设计尤为重要,尤其是当你时间很紧张时,尤其是当你一个人旅行时,功课一定要做好。还有就是各个地方之间的交通,这个也比较重要,想想,万一中间哪一个环节断了后面的都会乱。住,我个人认为,不那么重要,除非你去的地方人超多(那还不如不去呢),住的实在紧张。我自己旅行的时候很多都是到了晚上才开始找住的地方,侥幸的是,我还没有一次没找到住的地方过。我的经验是,大城市可以住青年旅行社,小地方可以去旅馆或者客栈之类的,提前能在网上找到既便宜又靠谱的地方更好。网上有很多好心人,多看看他们写的攻略自己心中就有数了。做得太细没必要,计划总是赶不上变化,把最基本的功课做了就可以了。

我是先到的重庆。重庆有一个铁哥们,我们互称对方“老大”,我在重庆全靠他招待,所以我功课也不用做。出了机场第一件事就是给这哥们打电话,机场就在他住的江北,坐个大巴不到半个小时就到他那了。见了他之后二话没说直奔秦妈火锅。秦妈火锅我是在网上看到的,听说不错,然后就建议老大带我去的。我们到的时候已经过了中午吃饭时间,人不多。重庆的火锅太辣,我们只敢吃微辣的,后来证明这是多么明智的选择。我很喜欢那里的蒜泥,吃起来很爽。老大特意点了鸭肠和腰花儿,这俩在北京吃火锅很少见到,挺好吃的。因为和老大很久没见,所以我们喝了很多啤酒,喝完之后我虽然还没醉但我发现走路腿都发软了……重庆火锅一大特色是麻,吃完之后我的调料碗了半碗都是花椒,而且嘴唇麻嗖嗖的……

吃完之后就去市内逛,因为那天天气相当差,大雾,阴天,所以感觉看到的风景也没那么好。感觉重庆作为山城,地方很拥挤,而且道路转弯多,还上上下下的,分清东西南北挺不容易的。去了解放碑那边,码头,坐了坐轻轨,看哪都是雾蒙蒙的。去了一条步行街,里面有个小吃街,我惊讶地发现路边上有一排坐着吃酸辣粉的人,真是重庆一条亮丽的风景线啊。我也要了一碗,太酸太辣,比起我在北京西单吃的辣多了。重庆的妹子皮肤普遍很好,不知道是因为这气候的原因还是因为吃火锅的原因,在步行街上走经常可以看到美女,我和老大两人眼都直勾勾的。晚饭去吃的老鸭汤,非常喜欢那汤,味道很鲜。一天结束,回到老大那里休息。

第二天去成都时遇到点儿小意外,是我没有预料到的,居然买不到车票……不光火车,就连汽车也是。我去的时候上午7点,汽车却只能买到10点半的,火车只能买到晚上的!很震惊。倒是票贩子很多,到处都是。我本来已经放弃买火车票的打算,可汽车也买不到早的,我就找了个票贩子,他答应可以帮我买到9点的汽车票,但我对他不怎么信任,就说不坐汽车了,谁知他说他还可以帮我联系火车票,而且还是9点的动车!跟他去找了另一个票贩子,然后躲到一个地方偷偷地看了看票,不像是假的,于是多加了50元才买到!他说送我进站,路上和他聊了聊,问他们怎么买的票,他告诉我他们都是提前4天(或者10天,因为重庆话不分平翘舌)排队买,而且他们背后有大老板安排一切。总算知道为啥我在这个时候都买不到车票了!还好,票没任何问题,动车2个小时就到成都了。

教训:在重庆即使非节假日也要提前买火车票!

到成都出了站就去买票,广播里一直在宣传火车站附近骗人的把戏,列举了10多条,震惊,然后售票大厅里用四川话也在宣传……人太多,估计一时半会儿也排不上,就放弃了。出来之后等约好一起去丽江的姑娘小佳。说来有趣,她是在我走的前一天晚上10点多才发的帖,要是我早睡觉的话根本就看不到了。见面之后我们就去找别的售票点儿,在旁边的银行里看到一个,买了两张晚上去攀枝花的硬座。

然后在小佳的带领下坐公交去市内,去了天府广场,春熙路,在那里面的“龙抄手”吃了个午饭,尝了尝几个没吃过的东西。逛完之后去宽窄巷,本以为是一个巷子,原来是两条巷子,一个宽一个窄,由此得名。巷子有古成都的风格,感觉和北京的南锣鼓巷差不多。听小佳介绍说成都人喜欢喝盖碗茶,就在路边找了一家坐下来细细品茶,水可以自己随便加,很舒服,要不是没时间真应该坐一个下午的。她说其实应该去武侯祠那里喝茶的,只是时间太紧张,去不了,就去锦里逛逛。锦里那边人也比较多,感觉里面有古城的风格,就是里面水不怎么干净。

逛完就去超市买在火车上吃的喝的,然后直奔火车站。在火车站附近随便找了家餐馆吃了个晚饭就去赶火车。上了火车才发现,后悔了,车上的人都快赶上过春节的时候了,非常挤。真应该买卧铺的,教训啊!坐着睡不容易睡着,所以就一直在和小佳聊天,一直聊到凌晨,实在困得不行了才坐着睡觉。到西昌这一站时下了很多人,车上出现很多空位置,我们才一人一个座位趟下去睡。睡醒发现沿途景色很美,原来西昌也是个好地方。

到了攀枝花已经上午9点多,出了火车站就有汽车宣称是去丽江,千万别坐!它什么时候开先不说,而且它很慢,8,9个小时才能到丽江!记住,到了那里就直接打个的去客运站,不要让司机打表,和他使劲砍价,大约一人20¥就可以了,因为在攀枝花汽车站离火车站很远,真的,不是一般远……打了的之后在车上和司机谈谈,多半他们也能帮你找个去丽江的车,这种车是私人的,基本上5个多小时就能到丽江。

(提供一个攀枝花司机师傅的电话:13882358228,去汽车站,联系到丽江的车都可以找他。)

去丽江的这种私人车基本上得凑齐人之后才出发,我们是4个人,每人120¥。从丽江去攀枝花的路超级难走,强烈建议晕车的人自备晕车药,不管你晕得厉害不厉害,到这里一定厉害。一开始我们遇到了堵车,因为攀枝花的公路很窄,而且还有很多运煤的大卡车,堵了接近一个小时才出去。然后就正式开始所谓难走的路了,其实就是盘山公路,转弯多,90度的弯家常便饭,也有180度的弯,偶尔还会有个360度的弯,现在你该知道为什么要你自备晕车药了吧!到中午一点多时饿得实在不行了,转得头发晕,像我这种从来不晕车的人都感觉不舒服了,不过还好,司机正好要停下来吃饭,吃了饭就感觉舒服多了。所以,建议吃饱之后再坐这种汽车!司机不怎么爱说话,不过车开得确实不错,在这种路上开车什么技术都能练出来。

(提供从攀枝花去丽江的司机师傅的电话:13550907380。)

不算堵车的话,大约6个小时就到丽江了,比起那种大巴来要快不少。到了丽江之后司机还能帮你联系一家旅店,我们那家是在古城边上,如果你自己懒得再找的话直接就住那好了,还不错,40¥一间。到了之后洗了个澡,然后就去逛古城了。

再见,云南!

at Shangrila
(在香格里拉普达措国家公园)

昨天北京大雪,飞机延误,还好及时改了航班才得以赶回来。从四季如春的云南一下子回到了已经是冰天雪地的北京,一时不太适应,不适应的恐怕不只是身体……唉,到此为止,我那短暂的云南之行全部结束了,留下的全是美好的回忆。

我发现自己已经无可救药地爱上了云南,留恋那里的美景,留恋那里的生活,留恋那里的故事。香格里拉果然是像梦中一样的美,丽江又是像初恋情人般的迷人,那里有唱不完的山歌,看不完的美景……现在我终于体会到为什么会有那么多人因为太喜欢那里而决定留下来不走了。而我却不得不回到北京,因为这里有我的工作,我的朋友。云南之行对我来说大概就像是一场美梦,梦醒了,还要回到现实中继续生活。

记得在丽江的第二天晚上,我们去了那家小吧黎酒吧,喝酒时听到了张震岳的那首《再见》,用它来表达我此时的心情再恰当不过了。想把这首歌送给美丽的云南,送给那位同行的美丽姑娘小佳。

IMG_2567
(小佳,在碧塔海)

我怕我没有机会
跟你说一声再见
因为也许
就再也见不到你

明天我要离开
熟悉的地方和你
要分离我眼泪就掉下去

IMG_2249
(束河,合影)

我会牢牢记住你的脸
我会珍惜你给的思念
这些日子在我心中
永远都不会抹去

我不能答应你
我是否会再回来
我不回头不回头的走下去

[audio:http://data1.act3.qq.com/2008-11-26/19/baec25b5dcc6b202ee7e56ead04fae8c.mp3]