Monday, January 5, 2009

努力用最佳方法解决问题

最近用Luabind封装Boost asio相关内容的时候,总是遇到堆错误!


头痛不已。


后来发现,这个错误源于一个小小的笔误,加上luabind没有处理表中没有域的异常,导致程序在出错后,悄无声息的继续运行。


最后,堆被破坏。但是现场已经不在。差错很困难。


得到两点教训:


1)出错立即崩溃,绝不吃掉错误。尤其是基础库,更加要注意这个“速错”原则!(就本次BUG而言,是Luabind的问题,已提交BUG。“速错”,切记!!!!!!!!!!!!!)


2)用最佳实践编程,不要不恰当地使用惯用法在不合适的地方。比如,不用用C++去实现upvalue,用lua的就好了。(如果我开始就用这个方法,也不会遇到这个错误)





下面,详细介绍下问题:

如果,已绑定如下类:


class luatimer


{


public:

void handle_timeout()


{


...






on_timeout_( this, "timeout" );// this的用法不好,浪费CPU时间,同时没有利用lua的upvalue能力


...


}






    luabind::object on_timeout_;//回调函数,







}


lua部分:


...



local function f( t, e )


                local t={}--这里是一个笔误,t覆盖了参数t的作用域



...


t:start(f,1000) --start timer  --这里当然找不到start域,但是luabind并不报错,而是死在很难看的地方,也就是说,指针跑飞了,加上是模板代码,基本没办法定位


end






版本2:









 void handle_timeout()


{


...

on_timeout_( "timeout" );// 没有了this, 捕获上下文的责任交给Lua


...


}











local function f(e)


local self = t1-- hold a ref to timer t1 -- 用lua的upvalue替代C++,高效美观,名字按照约定,不容易搞混


local tt={'hi~'}


self:start(f,1000) --start timer


end



No comments: