调用 FFI 出现 "table overflow"

Question:

  1. 首先安装 uuid 模块(ubuntu/debian请安装:sudo apt-get install uuid uuid-dev 两个模块)
  2. FFI 调用,代码示例:
local ffi = require 'ffi'

ffi.cdef[[
typedef unsigned char uuid_t[16];
void uuid_generate(uuid_t out);
void uuid_unparse(const uuid_t uu, char *out);
]]

local uuid = ffi.load('libuuid')

if uuid then
    local uuid_t   = ffi.new("uuid_t")
    local uuid_out = ffi.new("char[64]")
    uuid.uuid_generate(uuid_t)
    uuid.uuid_unparse(uuid_t, uuid_out)
    result = ffi.string(uuid_out)
    print(result)
end

当使用这个的时候刚开始不会出现错误,但是运行一段时间后就会出现 table overflow, 第二天早上回来看到的,请问遇到过这样的情况么?

Answer:

貌似这里每请求都调用 ffi.cdef?建议把 ngx_ffi.lua 实现为一个真正的 Lua 模块,这样就可以享受只加载一次的好处:

http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker

你遇见的 table overflow 的错误很容易通过下面这个独立的 Lua 脚本复现:

-- test.lua
local ffi = require "ffi"
while true do
    ffi.cdef[[
    typedef struct { void* ev_ptr; void* char_ptr; } bif_result;
    ]]
end

命令行上的执行结果如下:

$ /usr/local/openresty/luajit/bin/luajit-2.0.0-beta10 test.lua
/usr/local/openresty/luajit/bin/luajit-2.0.0-beta10: table overflow
stack traceback:
        [C]: in function 'cdef'
        a.lua:6: in main chunk
        [C]: ?

所以只要把 ffi.cdef 移出循环就不会溢出了。(而在你的场景中,则是把 ffi.cdef 调用移进 Lua 模块加载代码。)

可以参考一下 lua-resty-string 库中的 resty.md5 模块的实现:

https://github.com/agentzh/lua-resty-string/blob/master/lib/resty/md5.lua

根据下面链接完成整理

https://groups.google.com/forum/#!topic/openresty/zGxwOqUN4fc

results matching ""

    No results matching ""