2008-05-27

程序随笔 - 5

有个棘手的bug,昨天鼓捣了一天没搞定,而一向灵光的``睡眠大法''也没有让我在梦里得到答案。但早晨刚来时灵光乍现,很快便root-cause了,根本原因也是一个竞态,fix也不难。回头看看这个过程却挺有意思。

这个bug至今只能在物理机上重现,但是用strace,GDB或者valgrind跟踪时则一切OK,而且下次再跑的时候一切完全``康复'',让人觉得分外诡异。幸运的是,我刚开始就加入了backtrace功能,在segfault的时候能看见堆栈的call trace,而不至于一筹莫展、无从下手。

早晨又仔细观察了一下call trace,多看了两眼#10 frame之外的信息(以前我基本只看最近的十个frame),接着便是如醍醐灌顶般的顿悟。这个bug的难处在于重现的概率很低,现场很容易被破坏,并且日志和core dump都让人很困惑 -- 再次诅咒一下多线程。

提交了补丁,顺手又fix了一个P3的bug,还剩下两个P4,感觉松了一口气。

标签:

2008-05-22

程序随笔 - 4

ESR在TAOUP的第七章讨论多道程序设计中需要避免的问题时,写下了这段话:

Threads -- Threat or Menace?

``From a complexity-control point of view, threads are a bad substitute for lightweight processes with their own address spaces; the idea of threads is native to operating systems with expensive process-spawning and weak IPC facilities.''

读到这句话时是大学毕业,并没有深刻的感受。随着项目RC2阶段的结束,有些 bug也越来越隐秘,难以调试。调试多线程的网络程序让人体会到类似量子物理 里的``测不准原理'' -- 因为竞态都是时间相关的,在调试器下观察程序的行为 使得程序本身的行为发生了改变。

1. Bug #1984

耗费了我昨天一个下午和今天一个上午,也就是整整一天,还不算昨晚在家屁颠 屁颠调试到午夜的时间。我们的C, Java和Ruby的客户端API在调用两个XML-RPC 远程调用时都会莫名奇妙的发生问题:第一次调用是成功的,第二次会失败,并 且此后的调用都会失败。因为其它类似客户端API都工作的很好,因此我怀疑是服 务器代码的问题。

手工写了服务器端代码和一个简单的客户端,服务器端只提供这个出问题的调用, 客户端工作正常。而服务器端工作也非常正常,苦闷。怀疑是 libary 兼容性的 问题。

祭出``printf大法'',一切显示服务器端的数据都很正常,而C客户端的日志显示 处理一次HTTP-read的时候读到了一次EOF。于是跟踪了一晚所用library的源代码, 无果而终。

上午回到公司,在服务器端把所用怀疑的fooDoSomething()去除:
- ret = fooDoSomething();
+ ret = 0;

一切都工作正常。OK了,那一定是fooDoSomething()的bug了,后续的调试果然证 明了这个结论。但开始时该bug只在64位平台发生,而且如果打开debug后,错误 的行为会稍有一点小变化。我想这和编译器还有代码的内存布局有关。请相关同 事做了相关fix后,天下太平。

2. Bug #2034

这是一个race-condition,出自我的代码。问题在于代码完成后为了其它同事的 方便修改了一些接口。事实上如果我的代码不是那么小心,这个竞态反而更不易 出现。这暴露出多线程程序下,对数据读写需要异常小心。因为多线程环境下, 所有数据默认都是共享的。而因此需要的加锁解锁又使得程序性能下降,印证了 ESR的在TAOUP中的论断。但不幸的是,根据``墨菲法则'',RC2的代码刚好在一小 时前冻结,于是我的补丁要大佬们在例行会议时讨论通过才能提交到svn仓库。

3. Bug #2041

不再赘述。出于对C++的迷信以及些许over-skill,虽然也不是我的bug,但再次 证明了``Lessons from Debian/OpenSSL Fiasco''中的一句话:``Try not to write clever code. Try to write well-organized code.''

标签:

2008-05-18

无题

这几天电视上都是地震的报道,画面催人泪下。各种来源的捐款剧也已积累成一个数额庞大的数字。但心里总有种说不出来的感觉 -- 领导总是那么英明,我们的党也一只那么光辉,救灾的总是``最可爱的人'',最受悲痛绝望的从来都是老百姓。压抑着,直到在solidot上看见这句评论:``人们渴望被感动,渴望沉浸于悲情,渴望悲情被抚慰,渴望感受到力量,渴望民族主义,唯独没有给思考留下位置。''

灾难会再重演,悲伤会被遗忘,因为我们从来都缺乏痛定思痛的勇气。

标签:

2008-05-14

天佑吾民

前天下午,正在屁颠屁颠改代码的时候,突然听到左右说地震了。有的说西安,有的说北京,还有的说上海。接着,我们的QE在MSN上说北京site震感明显。开了个小会回来后,状态已经``away'',五点左右在家里爬上线说是强制疏散了。周围的电话开始频繁。MSN上收到朋友消息说成都地震了。对,我现在一直自诩是official的成都人。晚上短了老大和潇总,无回音,心开始往下沉。

昨晚。第一次上了天涯,看到多张图片。心里放心不下,又拨了电话。老大的电话始终无法接通,急。拨潇总,``喂?我还活着。''听到回音差不多只用了三秒。顿时如释重负,却不知所云。再次短了老大,过了会儿回复说没事。终于放下心来。

荀子说,``天行有常,不为尧存,不为桀亡。应之以治则吉,应之以乱则凶。”但愿天佑吾民。

标签:

2008-05-11

scheme笔记 - 2

Scheme笔记中又添加了一节,关于continuation。

Continuation是scheme语言中进行流程控制的一个强大机制。区区几行,或者几十行代码就可以实现其它语言中的跳转,异常,生成器等。同样给出了一些参考读物以帮助理解。

下一节讨论符号处理。Lisp之所以广泛用于人工智能,和其强大的符号处理能力是分不开的。

标签:

2008-05-10

无题

偶尔电视,看到传说中的奥运圣火,依稀想起一步电影:《大腕》。

标签:

工作札记(4)

今天下班之前终于向svn仓库提交了一千多行代码,作为这个礼拜的主要工作结果。 很久不用C++,尽显生疏之态。

有两种知识比较重要,一种是``why'',其二是``why not''。关于第一种,大部 分的获取来源差不多是textbook;至于后者,工作中屡见不鲜。前些天看见老鄢 共享出来的``反面模式'',击掌赞叹。知道``why not''和知道``why''一样重要。

当我看见ugly的代码时,不要郁闷,因为在别人眼中,或许我们的代码也一样丑 陋。当然,最郁闷的还是必须服从某些``by design'',无论是代码风格还是某些 强制的逻辑。据说开放源代码可以产生更高质量的代码,因为人民群众的眼睛是 雪亮的。这或许也是许多公司闭源的重要原因之一,因为他们的代码远没有鼓吹 的那么漂亮。

网上看见一句话:I never knew feeling so stupid could feel so good.

标签:

2008-05-06

Sheme笔记 - 1

这段时间稍微有点忙,没有太多时间继续写Scheme笔记,目前已经完成四部分内容:
  1. Scheme简介
  2. 求值器模型
  3. 递归和尾递归
  4. 高阶函数
人说RERO,于是放至主页,共勉。

标签:

2008-05-02

程序随笔 - 3

程序设计不仅是一门科学也是一门艺术。优秀代码共有的一个特质便是simplicity。简单就是美,它不是简陋,也不是简易,更不是单薄,它是简约,是对本质的把握,而且必须恰到好处,所谓``增一分则肥,减一分则瘦''。

程序在本质上是思维的体现,思维的漏洞便是程序的bug。在程序走向一定规模后便需要团队合作开发。当然,团队不是越大越好,因为成员之间的沟通需要开销。沟通中出现的误解轻则导致bug,重则甚至使得项目失败。这样便出现了一系列的流程,用以规范化程序设计的各个阶段,这就是管理。然而不幸的是,许多管理行为也只是精心组织的开销而已。

半年时间,项目的代码已经超过了15万行。想来UNIX v6的代码也就9000行左右,而Linux 0.95差不多也就1.4万行。上周末Team Dinner,某兄弟口出珠玑:``知道商业软件为何需要提供support?没有support根本无法运行嘛!''

标签:

程序随笔 - 2

  1. 一个人和两个人
    • 一个人的时候快乐得像只鸟,想飞就飞,渴了稍做啜饮。如果没有物质追求,这是一段相当自由的时光。相当多的时间可以投入个人爱好,享受执著后的豁然开朗,风清云淡,充实异常。兴致来时,邀二三好友,畅所欲言,人生快事也。
    • 两个人的时候自己需要更添一份责任,但亦获得了一分关心。需要学会体谅,推己及人 -- 因为自己开始在意别人的感受,而那个人也会在意自己的举止。每天时间流淌,以不能再像以前一样只知书剑。柴米油盐,举手投足,触指皆是生活。
  2. 程序和软件
    • 一天可以写上数百上千行代码,也可以读完一本小说。可以选择自己喜欢的语言,各种不同的算法。可以欣慰的保存,也可以毫不犹豫的推倒重来。这中间没有任何风险,只有收获。因为这些只是一个人的快乐,一段过程后智力上的愉悦。
    • 工作时写的程序叫软件,因为它会被客户使用,将被以后的程序员维护。我必须使用指定的语言,指定的设计,指定的代码风格,当然还有指定的时间。我需要在代码中遍布各种日志,还需要让同事知道自己模块的接口,即使并非我的设计。

标签:

Emacs窗口快速切换

一直用C-x o和C-x b来切换窗口和buffer,这显然没有Vim里用C-w [hjkl]切换到指定窗口来得快捷。对于习惯于多窗口编辑的俺来讲,颇有点不爽。某天xiang哥问怎么在Emacs下快速切换窗口,我也只有很不好意思的说C-x o -- 说实在的,正因此我写C代码的时候更多的会用vim。

不过从今天开始,一切有所改观啦,只要在.emacs里加上这一行:
(windmove-default-keybindings 'alt)

这样就能用alt-[up|down|left|right]来切换窗口。

标签:

2008-05-01

工作札记(3)

除了刚进公司培训时为了一个demo熬过一夜外,我还是基本恪守八小时工作制,少有OT之举。这样说来,除了睡眠意外,似乎每天还有几小时的时间可供个人消遣。但细究起来,多数还是耗在了厨房工作,如果再洗个澡,至少是九点半开外。此时满身倦意,浏览一下文章便已午夜,哪还有什么精力去思考IDP,心有余而力不足。一个Q一个Q飞快的过,MBO换汤不换药,俱往矣!

前天为了一个问题折腾了好久,还好遇到老鄢,虽然看起来解决之道没什么美感(当然,原先的设计所致),不过还是很实用。感谢老鄢。

标签: