调bug时看了一点Lua源码

调一个bug,lua中c++返回的字符串问题,该问题只在运行时出现,调试时不会出现,开始觉得很奇怪,还好现在用vs2003可以Attach Process。

 

一路跟踪代码tolua_pushstring->lua_pushstring->lua_pushlstring->luaS_newlstr->luaM_malloc(luaM_realloc_)->(*g->frealloc)->l_allocrealloc

->_realloc_base->_malloc_base->_nh_malloc_base->_heap_alloc_base->HeapAlloc

从lua跟到c++分配内存,顺便复习了一遍以前听过候捷老师的一次关于c++内存分配的讲座。

监视tolua_pushstring中的字符串地址,最后发现在分配内存时该地址被清空了。

 

原来是由于一个函数TYPE &info = Date.Getinfo()本应用引用而漏写了&符号,导致一个局部变量的字符串指针域被返回,重新分配内存时被覆盖。

回想起来,问题调试时不出现,只在在运行时出现可能是因为调试器的内存分配策略不同,调试时比较松散没有覆盖到原来的无效内存,而运行时分配比较集中?


开始以为是luaS_newlstr函数有问题,花了些时间看了下

TString *luaS_newlstr (lua_State *L, const char *str, size_t l)

--[[引用

在luaS_newlstr中会先计算字符串的hash值,然后遍历stringtable这个全局hash表,如果查找到对应的字符串就返回ts,否则调用newlstr重新生成一个。
而 newlstr则就是新建一个tsring然后给相应位赋值,然后计算hash值插入到全局的global_State的stringtable中。然后 每次都会比较nuse和size的大小,如果大于size则说明碰撞太严重,因此增加桶的大小。这里增加每次都是2的倍数增加。

--]]

 

同时了解了TString结构,

从TString取出char*的方法:

TString *ts = luaS_newlstr(L, s, len);

szStr =svalue(ts->tsv);

--等价于    szStr = (const char *)(&(luaS_newlstr(L, s, len)->tsv)+1);

#define rawtsvalue(o)    check_exp(ttisstring(o), &(o)->value.gc->ts)

#define tsvalue(o)    (&rawtsvalue(o)->tsv)

#define getstr(ts)    cast(const char *, (ts) + 1)
#define svalue(o)       getstr(tsvalue(o))



调试中还遇到了传送中古老的C语言问题,不知vs2003编译c用的什么c标准,函数中变量都要求在函数开始时声明,否则一直编译不过提示“未声明的标识符”,这个查了好久才搞定。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值