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


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

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


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


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

    文件:hello.lua

    [java] view plaincopy
    1. -- create farm  
    2. local function createLayerFarm()  
    3.     local layerFarm = CCLayer:create()  
    4.     print(debug.traceback())  
    5.   
    6.     -- add in farm background  
    7.     local bg = CCSprite:create("farm.jpg")  
    8.     bg:setPosition(winSize.width / 2 + 80, winSize.height / 2)  
    9.     layerFarm:release()    --故意将layerFarm释放,导致调用addChild时C++层异常  
    10.     layerFarm:addChild(bg)  
    11.     ........  

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

    1. /* method: addChild of class  CCNode */  
    2. #ifndef TOLUA_DISABLE_tolua_Cocos2d_CCNode_addChild00  
    3. static int tolua_Cocos2d_CCNode_addChild00(lua_State* tolua_S)  
    4. {  
    5. #ifndef TOLUA_RELEASE  
    6.  tolua_Error tolua_err;  
    7.  if (  
    8.      !tolua_isusertype(tolua_S,1,"CCNode",0,&tolua_err) ||  
    9.      !tolua_isusertype(tolua_S,2,"CCNode",0,&tolua_err) ||  
    10.      !tolua_isnoobj(tolua_S,3,&tolua_err)  
    11.  )  
    12.   goto tolua_lerror;  
    13.  else  
    14. #endif  
    15.  {  
    16.   CCNode* self = (CCNode*)  tolua_tousertype(tolua_S,1,0);  
    17.   CCNode* child = ((CCNode*)  tolua_tousertype(tolua_S,2,0));  
    18. #ifndef TOLUA_RELEASE  
    19.   if (!self) tolua_error(tolua_S,"invalid 'self' in function 'addChild'", NULL);  
    20. #endif  
    21.   {  
    22.           // 打印lua调用栈开始  
    23.       lua_getglobal(tolua_S, "debug");  
    24.       lua_getfield(tolua_S, -1, "traceback");  
    25.       int iError = lua_pcall( tolua_S,    //VMachine    
    26.                     0,    //Argument Count    
    27.                     1,    //Return Value Count    
    28.                     0 );   
    29.       const char* sz = lua_tostring(tolua_S, -1);  
    30.     // 上面的sz里面即为lua的调用栈信息,好好利用吧!  
    31.    self->addChild(child);  
    32.   }  
    33.  }  
    34.  return 0;  
    35. #ifndef TOLUA_RELEASE  
    36.  tolua_lerror:  
    37.  tolua_error(tolua_S,"#ferror in function 'addChild'.",&tolua_err);  
    38.  return 0;  
    39. #endif  
    40. }  
    41. #endif //#ifndef TOLUA_DISABLE  


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

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

    2、如上例,在C语言中调用debug.traceback 即可。C语言调用lua函数的方法属于lua基础内容,就不罗嗦了。

    http://blog.csdn.net/mayao11/article/details/8267503

  • 相关阅读:
    .NET开发工具
    二维图形的比例变换
    Java对十六进制文件读取
    ??Get Personal SPWeb Object(Mysite Object)获取MOSS个人站点的SPWeb对象
    ?使用SPSiteDataQuery和SPQuery查询不到数据
    moss和exchange 2007的sso
    [解决办法]正在尝试使用已关闭或释放并且不再有效的 SPWeb 对象
    MOSS的用户配置文件及其管理
    Moss要是有两个域用户在用的话.及界面修改 moss2010界面改成2007
    WebForm_PostBackOptions 未定义
  • 原文地址:https://www.cnblogs.com/byfei/p/6389791.html
Copyright © 2020-2023  润新知