IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [erlang]nif使用的一个注意事项

    庆亮发表于 2013-12-03 02:47:54
    love 0

    一、前提说明
    1. 项目本身为了简单,将所有的beam文件最终都部署在同一个ebin目录下(无层次结构),包括第三方deps,目录结构如下:

    mservice_code_struct

    2. deps中使用到了esqlite这个开源库(esqlite),这是个基于nif的erlang sqlite

    二、问题说明
    在我给esqlite添加热更新支持之后,遇到个问题:

    strace:[{esqlite3_nif,prepare,
    [<
    >,#Ref,,"select * from t_job"],
    []},
    {esqlite3,prepare,3,[{file,"src/esqlite3.erl"},{line,229}]},
    {esqlite3,q,3,[{file,"src/esqlite3.erl"},{line,75}]},

    跟踪时发现在reload时nif的两个static resource指针被重置了,这两个resource初始化代码如下:

    static ErlNifResourceType *esqlite_connection_type = NULL;
    static ErlNifResourceType *esqlite_statement_type = NULL;
    
    rt = enif_open_resource_type(env, "esqlite3_nif", "esqlite_connection_type",
    destruct_esqlite_connection, ERL_NIF_RT_CREATE, NULL);
    if(!rt)
    return -1;
    esqlite_connection_type = rt;
    
    rt = enif_open_resource_type(env, "esqlite3_nif", "esqlite_statement_type",
    destruct_esqlite_statement, ERL_NIF_RT_CREATE, NULL);
    if(!rt)
    return -1;
    esqlite_statement_type = rt;
    

    整个工程中没有任何地方显示的释放了以上两个resource,而nif的机制似乎也没有相关的说明。顺手抓了vmmap看了看,发现个异常情况:
    esqlite_nif_load_twice

    看样子,nif在reload时重新加载了另外一个同名so,问题是为什么code path中有重复的内容出现?看了看代码中引导的deps,想起来mochiweb是有这样的机制的:自动解决依赖目录,实现在 mochiapp_deps.erl(这是个mochiweb的代码模板文件),至此问题就好解决了,简单屏蔽掉mochiweb的这个机制即可。



沪ICP备19023445号-2号
友情链接