All Stories

写程序是件很诡异的事

  上午花了两个多小时,嗯,确实是两个多小时,写了个小程序,每隔一段时间扫描一下指定的文件夹下所有core dump文件,和历史数据库中的记录进行比较,如果历史数据库中没有记录,则认为是新追加的文件,一边将其添加到历史数据库中,一边则使用cdb.exe通过命令行进行分析,最后将分析结果连同那个core dump文件一起通过SMTP协议发送到notes邮箱中。  其中遇到不少奇怪的问题。本来是打算cdb.exe将分析结果重定向到文件后,自己读一下这个文件的内容,把这个内容作为邮件的正文发送的。结果首先是发现,使用system这个CRT函数,其中是调用了cmd.exe /c这个命令行,所以如果传给这个函数的参数如果同间有空格,是要用双引号包括起来的。尤其要注意的是,如果打算执行的是一个带参数的命令行,得从头到尾一起括起来。接着我就想用ifstream的方式把文件内容读出来,然而很诡异的是,直接将其输入到一个stringstream时,只有一小部分内容读出来了;通过getline一行一行读出来后,本来打算全部追加到另一个string中去的,但是就是追加不进去,最后想使用API吧,直接CreateFile,再ReadFile,内容但是全读出来了,最后通过SMTP发送这部分正文时,依旧只能发送前面一小部分。放弃了,本来就昆个Quick & Dirty的东西,于是还是直接把这个文本文件作为附件发送吧。也不知道是不是那个SMTP类本来就有问题,运行的过程中时不时弹出个出错信息来,什么delete指针时错了呀,堆被破坏了呀,等等等等,不一而足,实在无语得很!  不过尽管还是会弹错误框,但手工点一下也不麻烦,先这么着吧,至少可以当成一个监视器用了。  这两天我一直在想一个问题:是不是mini dump只有一个用途——!analyze -v?没有找到答案,但翻遍所有的能找到的参考资料,似乎这个猜想是真的!

炮轰Boost build

  今天在Boost的开发maillist上看到有人在抱怨Boost Build系统的不好用,我难得耐下性子来看了看,其中提到好几个问题:Getting Start文档中没有明确的说明命令行;编译MPI库需要修改user-config.jam文件;与ICU一起编译Regex库会报静态链接和动态静态不兼容的错;解决了Regex编译时链接的问题后,用的ICU lib文件名却需要自己修改一下;编译Graph库时链接Expat时需要修改jamfile.v2文件来修改链接的lib文件名。除了MPI的问题外,其他的我也都遇到过,也都差不多自己解决了,我还真是个可以逆来顺受的人,虽然觉得很麻烦,但却想不起要求Boost来改进这些缺点。不过今天看到这个帖子后,感觉大快人心啊,哈哈!  顺便提一下,今天我找到可用通过cdb.exe来直接使用命令行对dump文件进行分析的的方法了,可以直接将分析结果在控制台上输出,这样就简单地利用管道将分析结果获取到了。这样基本解决自动分析dump文件的技术上的障碍,最多是要再自己写个小程序,可以分成两部分,分别是前端和后端。前端负责获取新的dump文件,可以是定时扫描某个文件夹,或者定时扫描email,或者通过其他的socket传输等,反正就是获取到一个新的dump,然后调用cdb.exe这个命令行,而后端则是将cdb.exe输出的结果重定向到其他地方去,可以是通过email发送出去,或者是写到数据库中,或是写到excel中,或是直接填充到WIKI上去。总之,现在怎么整都可以了。

发现一个问题

  看《Windows高级调试》猛然发现一个问题,书中的例子都是对exe进行调试的,而且几乎都是知道问题重现步骤的。这跟我现在的情况可差得很远了,我只有一个core dump文件,不知道问题出现时的操作。看书上都是一直操作,直到问题出现,然后在调试器中断下来,查看寄存器,堆栈,句柄等信息,再抽丝剥茧一点点推测出问题的根本原因。我不行啊,我在源代码中加入了一个自定义的UnhandledExceptionHandler,在问题出现后,就转到那里去执行了,连最后现场都被破坏了的!  晕!

音乐方块

  昨天小妞给介绍我玩了一个PSP上的方块游戏,规则很简单,只要把4块或更多的同色方块组成正方形或扩展的长方形,就可以消去这些方块。这个游戏的很美妙的背景音乐,还有绚烂的动画。在小妞屋里玩了差不多一个小时,虽然规则简单,但要玩好实在不容易。  于是回到家,我自己去网上搜索了一下,原来叫《音乐方块2》。它由Q Entertainment公司门户的水口哲野出品,可玩性角度讲很适合mm玩,嗯,这也跟实际相符合,毕竟就是小妞介绍我玩的。  在家我也玩了一阵子,感觉比我原来PSP中已经安装的那些游戏要吸引我得多,看来PSP也不是一无事处啊,哈哈,原本都只是在像候机之类的时候打发无聊游戏才玩一下的。最近拿出PSP也是上次小思宇来这儿过夜,她拿来玩了一会儿炸弹人,后来还说搞得她一晚上没睡着,哈哈。以后得多多发掘一些有趣好玩的游戏啊,包括NDS上的。

