All Stories
如果胆子足够在,这两个网站上的都是值得试一下的,其中不乏一些好东西,比如日志库就有两个,一个叫Boost.Logging,一个叫Boost.Log。 https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction http://www.boostpro.com/vault/ 对于进入boost的侯选库,有两个存放点,一个就是上面第2个地址vault,还有一个是boost svn中的sandbox目录。从Review Schedule中看来,似乎进入Review的库从vault中来得多一点,而sandbox又有点像boost正式库的一个draft。
这两天在抽空分析程序的崩溃记录,这些记录都按照版本号分别放在不同的文件夹中。早先exe文件的版本号并没有严格对应于svn revision号,周一时用一个修改PE资源的小程序搞定了这个事情,以后做这方面的事可要精确和省神多了。 今天分析到一个记录,印象中以前也有过类似的记录,一时没想起来,发现是一个线程函数数,对一个std::map调用find方法,结果在STL内部引起崩溃了。开始的时候,还以为是调用find方法时传入的参数有问题,引发了STL的某个未定义行为。于是另外写了个小程序简单验证了一下自己的猜想,结果不如自己所料。后来猜测要引用这个map的对象时,包含它的指针已经无效了。但为什么无效,我却也得不出什么结论。最后突然想到,从崩溃记录分析得到的最后堆栈信息中,看到是调用find方法后,find方法中取xtree的根节点引起的崩溃,那么是不是这个map对象本身就是有问题的了呢?灵光一闪,这个map对象是做为一个类的成员的,如果这个类的实例被销毁了,这个map对象自然也跟着被销毁,而这时如果再试图访问它,当然会有问题。 分析出来具体的原因,修改起来就比较容易了,在该类的实例被销毁时,应该通知那个线程马上结束,而且不要再试图去访问那些它的成员了。在修改这块代码的过程中,我应用了boost::thread,这大大简化和缩减了需要编写的代码。
什么Boost.DirectX啊,Boost.Debug啊,Boost.Cppgui啊,越来越疯狂了哦!
今天一个同事突然发邮件来说我的升级程序在生成文件列表时,给数字都以3个数字一段都加上了逗号,我狂晕!拿自己的debug代码试了试,发现果然如同事所言,看来是确定代码写得有问题了! 单步跟踪,最后发现我在把数字转换成字符串时,用了std::stringstream类的流输入方法,就变成那种样子了,稍微想了一下就明白过来了,以前一直都是没有逗号的,后来有过修改的地方也就是当时用ofstream写文件时,为了能支持中文的路径和文件名,在程序启动时调用了一句std::locale::global(std::locale(""));后来就有了这个问题。我狂分特啊,跟另外一个同事分享这个经验时,他还问我为什么不用boost::lexical_cast呢,其实据说boost::lexical_cast内部也是用的std::stringstream来转换的,哈哈!
说什么无法控制,说什么循环引用,说什么编译时间,都他妈的傻x。怎么不去关心一下CPU能不能控制,Windows能不能控制,还不是他妈的那儿老老实实用着。怎么不去用一下汇编,Fortran,狗日的哪来的循环引用。怎么不去用Debug自己输入二进制码,哪来的编译时间。 莫装B,装B被雷劈!
今天写代码,出了不少错,都是很低级的,状态不好啊。 先是连接一个MySQL数据库,从一个表中Select一些记录出来,死活没数据,还以为是SQL语句有问题,用其他客户端去运行,发现SQL语句是正常的。然后换了一条SQL语句,同样是Select的,发现又可以了,一步一步排查,发现是那个表中查不到数据,另外一个表中查得到数据,突然发现原来我连的MySQL地址不是我想要的那个! 接着是从XML格式的配置文件中读取配置信息,发现有的配置项好像怎么都读不出来,一直都是使用默认的值,后来才发现在判断值是否为空的时候,多写了个感叹号! 好不容易磕磕碰碰地调试通过了,编译了一个Release版本,用Inno Setup打了个包,放到目标机器上去运行,发现居然没反应,而且不巧的是我什么调试手段都没有,也没有什么日志。后来通过MessageBox发现,似乎配置信息读取又有问题了。然后发现如果是直接用Debug版本是正常的,于是想调试一下Release的,结果不知道应该设置什么选项,调试不了!只好通过OutputDebugString来打些信息出来。经过一番搏斗,发现原来我把装载配置文件的那条语句外面套了一个ASSERT,我狂晕! 以我现在的水平,状态好的时候,最多一个月也就能产1w行代码,而且代码质量还不能保证,唉,怎么才能让新写的代码跑得稳定呢!
今天在Boost的邮件列表里看到有人在项目中使用Logging v2,这是在去年3月时提交Boost后review拒绝的一个库,当时我也略微关心过,因为一直在找一个好用的C++日志库,最后看到被拒绝了,我也就有点死心了,用起log4cxx来,其实发现log4cxx也不是那么好用,而且最近公司里用的时候发现似乎会有内存泄漏的问题。 看到邮件列表里那人对Logging的评价很高,我就心动了,它有一个优点是header only,这是我很喜欢的一点。其他的灵活性之类的我也没用过,也不好评价。不过我决定了,先在自己写的这些程序中试用一下。
啊,非SHFileOperation莫属!今天要实现个文件夹复制的特性,于是就想到这个API,可是很不幸,无论我怎么整,都报个1026错误!从网上找了一圈,发现代码根本一模一样的,人品问题啊! 后来在花费了不知道多少时间后,也许是1小时,也许更多,等不及了,花了10分钟自己用递归写了个函数来实现文件夹复制,我吐血三升!
回到家,习惯性地更新了一下boost svn中的代码,从来都最多只看一下哪些文件更新了,至于具体更新了什么内容,却从来没有关心过,也不是我能关心的。 然后整了一下自己写的一些代码。 再之后是继续整前几天放假时写的一个小程序,结果突然发现编译不过了!开始还怀疑该不会是VC出问题了吧,重启了一下VC,没用!于是看了一眼出错信息,定位到出错代码行,是boost::signals2中的一个叫signal_template.hpp的文件中。众所周知boost的代码只有超人才能看得懂,而我很幸运地不是超人,所以就看不懂啦!折腾了一阵,也没有办法,后来猛然看到这代码中明显是语法错误嘛!我猛烈地faint啊,原来超人也会犯错儿呀!尝试了一下把这语法错误修正,结果编译时报的是其他地方的错了,这我就不晓得是什么原因了。无奈之下,为了能正常编译我的程序,只好回退到之前一次提交的内容去了! 目瞪口呆!