关注LAMP|PHP源代码分析|web架构|PHP扩展|Erlang|服务端架构

erlang zlib引起的系统崩溃记录

2010-08-11

原创文章,转载请注明: 转载自庆亮的博客-webgame架构

本文链接地址: erlang zlib引起的系统崩溃记录

author: 庆亮 (qing.liang.cn@gmail.com /  http://twitter.com/qingliangcn )

date: 2010-07-12

 

之前同事遇到一个问题,系统运行一段时间后有大量的port没有正常关闭而导致beam崩溃,经过定位发现是由于zlib引起的。过程很简单,没什么技术含量,记录一下。

错误信息大致是这样的(原因是传入的数据不是zlib压缩格式):

** exception error: data_error

     in function  zlib:call/3

     in call from zlib:inflate/2

     in call from zlib:uncompress/1

call的实现,应该是这里,erlang:error(list_to_atom(Res))

 

看了下zlib的解压源码:

-spec uncompress(binary()) -> binary().
uncompress(Binary) when byte_size(Binary) >= 8 ->
   
Z = open(),
    inflateInit(
Z),
    Bs
= inflate(Z, Binary),
    inflateEnd(
Z),
    close(
Z),
   
list_to_binary(Bs);
uncompress(Binary) when is_binary(Binary) -> erlang:error(data_error);
uncompress(_) -> erlang:error(badarg).

 

open是返回一个port

open() ->
   
open_port({spawn, "zlib_drv"}, [binary]).      

        

close则关闭一个port

close(Z) ->
   
try
    true
= port_close(Z),
       
receive       %In case the caller is the owner and traps exits
            {'EXIT',
Z,_} -> ok
       
after 0 -> ok
       
end
   
catch _:_ -> erlang:error(badarg)
   
end.

inflate(Z, Data) ->
   
try port_command(Z, Data) of
        true
->
            call(
Z, ?INFLATE, <<?Z_NO_FLUSH:32>>),
            collect(
Z)
   
catch
       
error:_Err ->
            flush(
Z),
           
erlang:error(badarg)
   
end.
   

   
call(Z, Cmd, Arg) ->
   
try port_control(Z, Cmd, Arg) of
        [
0|Res] -> list_to_atom(Res);
        [
1|Res] ->
            flush(
Z),
           
erlang:error(list_to_atom(Res));
        [
2,A,B,C,D] ->
            (
A bsl 24)+(B bsl 16)+(C bsl 8)+D;
        [
3,A,B,C,D] ->
           
erlang:error({need_dictionary,(A bsl 24)+(B bsl 16)+(C bsl 8)+D})
   
catch
       
error:badarg -> %% Rethrow loses port_control from stacktrace.
           
erlang:error(badarg)
   
end.         

 

erlang在遇到port返回错误时直接error了,典型的非防御性编程。 但是个人认为这个接口应该在抛出错误之前关闭掉打开的port

 

        

作者:庆亮 | 分类目录:Erlang | 标签:

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>