搞定源代码断点
今天主要搞定了源代码断点,之前遇到的如果有断点,debuggee启动就会崩溃的问题,其实是通过socket发送命令过去后,debuggee在接收时会把不完整的信息压入到队列中,跟昨天遇到的回应消息不完整是一个道理。
最后我仍然是采用了完全使用debug库的功能实现的方式,这种方式的缺点是调试执行的效率很低,因为每次debug库回调时,都要判断一下是否在当前行有断点。至于之前我想过的那种快速断点的方案,就留到以后版本中实现吧!
今天主要搞定了源代码断点,之前遇到的如果有断点,debuggee启动就会崩溃的问题,其实是通过socket发送命令过去后,debuggee在接收时会把不完整的信息压入到队列中,跟昨天遇到的回应消息不完整是一个道理。
最后我仍然是采用了完全使用debug库的功能实现的方式,这种方式的缺点是调试执行的效率很低,因为每次debug库回调时,都要判断一下是否在当前行有断点。至于之前我想过的那种快速断点的方案,就留到以后版本中实现吧!
今天可算是最近两个月来状态最好一天了,修正了一堆问题,以至于调试器工作得像样起来了,剩下只要完成源代码断点的功能,就接近可发布的状态了!
这里简单记一下这些已解决的问题。
一开始,是有各种奇怪的问题的,比如在Lua扩展中解析XML格式的回应信息时,会报invalid node,有时候又会报call stack节点不存在,有时候在VS的调试器中运行时,会在分配内存的时候异常。这些问题,最终的原因可能是相同的。我的设计是另有一个工作线程通过socket在与debuggee进程通信,它会接收debuggee进程发回来的回应消息,并把这些回应消息压入一个队列中。而界面线程,会在应用程序消息空闲时,从该队列中撮回应消息,并转发给Lua扩展进行处理。这时我犯了一个错误,我会把一个可能不完整的消息结构体压入队列中,而界面线程取出处理时,并不能检测出是否内容完整。而且,我还是通过动态堆分配来存储这些额外信息,在界面线程中又会去释放这块内存,于是工作线程很可能去读写一块已经无效的内存。
另一个问题是,debuggee有时候会启动即崩溃,通过打印的调试信息显示,是boost::shared_ptr的使用有问题。我仔细检查了代码,发现只有两个boost::shared_ptr,还发现,其中有一个是不必要的,那是一个放在线程函数中的临时对象,生命周期只在该线程函数中有效,所以换成栈上创建就可以了。这样一来,后来经过几次测试,也确实没再出现崩溃。
还有问题是,只能调试一次,再启动debuggee就自动退出了,还有调试的时候用户手动停止调试,debugger会崩溃。其实这是没有仔细划分好各模块的职责,没有仔细设计各模块交互的协议。后来总结发现,如果debuggee要退出,分两种情况,即自动运行完退出和手动强制退出,无论哪种退出,都给Lua扩展发送一个通知,然后Lua扩展把调试端口(socket通信)停掉,而这个通知如果debuggee有能力发(手动强制退出),就让debuggee发,如果没能力(自动运行完),就让debugger发。而手动强制退出,则是只要向debuggee发送个退出命令就可以了。
今天心情真舒畅啊!
这两天整调试器,经过不怎样的努力,到现在为止,功能上基本算是具备了,不过就是剩下些bug,主要有:
从debuggee发送过来的信息有时候经过XML解析会出错。
从debuggee发送过来的信息,有时候没有调用栈信息。
断点工作不正常。
有时候刚启动debuggee,debuggee就崩溃。
明后天就集中精力修改这些问题了,哈哈!
前次说到,我觉得我把wxScintilla的代码合得有问题了,我的程序中使用了wxScintilla不能多选。其实是我毛躁了,没认真看Scintilla的文档。其实当时我也是浏览了一遍代码的,发现在wxScintilla中处理用户输入后,就直接转发到Scintilla的平台无关的代码中去了,而这部分平台无关代码我基本是严格复制了官方Scintilla的代码,所以照理是应该没问题的。昨天在整理《Free Software Collection》一文时,考虑到用什么软件来替代UltraEdit,结果发现SciTE的列编辑模式已经可以做得跟UltraEdit很接近了,看了看修改版的SciTE-Ru,也同样如此。当时我还有点怀疑是不是需要在容器应用程序中做单独的处理,想想又有点不太可能。看了一下SciTE-Ru的配置文件,发现是有这么个选项的,后来就去看Scintilla的文档了,看到在Multiple Selection & Virtual Space一节里,确实有相应的设置选项。
土了啊,代码合得没问题,哈哈!
我是突然发现,原来我患的是这个病:成功恐惧症!在《反模式》中看到,原来我这样的病症并不唯一,很多人都会有,以至于他们都把它写到书中去了!
说到底,还是出于不够自信,以及毅力缺乏。古时候有句话,叫“行百里者半九十”,其中有一层含义就是最后那10%的工作是最难完成的,不光是因为可能工作内容的难度增加,还有执行者心理上的障碍,就像我这样。
一直以来,我都是一个缺乏毅力的人,很少会从头到尾认认真真地完成一件事情。不论是工作,还是其他生活中的琐碎的小事,比如看书,总是会把最后一部分丢掉。以前有领导说我,做事情总是喜欢只做到90分,而不去追求那完美的100,我不以为然,我是有点小骄傲的,有点自以为是的,这种关键部分有技术难度的部分完成了么,剩下的修修补补让别人去做好了!
现在不行了,所有的事情都得亲历亲为了,这个毛病带来的隐患就爆发了,将将引起严重后果了。记得类似的严重情况在公司时有过一次,那是我第一次独立负责一个特性,不但要完成自己的功能,还得提供接口给其他人使用,到了最后那段时间,心里非常焦虑,极度没信心,到后来都是只敢埋头写代码,不敢调试运行,生怕调试不过,把自己打击得再无法拾起从头来过的勇气了。最后运气很不错,因为本来也只是简单地调用别人的接口,我自己的特性完成后,提供给别人的接口基本功能也是能保障的。
眼下我那个调试器部分,已经持续2个月了吧,一直没有正常的进展,实在是挑战我的心理承受能力。我只能强行扭转自己的心理喜好习惯,自我灌输些心理暗示,希望能顺利度过这一关吧!