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

        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",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.youkuaiyun.com/mayao11/article/details/8267503
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值