All Stories

辞职了

  今天是在Wicresoft上班的最后一天,中午请share team的所有人去食堂吃了一顿饭,其实食堂也不便宜,原本我打算在华师大的秋实阁请的,但是暑假了华师大食堂都关门了。于是在紫竹一食堂吃了,16个人542块钱。   这次跳槽是出于两个原因,一是经济方面的考虑,对于目前的我来说,跳槽是涨工资最快的方式,另一方面是工作内容,在Wicresoft做Dynamics AX的SE工作,我的生产力极其低下,查了一下过去一年的成绩,我的产出大概连Michelle的一半都不到,这让我很忧伤,这样的状况让我连向领导提出加薪的勇气都没有。新的工作我的要求是要多做些编码,SE工作可能一个月都写不到一行代码,我觉得我写代码的能力这样下去会退化干净的。而且我一直以前都只能说会C++,熟悉Windows平台桌面应用开发,却没有一个真正熟悉、精通的领域,这次新的工作会涉及到多媒体视频、网络传输方面的内容,这样我也就有机会拥有一两个领域的专业技能和知识了。   办离职手续其实总共花了不到2个小时时间,但跑来跑去还是挺累人的。

Ainesmile,Rust,Clang

  最近Ainesmile的进展几乎停下来了,因为想到要让它支持像TextMate那样的bundles机制,但又为了避开版权问题而不能直接使用TextMate的bundles,所以就想把那些bundle的格式转换一下用就行了,于是就要写个小程序进行文件格式的转换。为了这个转换小程序更具有通用性和实用性,我就很是贪心地想让它支持在JSON、Apple PList、Windows INI、Java Properties和plain XML任意二者间进行相互转换。本来想想觉得只是个很小的任务,可实际做的时间还是有很多事情要做的,而且想来这样一个具有通用性和实用性的工具应该可以发布给别人使用,于是在包装上也做了更多点的工作,比如画图标,而且为了能在Windows和Mac OS X上都能使用,同时以为以前用过的一个Rapid XML封装更容易使用,结果陷入了无尽的跨平台的fixing中。   昨天发现一个新语言,Rust,据说是Mozilla开发来为了替代C++重写Firefox用的,现在才0.3版本,语言特性也还在快速变化中。看了半天的tutorial,发现语法上给我的感觉是很像Ruby,又有Erlang的一点点元素,而它自称是一种系统编程语言,所以从一开始就很注重与C的交互。它是一种编译型语言,有个叫rustc的编译器,现在还只能通过自己下载编译源代码来使用它。看tutorial的时候突然有个念头,这些年不断冒出来的声称解决了一大堆问题的编程语言,实际上也就是它声称的那些个领域上表现较好而已啊,C语言才是王道啊,哈哈。   在编译Rust的时候,发现它自动下载了最新的LLVM和Clang的源代码并编译好了,于是我就想再试下Mac OS X下用Clang编译下Qt,以前曾经尝试过但失败了。这次也遇到两个错误,就是返回值类型要去const修饰,gitorious上已经有patch的,但在4.8.2上没有合入,自己改一下整个Qt 4.8.2就能用Clang编译通过了。Clang在Mac OS X上基于上处于产品级的质量了,但不知道在Windows上什么时候才能达到近似的水平啊,叹气。貌似Clang对unix-like的系统都支持得挺不错的,甚至能用来编译FreeBSD内核。

文本编辑器Ainesmile

  最近正在编写一个文本编辑器,取名为Ainesmile。按照惯例,这个名字同样是一个妹汁的id。   这个文本编辑器的目标是成为超越Coda、Sublime Text和TextMate的存在,所以基本的定位是一个代码编辑器,也可以做为一个通用的纯文本编辑器。它使用Qt开发,所以目前可以确认的是它将可以在Windows和Mac上运行,如果移植代价不大,将也会在Linux或FreeBSD等其他Qt支持的桌面环境中运行。   写这么一个文本编辑器的出发点,首先,我觉得Mac OS X上的几个编辑器的功能都很炫目,很有现代感,而Windows平台上除了e,就没有其他类似产品了,而e的功能也似乎只是TextMate的一个子集。其次,我觉得Mac用户真是人傻钱多的存在啊。   功能方面,我觉得实现起来没有特别大的技术难点,只不过工作量有点大。当前一个主要的问题是,美工方面,缺少一套用于菜单、工具栏的图标,以及程序图标。求帮助。

