Skip to content

Instantly share code, notes, and snippets.

@jlouis
Created January 16, 2014 14:50
Show Gist options
  • Save jlouis/8456179 to your computer and use it in GitHub Desktop.
Save jlouis/8456179 to your computer and use it in GitHub Desktop.
A Dialyzer failure I have observed on R16B03 OSX 10.9
— To reproduce:
# Clone repository and force a specific version
; git clone https://github.com/jlouis/msgpack-erlang.git
; cd msgpack-erlang
; git checkout origin/dialyzer-failure
; make
; make build_plt # Takes about 2 minutes
; make dialyzer
@ddosia
Copy link

ddosia commented Jan 16, 2014

Fedora 20, R16B03:

    [ddosia@dch-think-x1 msgpack-erlang]$ make dialyzer
    ==> msgpack-erlang (compile)
    ==> msgpack-erlang (xref)

    Use 'make check_plt' to check PLT prior to using this target.
    Use 'make build_plt' to build PLT prior to using this target.

    dialyzer -Wno_return --plt /home/ddosia/.msgpack_dialyzer_plt ebin
      Checking whether the PLT /home/ddosia/.msgpack_dialyzer_plt is up-to-date... yes
      Proceeding with analysis...
    =ERROR REPORT==== 16-Jan-2014::20:50:17 ===
    Error in process <0.68.0> with exit value: {function_clause,[{erl_types,unify_lists,[[{c,tuple,[{c,atom,[ext],unknown},{c,atom,[msgpack_term],unknown}],{2,{c,atom,[ext],unknown}}}],[],[],[{c,tuple,[{c,atom,[enable_str],unknown},{c,atom,[true],unknown}],{2,{c,atom... 


    dialyzer: Analysis failed with error:
    {function_clause,[{erl_types,unify_lists,
                                 [[{c,tuple,[...],...}],[],[],[{...}|...],[]],
                                 [{file,"erl_types.erl"},{line,2695}]},
                      {erl_types,t_unify,4,[{file,[...]},{line,...}]},
                      {erl_types,t_unify,4,[{file,...},{...}]},
                      {erl_types,t_unify,3,[{...}|...]},
                      {dialyzer_typesig,solve_subtype,4,[...]},
                      {dialyzer_typesig,mk_constraint,3,...},
                      {dialyzer_typesig,state__store_conj,...},
                      {dialyzer_typesig,...}]}
    Last messages in the log cache:
      Reading files and computing callgraph... done in 0.37 secs
      Removing edges... done in 0.05 secs
    make: *** [dialyzer] Error 1

@seancribbs
Copy link

Looking at the terms in that backtrace, I found this in msgpack_term.erl:

-behabiour(msgpack_ext).

Fixing that does not resolve the problem, however.

@seancribbs
Copy link

Got the entire backtrace via dialyzer --gui:

@seancribbs
Copy link

Ok, I think I have the culprit! The type passed to msgpack:parse_options/1,2 is msgpack_list_options(), which does not include the tuple {ext, Module::module()}. Fixing this in msgpack.hrl allows analysis to continue.

$ dialyzer --plt /Users/sean/.msgpack_dialyzer_plt ebin
  Checking whether the PLT /Users/sean/.msgpack_dialyzer_plt is up-to-date... yes
  Proceeding with analysis...
msgpack.erl:56: Function binary_to_term/1 has no local return
msgpack.erl:60: Function binary_to_term/2 has no local return
msgpack.erl:85: Function unpack/1 has no local return
msgpack.erl:85: The call msgpack:unpack(Bin::any(),[]) will never return since it differs in the 2nd argument from the success typing arguments: (binary(),#options_v2{interface::'jiffy' | 'jsx',map_unpack_fun::fun((binary(),non_neg_integer(),[any()] | {_},{_,_,_,_,_,_,_,_,_}) -> {_,_}),impl::'erlang' | 'nif',allow_atom::'none' | 'pack',enable_str::boolean(),ext_packer::'undefined' | fun((tuple(),['jiffy' | 'jsx' | {_,_}]) -> {'error',_} | {'ok',{_,_}}),ext_unpacker::'undefined' | fun((...) -> {'error',_} | {'ok',binary() | [any()] | number() | {_}}),original_list::['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]})
msgpack.erl:87: Invalid type specification for function msgpack:unpack/2. The success typing is (binary(),#options_v2{interface::'jiffy' | 'jsx',map_unpack_fun::fun((binary(),non_neg_integer(),[any()] | {_},{_,_,_,_,_,_,_,_,_}) -> {_,_}),impl::'erlang' | 'nif',allow_atom::'none' | 'pack',enable_str::boolean(),ext_packer::'undefined' | fun((tuple(),['jiffy' | 'jsx' | {_,_}]) -> {'error',_} | {'ok',{_,_}}),ext_unpacker::'undefined' | fun((...) -> {'error',_} | {'ok',binary() | [any()] | number() | {_}}),original_list::['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]}) -> {'error','incomplete' | 'not_just_binary' | binary() | {'badarg',_}} | {'ok',binary() | [binary() | [any()] | number() | {} | {_} | {_,_}] | number() | {[any()]}}
msgpack.erl:100: Function unpack_stream/1 has no local return
msgpack.erl:100: The call msgpack:unpack_stream(Bin::any(),[]) breaks the contract (binary(),msgpack_option()) -> {msgpack:object(),binary()} | {'error','incomplete'} | {'error',{'badarg',term()}}
msgpack_packer.erl:72: The call msgpack_packer:pack_array(List::[binary() | maybe_improper_list(any(),binary() | []) | char()],Opt::#options_v2{interface::'jiffy' | 'jsx',map_unpack_fun::fun((binary(),non_neg_integer(),[any()] | {_},{_,_,_,_,_,_,_,_,_}) -> {_,_}),impl::'erlang' | 'nif',allow_atom::'none' | 'pack',enable_str::'true',ext_packer::'undefined' | fun((tuple(),['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]) -> {'error',_} | {'ok',{byte(),binary()}}),ext_unpacker::'undefined' | fun((...) -> {'error',_} | {'ok',binary() | [binary() | [any()] | number() | {} | {_} | {_,_}] | number() | {[any()]}}),original_list::['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]}) breaks the contract ([msgpack:object()],[any()]) -> binary() | no_return()
msgpack_packer.erl:76: The call msgpack_packer:pack_array(List::[any()],Opt::#options_v2{interface::'jiffy' | 'jsx',map_unpack_fun::fun((binary(),non_neg_integer(),[any()] | {_},{_,_,_,_,_,_,_,_,_}) -> {_,_}),impl::'erlang' | 'nif',allow_atom::'none' | 'pack',enable_str::'true',ext_packer::'undefined' | fun((tuple(),['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]) -> {'error',_} | {'ok',{byte(),binary()}}),ext_unpacker::'undefined' | fun((...) -> {'error',_} | {'ok',binary() | [binary() | [any()] | number() | {} | {_} | {_,_}] | number() | {[any()]}}),original_list::['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]}) breaks the contract ([msgpack:object()],[any()]) -> binary() | no_return()
msgpack_packer.erl:78: The call msgpack_packer:pack_array(List::maybe_improper_list(),Opt::#options_v2{interface::'jiffy' | 'jsx',map_unpack_fun::fun((binary(),non_neg_integer(),[any()] | {_},{_,_,_,_,_,_,_,_,_}) -> {_,_}),impl::'erlang' | 'nif',allow_atom::'none' | 'pack',enable_str::'true',ext_packer::'undefined' | fun((tuple(),['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]) -> {'error',_} | {'ok',{byte(),binary()}}),ext_unpacker::'undefined' | fun((...) -> {'error',_} | {'ok',binary() | [binary() | [any()] | number() | {} | {_} | {_,_}] | number() | {[any()]}}),original_list::['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]}) breaks the contract ([msgpack:object()],[any()]) -> binary() | no_return()
msgpack_term.erl:34: Function from_binary/2 has no local return
msgpack_term.erl:35: The call msgpack:unpack(Bin::any(),[any(),...]) will never return since it differs in the 2nd argument from the success typing arguments: (binary(),{'options_v2','jiffy' | 'jsx',fun((binary(),non_neg_integer(),[any()] | {_},{_,_,_,_,_,_,_,_,_}) -> {_,_}),'erlang' | 'nif','none' | 'pack',boolean(),'undefined' | fun((tuple(),['jiffy' | 'jsx' | {_,_}]) -> {'error',_} | {'ok',{_,_}}),'undefined' | fun((...) -> {'error',_} | {'ok',binary() | [any()] | number() | {_}}),['jiffy' | 'jsx' | {'allow_atom','none' | 'pack'} | {'enable_str',boolean()} | {'ext',atom() | tuple()} | {'format','jiffy' | 'jsx'}]})
Unknown functions:
  eunit:test/1
 done in 0m2.30s
done (warnings were emitted)

@bullno1
Copy link

bullno1 commented Jan 16, 2014

Regardless of the error, Dialyzer should not crash right?

@kuenishi
Copy link

Yes I admit that my code is somewhat broken :'(

@kuenishi
Copy link

Anyway I'll try some fix later > msgpack/msgpack-erlang#26

@jj1bdx
Copy link

jj1bdx commented Jan 17, 2014

R16B03 on FreeBSD 10.0-RELEASE:

kenji@wellmax[1001]% make dialyzer
==> msgpack-erlang (compile)
==> msgpack-erlang (xref)

Use 'make check_plt' to check PLT prior to using this target.
Use 'make build_plt' to build PLT prior to using this target.

dialyzer -Wno_return --plt /home/kenji/.msgpack_dialyzer_plt ebin
  Checking whether the PLT /home/kenji/.msgpack_dialyzer_plt is up-to-date... yes
  Proceeding with analysis...
=ERROR REPORT==== 17-Jan-2014::12:40:50 ===
Error in process <0.67.0> with exit value: {function_clause,[{erl_types,unify_lists,[[{c,tuple,[{c,atom,[ext],unknown},{c,atom,[msgpack_term],unknown}],{2,{c,atom,[ext],unknown}}}],[],[],[{c,tuple,[{c,atom,[enable_str],unknown},{c,atom,[true],unknown}],{2,{c,atom...


dialyzer: Analysis failed with error:
{function_clause,[{erl_types,unify_lists,
                             [[{c,tuple,[...],...}],[],[],[{...}|...],[]],
                             [{file,"erl_types.erl"},{line,2695}]},
                  {erl_types,t_unify,4,[{file,[...]},{line,...}]},
                  {erl_types,t_unify,4,[{file,...},{...}]},
                  {erl_types,t_unify,3,[{...}|...]},
                  {dialyzer_typesig,solve_subtype,4,[...]},
                  {dialyzer_typesig,mk_constraint,3,...},
                  {dialyzer_typesig,state__store_conj,...},
                  {dialyzer_typesig,...}]}
Last messages in the log cache:
  Reading files and computing callgraph... done in 0.27 secs
  Removing edges... done in 0.05 secs
*** Error code 1

Stop.
make: stopped in /home/kenji/src/msgpack-erlang

@legoscia
Copy link

Same error on R15B03 (Dialyzer 2.5.3), OSX 10.8.5:

dialyzer -Wno_return --plt /Users/magnus/.msgpack_dialyzer_plt ebin
  Checking whether the PLT /Users/magnus/.msgpack_dialyzer_plt is up-to-date... yes
  Proceeding with analysis...
=ERROR REPORT==== 17-Jan-2014::15:05:30 ===
Error in process <0.76.0> with exit value: {function_clause,[{erl_types,unify_lists,[[{c,tuple,[{c,atom,[ext],unknown},{c,atom,[msgpack_term],unknown}],{2,{c,atom,[ext],unknown}}}],[],[],[{c,tuple,[{c,atom,[enable_str],unknown},{c,atom,[true],unknown}],{2,{c,atom... 


dialyzer: Analysis failed with error:
{function_clause,[{erl_types,unify_lists,
                             [[{c,tuple,[...],...}],[],[],[{...}|...],[]],
                             [{file,"erl_types.erl"},{line,2732}]},
                  {erl_types,t_unify,4,[{file,[...]},{line,...}]},
                  {erl_types,t_unify,4,[{file,...},{...}]},
                  {erl_types,t_unify,3,[{...}|...]},
                  {dialyzer_typesig,solve_subtype,4,[...]},
                  {dialyzer_typesig,mk_constraint,3,...},
                  {dialyzer_typesig,state__store_conj,...},
                  {dialyzer_typesig,...}]}
Last messages in the log cache:
  Reading files and computing callgraph... done in 0.29 secs
  Removing edges... done in 0.02 secs
make: *** [dialyzer] Error 1

@legoscia
Copy link

Likewise on R13B04, though I needed this patch to make it compile:

diff --git a/src/msgpack.erl b/src/msgpack.erl
index 7e16581..1fad597 100644
--- a/src/msgpack.erl
+++ b/src/msgpack.erl
@@ -139,8 +139,8 @@ parse_options([{enable_str,Bool}|TL], Opt0) ->
     Opt = Opt0?OPTION{enable_str=Bool},
     parse_options(TL, Opt);
 parse_options([{ext, Module}|TL], Opt0) when is_atom(Module) ->
-    Opt = Opt0?OPTION{ext_packer=fun Module:pack_ext/2,
-                      ext_unpacker=fun Module:unpack_ext/3},
+    Opt = Opt0?OPTION{ext_packer={Module, pack_ext, 2},
+                      ext_unpacker={Module, unpack_ext, 3}},
     parse_options(TL, Opt);
 parse_options([{ext, {Packer,Unpacker}}|TL], Opt0) when
       is_function(Packer, 2) andalso
dialyzer -Wno_return --plt /Users/magnus/.msgpack_dialyzer_plt ebin
  Checking whether the PLT /Users/magnus/.msgpack_dialyzer_plt is up-to-date... yes
  Proceeding with analysis...
=ERROR REPORT==== 17-Jan-2014::15:26:55 ===
Error in process <0.30.0> with exit value: {function_clause,[{erl_types,unify_lists,[[{c,tuple,[{c,atom,[ext],unknown},{c,atom,[msgpack_term],unknown}],{2,{c,atom,[ext],unknown}}}],[],{dict,0,16,16,8,80,48,{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},{{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]}}},[{c,tuple,[{c,atom,[enable_str... 


dialyzer: Analysis failed with error: {function_clause,[{erl_types,unify_lists,
                             [[{c,tuple,[...],...}],
                              [],
                              {dict,0,...},
                              [{...}|...],
                              []]},
                  {erl_types,t_unify,4},
                  {erl_types,t_unify,4},
                  {erl_types,t_unify,3}]}
Last messages in the log cache:
  Typesig analysis for SCC: [{msgpack,module_info,0}]
  Typesig analysis for SCC: [{msgpack,module_info,1}]
  Typesig analysis for SCC: [{msgpack,parse_options,1}]
  Typesig analysis for SCC: [{msgpack,pack,2}]
  Typesig analysis for SCC: [{msgpack,unpack_stream,2}]
  Typesig analysis for SCC: [{msgpack,unpack_stream,1}]
  Typesig analysis for SCC: [{msgpack,unpack,2}]
  Typesig analysis for SCC: [{msgpack,pack,1}]
  Typesig analysis for SCC: [{msgpack,unpack,1}]
  Typesig analysis for SCC: [{msgpack_term,to_binary,1}]
make: *** [dialyzer] Error 1

@kostis
Copy link

kostis commented Jan 21, 2014

As seancribbs wrote, the culprit is that the type passed to msgpack:parse_options/1,2 is a list which includes the tuple {ext, Module::module()} but this tuple is not part ofmsgpack_list_options(). So either this type should be added to the definition, or taken out from the call.

But yes, dialyzer should not crash and this will be fixed (partial fix to be sent to erlang-bugs). Thanks for reporting this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment