昨天好不容易咬咬牙,把捕获未处理异常的功能提取出来封装成一个dll了。这是一个很简单的功能,所有的代码都是现成的,我只不过是把它从源代码复用的方式改成了二进制复用。当时公司里的同事说我这源代码复用的方式太落后,想叫我改成一个COM组件。而我又恰恰对COM很反感,所以一直都没动手。这次在一体化平台中涉及到2个exe程序,而只在一个主程序中用到了这个功能,有一天收到一个报告,另一个exe程序也会崩溃了,所以就有了要分离出来的想法。
提取成dll我当然不会用COM来封装,而是学MinGW中的exchndl.dll的方式,移植的主要工作是把MFC中的CString类都替换掉。这花了不多的时间,然后放在WallpaperHelper中进行测试。
除了记录了系统简要信息和调用栈信息,我还另外加了几项也许有点用的内容,包括当前系统中所有的进程、环境变量、当前进程所有的模块、所有线程信息。本来还想加些其他内容的,比如当前系统的服务信息、系统设备驱动程序信息、当前进程的所有句柄、所有文件映射、所有窗口等等,不过想到暂时这些信息也不是很重要,而且这样会让生成崩溃报告的时间更长,先还是放一边吧。
最近我想我真的是工作压力大了点,昨天下午睡午觉,梦到了很多乱七八糟的事情。最让我觉得气愤的是,居然梦到有个老女人,对我的工作指手划脚的,然后旁边两个同事也不知道在干吗,跟现实中的很相似。真是日有所思,夜有所梦,愤慨啊,竟然我的梦都被人这样强加干涉了!
posted @
2008-09-07 21:38 missdeer 阅读(7) |
评论 (0) |
编辑 收藏
昨天从网上查到,要让dot支持中文,必须得把dot文件保存成UTF-8编码,可是我用C Runtime、MFC CFile、C++ iostream都只会保存成ASCII的,于是不可避免地要再多一道工序把字符编码转换一下。
从一开始我就想到了iconv。先拿来它的可执行文件,在控制台上尝试了几次,原来是要把中文的设置为gbk才行,如果是ascii或者 gb_2312-80都是不行的。知道iconv确实是可以将编码转换后,就放心大胆地在程序中使用iconv库了。从公司归档库中找得到的只有1.9版的,但好在.h文件和.lib文件都有,看了一下头文件中的声明,猜猜也就是先iconv_open,然后iconv、最后iconv_close共三步操作而已。于是先把文件都读出来,然后iconv。可是死活不能把转换后的内容存放到目的缓冲区中,而源缓冲区,以及返回值,还是源数据长度和目的数据长度却都是对的,实在不得要领。这样郁闷了好久,还是不得其法,于是准备直接用iconv.exe来转换算了。
iconv.exe转换时会把转换后的结果直接在控制台输出,可以通过管道重定向到文件中,可是在程序中要得到这个结果就遇到了些挫折。首先想到的当然是CreateProcess,然后通过管道捕获输出,可是发现这新生成的进程一直不结束,我估计是哪个参数没设对,这个API的参数也太多了点,昏厥!放弃,试了试C runtime函数system,倒是可以直接像在控制台上写一个有重定向的命令行,可是在执行时,会出来两个黑的控制台窗口,这用户体验也太差了!再放弃,看了看ShellExecute这个API,但好像不能重定向。
还是转回来用iconv库吧!最后还是从网上找了一段代码,先要iconv传入几个空指针的调用,再一行一行地从源文件中读出内容,再一行一行地调用iconv,最后一行一行地写入目的文件,这样居然就行了,大汗淋漓!
posted @
2008-09-05 22:46 missdeer 阅读(9) |
评论 (0) |
编辑 收藏
几个月前,就想从公司图书馆去借本《Lex与Yacc》了,可是从在线服务中可以查到确实有一本没有借出去,但到了图书馆就是找不到那本书放在什么地方了,图书馆的人说他们也没有办法找到,因为书要么就是照着编号放在书架上的,如果在指定的书架上没有,那就没办法了。我还为此去了几次图书馆,希望碰碰运气万一某一天他们整理的时候能发现那本没有找到的书,但是一次一次都失望而归。也想过自己买一本,但逛过深圳的几处大型书城,都没有找到过,从网上倒是能看到介绍,可是都是断货了,太郁闷了!
昨天觉得该去还那本《Windows技术内幕》了,虽然借了三个月,但没看几页。到图书馆一看,惊喜地发现有一本《Lex与Yacc》静静地躺在柜台面上,看来是刚刚有人还回来的,连忙抢到手中。
实在觉得这词法分析和语法分析在处理模式化文本时太有用了。说起来虽然现在在做那个劳什子一体化平台,可是我心里却一直想回去完善编辑器,简直有种生不逢时,壮志未酬的感觉。本来同事是有一种语法解析组件的,大概浏览过那代码,其实是从ruby源代码里抠出来,在某一阶段直接把语法分析树dump出来。不过不知道为什么在源代码超过8000行时,分析出来的行号总是过绕接,从头开始。我也没仔细定位过这个问题到底是哪里出了错,主要是那代码全是别人写的,而且用了一些我个人极不喜欢的处理方式,我就懒得再去查错和修正了。我宁可自己再写一个解析器,因为我知道用lex和yacc可以做到。当时简单地看过ruby的源代码,发现它的词法分析器并不是用lex生成的,并且里里有一段代码是用gperf生成的,于是以为gperf也是一种词法分析器生成器,后来自己用了gperf才明白过来,原来ruby的词法分析器是手写的,其中gperf生成的那段代码只是为了识别出其中的保留字而已。而语法分析器确实像是用yacc生成的,不过由于ruby的语法太过于魔幻,所以语法分析器似乎复杂得超出我的想像。如果我回头再去做编辑器,这个语法解析器势在必行,不关是为了解析出语法树显示出来,另外还有些用途。其中之一是,其中有一个另外的需求是将表格化的描述与脚本来回转换,如果没有可靠的语法解析器支持,这个需求要实现就实在太过困难了点。另外还有个需求,是前两天才提出来的,说是要能跳转到方法定义处,于是当然要知道方法定义的位置,而这位置当然需要事先准备好。本来还以为rdoc从源代码中提取文件时可以顺便提取出来,后来同事一说,yaml中并没有保留文件名和行号,所以还得想办法提出来。我一想这个就太不可靠了点,万一某些方法就是没有注释文档呢。所以一定要另外有个模块来提取方法定义,我当时想到了ctags。今天试了试,发现用ctags还是有些缺憾,它只能提取出方法名称,以及匹配该名称的正则表达式,而并没有行号。另外,看了看ctags的源代码,发现另外更严重的问题,ruby并没有说定义方法时def关键字和方法名一定要在同一行中,如果是不同行中,ctags就不行了,所以还是得实实在在的语法解析器出马啊!
当然,像ruby这种比较复杂的语法解析,我不需求全部自己从头开始写起,可以抄袭一部分它的代码,至少词法分析器大部分可以直接使用,而那语法解析里把BNF留下,把动作换掉, 这样虽然还是要读懂那部分代码,但总比全部自己来轻松多了,而且也可靠得多。
得稍微系统点地学习一下lex与yacc了。
posted @
2008-09-04 21:32 missdeer 阅读(6) |
评论 (0) |
编辑 收藏
今天在公司就发现有人传了个chrome的完整安装包上来,都没有安装过程,直接双击,过n秒钟的后,窗口就弹出来了,很简洁,简洁得让人感觉像是个玩具。只玩了两下,就没了新鲜感,就凭它现在的状态,它是吸引不了我的,我还是继续用回Firefox,那些使用习惯设置,插件,都已经成为我暂时离不开 Firefox的理由。
回家打开Google Reader一看,n多blog和discussion在描述chrome,顺便让我有那么一点点惊喜地发现这还能直接从svn里下到源代码!不过就像其他的各种开源源代码一样,不到真的要用时,我是决计不会去看这些源代码的,尽管我确实已经下了不少源代码了,包括Code::Blocks、 CodeLite、notepad++等等,都是因为在某些时刻突然觉得这些源代码有一定的参考价值,而且update这些源代码也成为我每次打开电脑后几乎必做的一件事。但实际上,我却还是没有真正能从这些源代码中获取过多少有用有价值的东西,这不怪这些源代码,而要怪我自己。公司里有个牛人,看部门似乎是个做硬件的,却好像看过n多开源项目的源代码,包括那些BSD系统、Linux系统的,实在佩服这种人的毅力和恒心。
Google出浏览器了,对最终用户来说,也许是件好事,这样激烈的市场竞争,能促进产品进步。当然可能就苦了Web开发者,不同的浏览器之间必定有些不兼容的情况存在,而Web开发者则必然需要为了兼容几大主流浏览器而煞费苦心。
对于我来说,暂时影响不大,继续留守Firefox 3观望中。
posted @
2008-09-03 19:30 missdeer 阅读(12) |
评论 (0) |
编辑 收藏
上周没调完,今天接着调,调了一天,勉强可以实现点对点文件传输了,但还剩下不少问题,比如我会在服务器端先读入整个文件,如果该文件很大很大,岂不是很占内存,如果超过了物理内存的容量,要动用虚拟内存,岂不是效率又会降低不少!这只是众多问题中的一个,还有其他各种问题,只能走一步算一步了,关键是先把容错性做好,不要动不动就崩溃。
现在的情况是一个程序里,又当服务器端,又当客户端,两边我都是用reactor实现的,其实我对其中的工作原理一窍不通,只不过抓来几个例子,照着书上写的拼凑起来,好在调试工具还算好用,加上一点点的抽丝剥茧,总算理出点头绪,也得到些经验教训。
首先,不要为了图省事而使用那个全局单件reactor对象,我开始的时候服务器和客户端共用这个对象,后来觉得不妥,把客户端的改成一个客户端连接临时生成一个reactor,使用调试工具发现勉强可以用了,服务器端却不会自动调用handle_output,后来把服务器端的那个reactor也换成自己生成的,竟然也可以了,也许是我没用对,但反正现在它几乎能运行起来了。
其次,无论reactor是用在服务器端还是客户端,都要 run_reactor_event_loop一把,这个调用一直不返回,大概直到end_event_loop之后才返回吧,所以要另开一个线程来调用,除非是不想干其他事情了。这样,还可以看到一点,就是在适当的时机,要调用这个结束的方法。这和boost.asio的做法很相像。
再次,发现ACE_Message_Queue里居然只能存入16个最初压入的记录,后面再压入的全都被丢掉了,也不知道是不是有方法可以扩充到更多个数的,或者我觉得STL里的deque也不错,可以在头尾任意一端进行存取,不过ACE_Message_Queue似乎可以通过模板参数指定线程同步等选项,deque大概就完全要靠程序员自己把握了。
最后,要调socket程序,拥有和掌握好用的调试工具实在很重要,Wireshark这个开源的东东实在不错,只不过公司里居然装WinPCap是受限的,不过那个检查工具是防君子不防小人,好在可以通过改注册表中的卸载项来骗过它。另外从公司网上找到几个可以模拟TCP/UDP的Server/Client的小程序,很容易用,有这样的工具,就可以先调试其中的服务器端或客户端,等这样单独的调得差不多了,就可以进行联调。不然同时联调的话,出了错还不知道到底是哪边的问题。
posted @
2008-08-25 19:14 missdeer 阅读(15) |
评论 (0) |
编辑 收藏
发现机器上装的几个VS出问题了。6.0不说,因为压根没想过要用它。2003出问题似乎是最早的,大概是因为最早用得最多,就出问题也早,发现问题也早,现象是时不时弹出个消息框说什么GDIPLUS怎么出错了,而且一弹就会连续地弹好几次,让人受不了。2005本来还没怎么发现问题的,因为不常用,要用也是2003或2008,当时只是发现它的菜单怎么变中英文夹杂了,也没怎么在意,反正看得懂,最近一段时间想用它来创建个工程,发现这个 wizard不能用了,估计也是因为这本地化引起的,老是去不存在的目录下查找那些html文件!最后说2008,2008是今年开始用的,春节回家的时候用它来写WallpaperHelper,当时安装的时候也费了些力气,新建个MFC工程来编译,发现还缺几个.exe文件,抱着侥幸心理从2005那里照着文件名拷贝过来,发现勉强也能用,结果今年上半年堕落颓废了,看小说去了,几乎写过代码,现在发现2008里的资源编辑器不能用了,资源视图里都打不开资源,只是报个RC多少号的错,我也懒得再去查这是什么错了,反正这个资源文件是肯定没错的,郁闷死!
没耐心继续跟它们耗了,直接卸载,重装!
posted @
2008-08-24 11:12 missdeer 阅读(18) |
评论 (0) |
编辑 收藏
昨晚在整理硬盘上的电子书,顺便想到我零星收集的n多资料,一般就是一张网页,或者一个txt文件,里面可能是一篇文章,或者一小段代码,却很可能讲述了一个技术原理或一个小小的编程技巧,我没有计算过总共有多少个这样的文件,估摸着应该有几万个吧,这些只是平时上网,看到觉得有用才收藏下来的,不像那些电子书,很大一部分是去年从一个同事那里直接拿硬盘对拷过来,有些根本不是我关心的领域的,比如无线通信之类的。
这些文档散落在硬盘上,虽然我也大体上划分了一些分类,比如algorithme、crack等等,但当真要找某个比较细节的内容时,很可能要花很多时间,还不一定能找到。于是我就想,要是有一个适用于编程资料收集管理的工具就好了。我是懒得再去网上找了,先不说能不能找到真的完全符合我的要求的软件,即使有(这个可能性很小很小啊),也不一定是免费的。以前看过几个文档收集管理工具,要么是纯粹的通用工具,缺少对编程资料的倾向性适配,要么就是纯粹收集源代码的,又缺少对文字内容的支持。所以又回到原来我说过的一句话上来,最好用的软件是自己写的。
以前用BCB写过一个电子书管理的工具,花了些时间,但实际上并不好用,界面也其丑无比,太业余了,这是促使我后来义无反顾地投入VC阵营的重要原因之一,在像XTP、BCG之类的界面库帮助下,用MFC做界面其实并不比VCL麻烦,而且以我个人的经验看来,在同等工作量投入的情况下,反而更容易做出比较专业的界面来。又跑题了,那个电子书管理程序的功能太弱,虽然当时也想过不光要能管理电子书,还要能管理普通的文本资料,但后来由于对界面的极度不满意,直到完全失去了兴趣和信心,就放弃了。
现在想用MFC+XTP写一个,数据库就用SQLite好了,不光能管理文本资料,也能管理电子书,这是我比较希望的一种方式。管理文本资料时,需要特别关注,可能有两种不同类型的内容,一类是文字描述,一类是源代码,所以要同时有两个视图来表达一份资料的内容。资料的分类管理是必须的,而且更需要的是一种比较方便的搜索功能,不但要能搜索标题,还要能搜索内容。再有就是文本资料和电子书的管理要融合在一起,看起来没有特别明显的分界,但又留有余地可以完全分离开来。
这个工具不是通用目的的,是为程序员专用的,所以用户范围可能少了点,但这也算是围绕着我的整体规划目标了,developing for developers!
posted @
2008-08-23 10:14 missdeer 阅读(26) |
评论 (0) |
编辑 收藏
昨天就想把其中一段代码,一堆if...else比较字符串的代码替换成用gperf生成的hash来进行分派,但是昨天想了想我根本不会用gperf呀,晕死,于是想着回家上网找点资源。结果回到家还是什么都忘了,光顾着看小说和聊天了。
今天到公司里看到那段代码才想起来,昨天晚上堕落去了,于是有点儿沮丧。后来偶然发现,嘿嘿,在资料共享区有几篇关于gperf的文章,看来是我跟同事的唠叨发挥作用了。看了一下,发现它的输入格式虽然有点学了lex/yacc的样子,却比它们简单多了,而且我的需求也是非常简单,就是可能会有6种不同的字符串,我现在想让它能自动映射到一个枚举值。gperf的秉承了开源命令行软件的一贯作风,虽然只是那么小小一个功能,也提供了好几个命令行选项,幸亏有比较详细的中文说明,再加上功能实在不复杂,试了几次,就可以了。跟最新的flex/bison一样,我用了cygwin中版本号3.0.3的 gperf,它也支持输出C++代码,这是我比较喜欢的一点,毕竟C代码混在C++中还是感觉有点别扭的。
另外一点说不上技巧的小提示,如果对生成的hash函数不放心,可以写个单元测试用例,跑一遍就安心啦,而且这种hash函数一般的应用场合下不会有太多的映射关系,看人家ruby用在识别关键字上,也就是几十个而已,单元测试遍历一个所有的映射关系,写一遍就一劳永逸,不错不错,哈哈。
这个小工具值得推广,以后凡是遇到3个或以上字符串需要比较时,就可以考虑用gperf来做这种工作,不但代码运行效率高,而且代码可维护性也上去了,一举两得。
posted @
2008-07-29 19:28 missdeer 阅读(19) |
评论 (0) |
编辑 收藏
这几天看google reader上Codegear blogs一栏上,不时地贴出Tiburon这个词,开始还没留意,直到过了两天,目光稍作停留,才发现,原来是Delphi 2009/C++ Builder 2009的开发代号!上wikipedia查了一下Tiburon,似乎是一个加州小镇的名字,也不知是不是说的同一个。软件以地名作为开发代号的例子数不胜数,Borland系的产品更是如此。
这两年是Delphi/C++ Builder的多事之秋,先是从Borland分离出CodeGear子公司,出了个Codegear RAD Studio 2007,之后就是将整条IDE产品线以两千多万美金的跳楼价甩卖给Embarcadero,一代传奇,以这样的方式终结,让人唏嘘。
Tiburon最大的改进是对Unicode的支持,说是所有的都是基于Unicode实现的,包括编译器、RTL、VCL、IDE、COM、 dbExpress等等等等。我也不知道到底用户对这个特性的需求有多强烈,只是感觉这太晚了点,如果早5~8年就有这个特性,也许情况会好一些。除此之外,增加了一些新的VCL控件,不过说实话官方VCL控件的个数多少其实影响并不是太大,好多第三方控件库,各种酷炫的控件都有。另外还有些其他的改进之处,比如对Delphi语言的修改,使其支持泛型、匿名方法等,还有IDE的增强。比较炫的是C++ Builder集成了UML建模工具,可以使代码和UML模型同步,来回在两边编辑,这个特性我比较感兴趣,一定程度上说,Borland系不愧是最会做开发工具的。
然而,我现在已经不用C++ Builder了,转用VC一年多,也只是工作需要,以后会慢慢转向那些开源免费的开发工具上去,或者自己做。现在或许只是因为身上有那么一丁点自己也不太愿意承认的Borland情结,关注一下最新的发展动态罢了。
posted @
2008-07-19 09:19 missdeer 阅读(51) |
评论 (0) |
编辑 收藏
以前对这方面没有多少关注,只是偶然看到LuaEdit用了个叫madExcept的库,可以让Delphi程序在运行时如果崩溃了弹出个看起来比较牛的对话框,显示一些当前进程和当前系统的相关信息,并可以让用户选择是否将这份报告通过email发送回开发者。当时很好奇这是怎么做到的,很希望在自己的程序中也集成进这个功能,但很遗憾地发现,这个库只适用于Delphi,而我偏偏就不是用Delphi的。
后来,偶然,没错,以是偶然,看到公司网上有人说FileZilla有一部分这种代码,于是找来看了看,才大致了解了基本原理,并直接把这段代码抠出来用在了项目中,但到目前为了,这个功能虽然加进去了,却还没有发挥实际的功用。因为这段代码针对使用VC编译的程序会生成一个dump文件,该文件需要配合编译时的源代码以及编译器生成的pdb文件协同工作才会有实际用途,而我们的项目没有一个良好的机制把各个发布版本配套的源代码和pdb文件归档。
这些天看了《软件调试》,稍微了解了Windows的错误报告机制,觉得这是一种能很好改善用户体验,帮助开发团队改进软件的方法。
前段时间读Code::Blocks和CodeLite的源代码时,发现在Windows平台下编译时它们都动态装入了一个叫exchndl.dll的动态链接库,却只是装入,没做其他任何事情。根据代码注释中的只言片语,加上后来去down了Dr.mingw的源代码,发现这个dll就是做了捕获未处理异常,生成报告的工作。
于是,我就有了现在这个想法,也许这个想法就是微软的错误报告机制的简装版。首先,确定这套机制由三大部件协同完成:1、未处理异常捕获;2、反馈崩溃信息;3、分析处理崩溃信息。在具体实现时,可按这三部分分别处理,未处理异常捕获,就像exchndl.dll一样,只需要提供一个dll,应用程序只需要装入后,什么也不用管了;反馈崩溃信息,可以另外再写个客户端,将报告信息(文件)传送给服务器端;分析处理崩溃信息,也就放在服务器端了,可以自动作些简单的分析(像WinDBG那样的,配合对应的源代码和pdb,可以找到引起崩溃的代码行),根据这代码行,可以给用户显示个html页面,说明一下崩溃原因等等,当然这需要一定的人工介入,而且也是三部分中最复杂的。这些工作都可以通过微软提供的技术来实现,但还是有不小的工作量,比如像WinDBG那样结合pdb和源代码分析dump文件,这都是调试器的一部分功能了,另外再显示html页面,肯定是需要有先例通过人工编制一个页面。
而且这套机制似乎有个最大的不足,是只适用于VC编译的程序。也许其他的编译套件(Borland、DigitalMars、OpenWatcom、Intel……)也提供了类似的机制,但可能没有VC的完善,不需要人工分析即可定位到源代码行,这是何等方便啊!
posted @
2008-07-09 19:39 missdeer 阅读(35) |
评论 (0) |
编辑 收藏