【Elang】dialyzer

在windows下跑dialyzer

先構建dialyzer_plt

dialyzer --build_plt --output_plt .dialyzer_plt --apps erts kernel stdlib mnesia compiler inets xmerl crypto ssl runtime_tools public_key tools
dialyzer --plt ./.dialyzer_plt -I ./include --src -r ./src --statistics -o output.log  -Wno_behaviours -Wno_match -Wno_unused -Wno_return

--src:表示分析‘.erl’的源代碼,不加的話默認分析'.beam'文件

-Wno_match:對於一些未使用的匹配模式會進行報錯,比如下邊的代碼,本身是沒有問題的,但是在調用時,只有一個地方調用用匹配了第一個,第二個未使用,就會報錯。使用-Wno_match忽略這類型的報錯。

make_p_chat_role(#r_channel_chat{role_id=RoleID,role_name=RoleName,union_name=UnionName,vip=Vip,head_id=HeadID, head_box_id=HeaaBox}) ->
	#p_chat_role{role_id=RoleID,role_name=RoleName,union_name=UnionName,vip=Vip, head_id=HeadID, head_box_id=HeaaBox};
make_p_chat_role(RoleID) when is_integer(RoleID) ->
    case role_data:get_role_attr(RoleID) of
        {ok, #r_role_attr{role_name = RoleName,  union_id=UnionID}} ->
			UnionName = api_role_union:get_union_name(UnionID),
			Vip = role_vip:get_vip_level(RoleID),
			{HeadId, HeadBoxId} = api_role_head:get_head_id(RoleID),
            #p_chat_role{role_id=RoleID,role_name=RoleName,union_name=UnionName,vip=Vip,
						 head_id=HeadId, head_box_id=HeadBoxId};
        _ ->
            #p_chat_role{role_id = RoleID}
    end.

-Wno_unused:禁止對未使用的函數報錯

-Wno_behaviours:禁止類似下邊的報錯

glogger_type_sup.erl:36: The return type {'ok',{{'one_for_all',non_neg_integer(),pos_integer()} | {'one_for_one',non_neg_integer(),pos_integer()} | {'rest_for_one',non_neg_integer(),pos_integer()} | {'simple_one_for_one',non_neg_integer(),pos_integer()},[{_,{atom(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','supervisor' | 'worker','dynamic' | [atom()]}]}} in the specification of init/1 is not a subtype of 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),pos_integer()} | {'one_for_one',non_neg_integer(),pos_integer()} | {'rest_for_one',non_neg_integer(),pos_integer()} | {'simple_one_for_one',non_neg_integer(),pos_integer()} | #{'intensity'=>non_neg_integer(), 'period'=>pos_integer(), 'strategy'=>'one_for_all' | 'one_for_one' | 'rest_for_one' | 'simple_one_for_one'},[{_,{atom(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom()]} | #{'id':=_, 'start':={atom(),atom(),'undefined' | [any()]}, 'modules'=>'dynamic' | [atom()], 'restart'=>'permanent' | 'temporary' | 'transient', 'shutdown'=>'brutal_kill' | 'infinity' | non_neg_integer(), 'type'=>'supervisor' | 'worker'}]}}, which is the expected return type for the callback of the supervisor behaviour

跑dialyzer的時候經常會碰上一些莫名其妙的報錯,比如glogger_clear_server.erl:128: The created fun has no local return。檢查了一下代碼,並沒有看出哪裏有問題,也有調用

clear_logs3(LogType, Day) ->
	Dir = glogger_mod:get_log_dir(LogType),
	{ok, FileL} = file:list_dir(Dir),
	?D(FileL),
	Now = common_time:now(),
	ClearUnixTime = Now - (Day+1)*86400,
	lists:foreach(
	  fun(FileName) -> 
		 case glogger_mod:is_log_file(FileName) of
			 false -> ignore;
			 true ->
				 {Y,M,D} = glogger_mod:get_file_date(FileName),
				 UnixTime = common_time:timestamp({Y,M,D}),
				 case UnixTime < ClearUnixTime of
					 true -> 
						 FullFileName = filename:join(Dir, FileName),
						 file:delete(FullFileName);
					 false -> ignore
				 end
		 end
	  end, FileL).

結果把該函數導出,再跑dialyzer就沒有這個報錯了。使用-Wno_return可以禁止這類報錯。

出現下邊的報錯,二進制構造失敗,嘗試了各種禁止參數都沒有用,代碼看起來也沒有問題,將返回值直接替換進參數就沒有報錯,最後只能忽略這個問題。

gateway_websocket_layer.erl:257: Binary construction will fail since the value field FrameHeader in segment FrameHeader:8/integer-unit:1 has type <<_:8>>

%% 代碼

frame_data(Type, <<>>) ->
    FrameHeader = get_frame_header(Type),
    <<FrameHeader:8, 0:8>>;
frame_data(Type, Data) ->
    FrameHeader = get_frame_header(Type),
    LengthHeader = get_length_header(size(Data)),
    <<FrameHeader/binary, LengthHeader/binary, Data/binary>>.

%%
get_frame_header(continuation) -> <<8:4, 0:4>>;
get_frame_header(text) -> <<8:4, 1:4>>;
get_frame_header(binary) -> <<8:4, 2:4>>;
get_frame_header(close) -> <<8:4, 8:4>>;
get_frame_header(ping) -> <<8:4, 9:4>>;
get_frame_header(pong) -> <<8:4, 10:4>>;
get_frame_header(_) -> <<8:4, 15:4>>.

用下邊的代碼測試dialyzer會不會拋錯,test_num傳進的是數字,正常當跑到test的時候是會崩潰的,但是使用dialyzer分析不出這種錯誤(沒有使用任何禁用參數)。不得不說dialyzer還是比較雞肋的,正常代碼拋出各種莫名奇妙的拋錯,一些隱晦的問題分析不出。


-spec test(_, _) -> boolean().
test(true, true) -> true;
test(false, _) -> false;
test(_, false) -> false.

-spec test_num(number(), number()) -> number().
test_num(X, Y) ->
	test(X, Y),
	X+Y.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章