好久没来写blog了

  这个月总的说来过得很开心,进展很大,当然前些天也一度出现很灭世的事,甚至为之放声大哭。   一个人的日子果然非常无趣,于是马上回到了用物质享受来麻痹精神的状态,买了一个BlackBerry的PlayBook,一个HP的TouchPad,总共花掉2600块钱,这个月就开销就这变大了。   之后一段时间最主要的两件事,一是找工作,二是写程序。有很多程序要写,现在由于Qt的lighthouse在4.8版本的比较成熟的运用,使得它在QNX,Android,iOS平台上都能进行可以发布级别的移植了,甚至webOS上都可以用了,除了据说虚拟键盘会弹不出来,这样在Pre2/3上应该是没问题吧,虽然我最想的是在TouchPad上用。不过iOS上那个Qt4iOS是要付费的,而且不卖license给个人用户,估计是因为太贵,作者觉得个人用户承受不起,郁闷!   昨天下班后去浦东机场接了小咪,感觉她跟中学时的长相差别好大,看照片中学时要清纯漂亮很多。回到小区是21:39,然后去对面的接头暗号吃肉,不过好像有点吃坏肚子了,晚上2点多起来拉肚子。后来醒来很多次,7:15时醒来打电话喊人起床,再一直迷迷糊糊睡到10点多,发现小咪已经起床了,再起来两人收拾收拾,去老街吃东西。每当有人来这里,我都是带人去老街吃东西,哈哈。不过小咪没像其他人一样吃汤圆,而是去吃了小笼包。吃完就把她送到虹桥高铁站送走啦!   从高铁站回来,又把别人托小咪带回来的东西送到人家手上了。   哈,好像没什么可以写的了。

一次从栈中寻找被优化到寄存器中的局部变量指针的经历

  上周基本解决了一个dump文件分析的问题。   一开始,问题没有弄复杂,只是从最后异常看到call stack,大体得出某个类的指针为NULL,却被继续使用,然后fix的话只要在被使用前判断一下是否不为NULL就行了。   不过这个fix有一点没有考虑到,是该方法一开始就有一个分支对该指针进行了判断。所以如果该分支确实成立的话,我的fix就说明有问题了。于是新的问题就成了验证该分支的条件是否成立。   分支的条件是判断另一个对象的每个成员是否为空。本来,这个对象一开始是new出来的,指针是某个方法的局部变量,一般说来是放在栈上的。不过通过call stack切换到那个方法的context后,发现查看局部变量并没有那个指针。通过查看反汇编的代码,才发现原来该指针被优化了,并不存储在栈上,而是存储在寄存器r13上了。于是我就开始想着如何可以查看某一级call stack时的寄存器,一开始我以为每次call指令时,会自动把所有寄存器的值都压栈的,后来发现不是,还特地去找了Intel的指令手册看了一下说明,反正没说有压栈寄存器,大概是我记错了。问了一下那个老外同事,他说没什么办法,只有想办法从栈里找。   这样没头绪了几天,后来灵光一闪,偶尔发现在call stack中使用r13存储指针的方法的下一级被调用方法的反汇编代码中,把r13压栈了!于是只要在栈中就肯定能找到那个指针的值了。至于怎么找那个栈中的位置,从函数的返回地址找!从最后的esp值开始大地址(栈的生长方向是往小地址方向生长)开始搜索那一个方法的返回地址,找到后再往小地址找压入的栈的寄存器值,果然找到一个值,可以通过dt来查看,还可以通过dds该地址的vf-table来查看它的虚表包含的虚函数名称,这样就可以验证是否是要找的那个对象。果然没错!

最近过得很开心

  前天傍晚下班回来的路上被追尾了。因为车速比较快,前面的一辆的士突然停下载客,我就急刹车,差点点就要撞上前面的,我都感觉到我的车好像因为刹车踩得太猛而什么东西突然断裂了一样,但是后面另一辆的士就没刹住,撞上我了。看了一下,我只是后面有几条划痕,那的士是右大灯完全废了,都往里陷入了。我也懒得跟他计较,只想着快点回去。   最近几天因为原来做面试的两个同事都到美国培训去了,于是把面试的活都仍给我了。开始还觉得有点新鲜感,两三次后就有点厌倦了,电话面试了好些人,不少还是硕士,不过貌似大多对软件开发并不是很熟练。   接到几个Watson bug,不过实在没经验啊。   KarenMeu迟迟不开工,主要是有两大块还没一个清晰的思路。界面部分想模仿Qt Creator,看了一点源代码,没头绪。另外就是想有一个极度灵活的插件架构,插件主要分两类,一类是界面插件,一类是业务插件,业务插件产生数据,提供给界面显示和操作。同一个业务插件可以让用户自由地选择不同的界面插件进行显示。具体细节想不好该如何实现。   最近过得很开心。

