調bug時看了一點Lua原始碼

2021-05-22 18:29:55 字數 1471 閱讀 6513

調乙個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標準,函式中變數都要求在函式開始時宣告,否則一直編譯不過提示「未宣告的識別符號」,這個查了好久才搞定。

ThreadLocal原始碼解析及一點思考

看乙個案例 public static void main string args other thread thread.start 輸出 main other threadthreadlocal的作用顯而易見 某變數是執行緒共享變數,但某執行緒下對其的操作僅對該執行緒可見 看下threadloc...

Discuz原始碼的一點心得

今天同事參照discuz的框架做乙個小東西,框架搭的差不多時,提到其中有乙個地方不太明白 在discuz.web中沒有新增discuz.data.sqlserver的引用,如圖 但執行時沒有任何問題,而他的框架中不新增dll引用,會導致執行失敗丟擲異常 編譯都通過 我簡單看了下discuz的原始碼 ...

nDPI原始碼的一點分析

ndpi是開源的深度包檢測庫,更詳細的介紹,請參考ndpi 官網 每種應用層協議的檢測的流程 ndpi detection process packet check ndpi flow func check ndpi tcp flow func check ndpi udp flow func或ch...