加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-14 22:18:16 所属栏目:大数据 来源:网络整理
导读:? ? ? ? cocos2d-x这个开源引擎目前在移动开发领域挺火,我用了一阵子,非常喜欢它的lua绑定,一旦理解了其工作机制,用起来相比C++有不同的感受。 ? ? ? ? 但是想要用好lua脚本,实在不是件容易的事情。要让lua绑定变得非常好用,可能依然需要大量工作。 ?

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

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


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


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

文件:hello.lua

-- 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:

/* 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",&tolua_err) ||
     !tolua_isusertype(tolua_S,2,&tolua_err) ||
     !tolua_isnoobj(tolua_S,3,&tolua_err)
 )
  goto tolua_lerror;
 else
#endif
 {
  CCNode* self = (CCNode*)  tolua_tousertype(tolua_S,0);
  CCNode* child = ((CCNode*)  tolua_tousertype(tolua_S,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基础内容,就不罗嗦了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读