Ninayan W.I.P.(29)

  这两天又重新拾起Ninayan来,随着embed.ly的收费,Ninayan的主打的图片、视频浏览功能被废掉了,只好自己写代码来实现这部分了,但这工作量应该比较大,只能慢慢来了,有点想把这部分代码做成开源项目,叫SANSASORI。   之前也有断断续续地修改,支持Follow5,后来Follow5停运,然后支持StatusNet。这两天主要修改了一下UI,Twitter部分原本就支持使用Twip4的T模式和O模式,只不过没有设置UI,这次把账号设置的UI做了小部分高速,除了可以修改API地址,还为每种oauth服务都增加了用户自定义API Key的功能。这主要是在支持腾讯和新浪微博的过程中,一直遇到因为API Key不能正常使用的问题,如果用户可以自定义,应该能缓解一部分问题。   另外,还在Proxy部分增加了导入用户自定义的SSL证书的UI,这样就可以使用goagent做代理了。不过使用goagent的过程中偶尔发现会有所有网络连接都阻塞不返回,然后不能发起新的网络连接的问题,在网上找了一圈没找到怎么为QNetworkAccessManager的post和get方法设置timeout的方法,纠结。   把文章、图片和视频的浏览功能修复后就不打算再为Ninayan大动干戈了,不增加功能了,顶多就是有bug修一下。之后就开始做KarenMeu了。

嵌入的CLR引用销毁的C++对象的问题续

  前面的blog中,网友sali98提到可以用#pragma init_seg(compiler)等来安排全局对象的构造和析构顺序。这倒是我以前没有想到的,不过经过实际测试后,发现这个方案并不能解决我的问题。   在原来的定位结果中,以为单纯是嵌入的CLR对象晚于C++对象的销毁引起的问题,实际上问题要稍微复杂一点。首先,上次提到的使用_exit引起的对象无声息的消失,不是主要问题。这里调用_exit是在之前有个人把exit换掉的结果,他以为_exit不会调用对象的析构函数,于是不会引起析构时资源销毁时机不正确的问题。事实上这个fix是不起作用的,因为从call stack来看,_exit对嵌入的CLR似乎不起那个作用,而且无论是exit还是_exit都会在对象正常或不正常销毁后仍然有消息循环存在,消息循环中某些处理代码仍然会继续运行,而那些代码也是有可能会引用已消失的singleton的。   最早我想的解决方案是基于这样的想法,既然是C++的singleton在被销毁后没经检验就来使用,那么就把singleton改好一点就行了,我想过《Modern C++ Design》中提到的Phoenix Singleton,也看过一些boost中的Singleton的实现。不过后来都感觉太麻烦,没必要。于是今天试了一个很简单的方法,增加一个static bool变量,标记当前singleton是否有效,然后在每个非static的method开头都先判断一下。简单测试一下,倒是能勉强工作了,不过发现另外一个问题,这样的singleton不止一个!而且另一个不好的地方是,每个非static的method都要修改一下,不必要的改动太多。   今天又看了一下crash的call stack,我就觉得单纯修改singleton的实现似乎不是很高效。于是我就想,是不是有办法在调用exit或_exit前就自己写代码把CLR卸载掉,把消息循环停掉?以我对.NET的粗浅的了解,我觉得嵌入的CLR是应该可以主动卸载掉的,只不过也许某些正在使用的资源会成为阻碍,这个要仔细调研一下。而停掉消息循环这个,感觉也是可以的,增加个标记,在消息循环里判断一下,可以自己主动跳出循环。

编译了GDIPP

  前两天才知道GDIPP是LGPL的,放在googlecode上。昨天把它所有的源代码clone下来了,然后编译了一下,倒是全部编译出来了,不过运行后貌似没什么效果,囧了,有空读一下它的源代码。众所周知Windows的字体渲染效果不怎么样,所以对于自己有一套效果良好的字体渲染手段是很有吸引力的,我就是想试一下把GDIPP集成到自己的程序中去。