让时间来化解

  今天疯丫头发邮件来,随便聊起各自的近况。这个性格柔弱却有点儿自己的小固执的姑娘,看着就是那种让人忍不住想欺负一下,却又忍不住要好好疼惜的人。想起以前一起玩耍的日子,还有她对我的各种大决定的意见,有时候让我觉得有点儿困惑。  也许我在她眼中真的就是一个小弟弟,偶尔在她的面前会表现出一些小孩子脾气来,也许有时候我在她眼中又是一个男人,站在女人对面的男人,希望能做些理应不该由女人担当的事情。  原本被我深深压抑在内心底层的那些亘古遥远的回忆和情绪,又都活络起来。也许唯有时间可以化解这一切。

《Windows高级调试》

  书在桌上摊开好几天了,不过一直没有投入进去用心读。今天似乎也有点闲了,于是认真地看了一会儿。这本书在去年《软件调试》上市做宣传的时候就已经听说了,还花了点时间去网上找过英文的电子版本,尽管后来发现公司网上很早前就有人发过了。找来英文电子版也就纯粹是满足一下心里那种奇怪的怪癖吧,而从来没有开始看过。  今天读来,发现《Windows高级调试》和《软件调试》基本上两本没有交集的著作,但在一定程度上却是互补的。《软件调试》着重的是原理和底层设施的介绍,而《Windows高级调试》则注重实践,应用各种现有的软件工具,调试各种软件问题。由此联想到另外一本书《Windows用户态程序高效排错》,该书则是案例形式,内容显得比较零碎,不如《Windows高级调试》那么系统化。  最近几个月来,在负责项目组内的core dump文件分析工作,由此才对该领域开始重视。一直以来,都是依靠WinDbg的!analyze -v命令进行分析,如果它能打印出最后的调用栈,而且调用栈又能比较明显地指出出错的源代码行,我才能连猜带蒙地得出一个定位结果并以此指导问题修改。但这样的好事并不多,大概还有3层左右的core dump直接靠!analyze -v是得不到那么明显的信息的,于是对这方面的技能要求就高了。  今天又从一个同事那里得到一个ppt,里面是公司一个传说中的core dump分析组的演示,原来还怀着比较崇敬的心理希望能从中学到那么一招半式的,结果从头到尾翻了一遍后,发现他们就是直接调试的debug building,让我比较失望,同时更是有些不屑,不过如此嘛!  最终还是得靠自己呀,总之看了《Windows高级调试》一书中对于“栈”的调试那部分后,我隐约觉得,在这书的指导下,加上这么多的实践机会,应该能让我在分析core dump的能力得到很大的提高。

MinGW升级

  前些天鬼使神差地换上了MinGW官方的4.4.0Release,当时也没怎么想什么后果,只是觉得这4.4.0无论是在语言上或者库上,都向C++0x靠近了不少,就应该拿来用用。昨天兴起,启动了CruiseControl,却发现其中一个用到了wxWidgets的工程构建不通过,依次修改,修改好几次,才终于搞定。  换编译器是件大事啊,boost要重新编译,wxWidgets要重要编译,这些都是比较正规的使用了C++的库,最近一次出错,是发现我的工程在链接时找不到一些符号,而其中一大批符号的名称中都有sjlj字样,想来是异常处理机制的问题了。上官网看了一下release notes,原来它把默认的异常处理机制从sjlj换成dwarf-2了,而我原来用的TDM-GCC是默认用sjlj的,所以只要全部重新编译工程就可以了。传说中,这个dwarf-2在没有异常时,是0开销的,不过TDM-GCC的网站上说,用dwarf-2前,要先仔细确认一下,该工程会链接到的那些DLL中如果要抛出异常,是用什么机制的,除非能保证它们也都用dwarf-2的方式或者干脆不抛异常,不然还是老实点用sjlj方式的好。不过我想,我在这方面的顾虑很小吧。

看到Chrome的可执行代码差分算法

  无意中在一个讨论组中看到Chrome的新differential算法Courgette(http://dev.chromium.org/developers/design-documents/software-updates-courgette)的讨论,其中提到一个Develper Channel从190.1到190.4的升级例子:完整升级包:10,385,920字节,一般bsdiff算法:704,512字节,而Courgette算法:78,848字节,近十倍的空间效率提升啊!真是太恐怖了,直到今天我才知道,原来对于二进制补丁,也是有这种优化算法的,汗啊!http://neugierig.org/software/chromium/notes/2009/05/courgette.html 这篇文章也对这个算法进行了介绍。大体上,Courgette算法目前是基于x86体系的,适用于exe、dll等可执行文件补丁,它会将这些新旧版本二进制码进行反汇编,在反汇编的基础上进行比较,据说是将二进制文件中所有的internal pointer/reference的地址重新符号化, 然后再计算differential,得到补丁。  另外一个博客中也有一篇讲优化二进制补丁算法的,http://blog.csdn.net/housisong/archive/2006/04/11/658863.aspx。  由此我想到我们现在的自动升级程序,都是完整文件下载替换的,土了啊!

Loki::Factory挺好用

  这两天在做一个特性,其中一段很经典的根据不同的类型id来创建不同的对象的代码,想到了《Modern C++ Design》中的那个实现,马上找来Loki用。  非常简洁的代码,定义一个基类,然后就可以根据类型id来创建对象了,如果创建对象的时候需要一些参数,也很容易,另外定义一个Loki::Seq就可以了。  每个派生类可以在源文件中用一个匿名的namespace保护起来进行注册,这样就彻底达到了只要加入该源文件,就有该类,不加入该源文件,就没有该类。不需要修改其它任何代码。  挺好用的!