您的位置:首页 > 编程语言 > Lua

lua调用C++函数崩溃时,查看lua的调用栈信息 (特别适用于tolua++)

2014-05-25 12:51 579 查看
cocos2d-x这个开源引擎目前在移动开发领域挺火,我用了一阵子,非常喜欢它的lua绑定,一旦理解了其工作机制,用起来相比C++有不同的感受。

但是想要用好lua脚本,实在不是件容易的事情。要让lua绑定变得非常好用,可能依然需要大量工作。

这里记录一个很实用的技巧:在lua调用cocos2d-x的接口而导致崩溃时,无法直接看到lua的调用栈,也就无法知道目前正运行到lua脚本的哪一行。此时可以考虑如下方法:

就以cocos2d-x 2.0的HelloLua为例,假设lua脚本在执行addChild时崩溃:

文件:hello.lua

[java] view
plaincopy

-- create farm

local function createLayerFarm()

local layerFarm = CCLayer:create()

print(debug.traceback())

-- add in farm background

local bg = CCSprite:create("farm.jpg")

bg:setPosition(winSize.width / 2 + 80, winSize.height / 2)

layerFarm:release() --故意将layerFarm释放,导致调用addChild时C++层异常

layerFarm:addChild(bg)

........

这样,在执行到addChild时,程序最终会因为空指针崩溃,具体是在tolua++生成的这个函数TOLUA_DISABLE_tolua_Cocos2d_CCNode_addChild00:

[cpp] view
plaincopy

/* method: addChild of class CCNode */

#ifndef TOLUA_DISABLE_tolua_Cocos2d_CCNode_addChild00

static int tolua_Cocos2d_CCNode_addChild00(lua_State* tolua_S)

{

#ifndef TOLUA_RELEASE

tolua_Error tolua_err;

if (

!tolua_isusertype(tolua_S,1,"CCNode",0,&tolua_err) ||

!tolua_isusertype(tolua_S,2,"CCNode",0,&tolua_err) ||

!tolua_isnoobj(tolua_S,3,&tolua_err)

)

goto tolua_lerror;

else

#endif

{

CCNode* self = (CCNode*) tolua_tousertype(tolua_S,1,0);

CCNode* child = ((CCNode*) tolua_tousertype(tolua_S,2,0));

#ifndef TOLUA_RELEASE

if (!self) tolua_error(tolua_S,"invalid 'self' in function 'addChild'", NULL);

#endif

{

// 打印lua调用栈开始

lua_getglobal(tolua_S, "debug");

lua_getfield(tolua_S, -1, "traceback");

int iError = lua_pcall( tolua_S, //VMachine

0, //Argument Count

1, //Return Value Count

0 );

const char* sz = lua_tostring(tolua_S, -1);

// 上面的sz里面即为lua的调用栈信息,好好利用吧!

self->addChild(child);

}

}

return 0;

#ifndef TOLUA_RELEASE

tolua_lerror:

tolua_error(tolua_S,"#ferror in function 'addChild'.",&tolua_err);

return 0;

#endif

}

#endif //#ifndef TOLUA_DISABLE

如上面代码中的注释部分所示,具体就不说了。原理就是两点:

1、lua执行时,随时都可以调用 debug.traceback() 获得描述调用栈的字符串。

2、如上例,在C语言中调用debug.traceback 即可。C语言调用lua函数的方法属于lua基础内容,就不罗嗦了。
http://blog.csdn.net/mayao11/article/details/8267503
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: