librime-lua icon indicating copy to clipboard operation
librime-lua copied to clipboard

DbAccessor 不确定释放时机可能导致输入法崩溃

Open ksqsf opened this issue 1 year ago • 3 comments

DbAccessor 必须在 Db 本身被释放前释放。目前 Lua 中没有手动释放的接口,仅凭 GC 会由于不确定的释放顺序导致输入法崩溃。

related: #354

ksqsf avatar Nov 18 '24 01:11 ksqsf

我試着 產生 DbAccessor 後 ,關閉 leveldb 的確會崩潰 (TableDb 不會) 但是在lua_filter lua_translator 中使用應該不成問題 function init() 中開啓 userdb , function fini() 關閉userdb 在 function func() 中使用 DbAccessor 應該是可行的( func() 結束後 luaTransltion::~LuaTranslation() 會執行gc()

shewer avatar Nov 18 '24 07:11 shewer

我这里的用例是在 filter 中 query 然后产生一些新候选然后导致手机端崩溃。实际上一些崩溃日志正好显示是 luaTransltion::~LuaTranslation() 中的 gc 导致的。

情况大概可能是这样:

  1. 弹出输入框,初始化 rime 会话和 userdb。
  2. 关闭程序,关闭 rime 会话,调用 fini 关闭 userdb,但此时最后一个 DbAccessor 没有回收。
  3. 再次弹出输入框,重新初始化 userdb,此时按下第一个字,回收上一次 query 产生的 DbAccessor 导致崩溃。

我在 query 完毕后手动触发 collectgarbage 可以解决该问题,所以觉得应该是这个情况(暂时也没有完全搞明白)。

ksqsf avatar Nov 18 '24 09:11 ksqsf

有一个更简单的fix,只要在 db:close() 之前 collectgarbage() 一次就可以保证不崩溃,不需要在每次 query 之后 collectgarbage。

所以也可以让 db:close() 内置一个 collectgarbage() 把 DbAccessor 先关掉。这样不是很稳(有可能仍然持有 DbAccessor 引用),但是对于大部分正确使用 init fini 的组件(进入 fini 时已经失去所有 DbAccessor 引用)来说应该已经足够了。

所以修改了一下 issue 标题。

ksqsf avatar Nov 18 '24 10:11 ksqsf