You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
During its normal operation, a string buffer uses a variable number of stack slots. So, while using a buffer, you cannot assume that you know where the top of the stack is.
一般的操作过程中,字符串缓存会使用不定量的栈槽。 因此,在使用缓存中,你不能假定目前栈顶在哪。 在对缓存操作的函数调用间,你都可以使用栈,只需要保证栈平衡即可; 即,在你做一次缓存操作调用时,当时的栈位置和上次调用缓存操作后的位置相同。 (对于 luaL_addvalue 是个唯一的例外。) 在调用完 luaL_pushresult 后, 栈会恢复到缓存初始化时的位置上,并在顶部压入最终的字符串。
最近在写一个 Lua 库,用于打印报错堆栈上的函数参数和 upvalue,最开始用 Lua 实现了一个版本,运行效果还可以。想着用 C 来实现一遍,经过一段时间的奋战,终于能跑了。
运行效果展示
测试代码:
运行效果大概是这样的:
遇到问题
但是会偶然的出现 core dumped 。由于是偶现的, gdb 好像也不好调试,就只能加打印,批量重试了。
写个脚本批量运行,把 core 文件和日志文件对应起来。
遇到报错就停下来。
然后也借助 gdb 来查看 core 文件,发现 gdb 竟然有个 TUI 界面。使用
tui enable
开启 TUI 界面,界面是会自动显示当前代码文件的,按方向键上下滚动代码。![[Pasted image 20230211143947.png]]
使用
up/down
切换堆栈层级,代码会跟着切换。排除法定位问题
怀疑是 lua_Buffer 的问题,注释部分代码试试看。怀疑 luaL_tolstring 函数会影响,先修改不调用这个函数。
怀疑 lua_Buffer 的问题,可以把 lua_Buffer 注释掉,只打印序列化出的数据,或者用其他方法来存储序列化后的数据。怀疑 lua_Buffer 的原因是调试的时候发现 lua_pushvalue 经常会把 buffer 的数据弄成乱码,可能是
_ENV
里有特殊字符。通过注释 lua_Buffer 相关代码,目前跑了一天还没遇到过报错。
或许是不是不能同时使用 2 个 buffer 呢?可以研究一下 lua_Buffer 的代码。
通过排除法,已经定位到是 Buffer 的问题,具体是加了什么特殊字符问题引起的还没定位到。特殊字符可能是
_ENV
里的。再使用排除法,只保留
已经重现到。
再试试只序列化 ENV 的情况,不处理堆栈的情况。终于知道原因了,原来几年前就遇到过。
hanxi/lua-seri#1
终于理解这句话的意思了,就是每次操作 buffer 前后,需要保持栈不变。所以解决方法也就是 issues 里提出的 2 个,自己实现一个 buffer 或者把数据缓存到一个表里,最后才使用 buffer 合并。甚至包括 luaL_bufferinit ,这也就说明,必须保证 buffer 在栈顶了。因为无法使用此办法来序列化了。
还特意去 Lua 邮件列表里问了这个 buffer 的用法:
http://lua-users.org/lists/lua-l/2023-02/msg00082.html
最终的解决办法是使用
luaL_buffinitsize
申请一段固定长度的 buffer, 采用memcpy
写入数据。最终成果: https://github.com/hanxi/ltraceback
顺便把之前写的一个序列化 lua 数据的库的 bug 修复好了。
https://github.com/hanxi/lua-seri
The text was updated successfully, but these errors were encountered: