Lua使用os.date函數也要小心

前段時間,在給我們遊戲服務器寫lua的腳本的時候,發現了一個奇怪的現象,一段lua代碼只要一執行就把服務器給搞掛了,仔細分析了一下,發現這段lua代碼並沒有執行什麼特別的操作,甚至都沒有跟我們服務器的C++層交互,僅僅只是使用lua自身的一些庫函數,而且只對windows平臺下的服務端會產生這個崩潰。初步認爲是windows平臺的原因。於是我在windows平臺下編譯了lua的源碼,跟進去後發現原來是宕在了windows的CRT函數裏,解釋一下CRT是windows的C運行時庫,如果有朋友不清楚,可以看看《程序員自我修養》這本書中關於運行時庫的章節,正好網上給出的示例章節就是這有這一章,可以看這裏:http://book.51cto.com/art/200904/120986.htm

接着說我的問題,宕在了一次調用lua內置的os庫的date()函數,調用如下:

os.date("%C")

跟進lua源碼後發現,源碼裏最後調用了C庫的strftime函數:

wKioL1NGEwagdDUeAAIB-KSz6Rs123.jpg


打開,因爲我們的服務端編的都是debug版本,vs編debug版默認使用的多線程的那個debug版本的庫:

wKiom1NGE7vCKAf2AAGcj0DjXhA542.jpg


打開源碼找到對應的 strftime 函數,然後一路跟進去,最後終於找到了罪魁禍首!尼瑪居然有一行 ASSERT!

wKioL1NGFTjCdcz2AACDetC1xO0975.jpg


wKiom1NGFWLR78UTAAENqvyPvY0744.jpg


wKioL1NGFTqB5hGWAADWSU0zmYQ909.jpg


wKioL1NGFTvh5QwBAAGS5yYMyCI589.jpg


最後就因爲這個ASSERT,我們的服務端光榮的掛了,而且我們外網的服務端就用的是debug版本,不過幸好 glibc 的庫下不存在這個問題。


既然都看到這裏了,我就順帶對比了一下,vs這個版本的CRT庫裏strftime能夠支持的字符和標準有什麼區別:

CRT能夠支持的字符有:aAbBcdHIjmMpSUwWxXyYZz%'\004''\015'

而最新的c和c++可以支持的果然更多,可以在cplusplus.com對比一下:http://www.cplusplus.com/reference/ctime/strftime/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章