[erlang-bugs] Wrong dialyzer spec for erlang:process_info/2

Michał Ptaszek <>
Fri Oct 19 18:21:14 CEST 2012


On Fri, Oct 19, 2012 at 6:02 PM, Kostis Sagonas <> wrote:
> On 10/19/2012 05:04 PM, Michał Ptaszek wrote:
>>
>> Hey,
>>
>> Let's define a function which is supposed to return us a list of links
>> for a given process:
>>
>> -spec links(pid()) ->  [port() | pid()].
>> links(Pid) ->
>>      {links, Links} = process_info(Pid, links),
>>      Links.
>>
>> Now let's run the dialyzer on the beam file:
>>
>> dialyzer -Wno_return -Wunderspecs --fullpath --plt .plt pi.beam
>>    Checking whether the PLT .plt is up-to-date... yes
>>    Proceeding with analysis...
>> pi.erl:5: Type specification pi:links(pid()) ->  [port() | pid()] is a
>> supertype of the success typing: pi:links(pid()) ->  [pid()]
>>   done in 0m1.45s
>> done (warnings were emitted)
>>
>> However it's clearly not right. For instance:
>> ()1>  erlang:process_info(whereis(erl_prim_loader),
>> links).
>> {links,[#Port<0.1>,<0.0.0>]}
>
>
> Ah, the hard-coded type information again. The main problem is that this
> information was obtained by faithfully reading (decrypting?) the Erlang/OTP
> documentation. Sometimes, this documentation specifies only half the
> truth... (Also sometimes, this is done on purpose.)
>
> For example, the published documentation of process_info/2 reads that the
> function returns:
> ...
>   {links, Pids}
>     Pids is a list of pids, with processes to which the process has a link.
>
> (See http://erlang.org/doc/man/erlang.html#process_info-2)
>
> So, it's not so clear whether the fact that it occasionally also returns
> ports as well as pids is to be relied upon in applications or not, though
> most probably it is.
>
> *Aside*: I would suggest to the OTP folks to also correct such incomplete
> inaccurate documentation of the BIFs, not only the specs.
>
>
>> I wanted to fix it by myself, however could not find the right place
>> to apply the patch. Where can I find specs for ERTS BIFs?
>
>
> In Erlang/OTP R15B02 (and previous) or in 'maint' the hard-coded type
> information is in lib/hipe/cerl/erl_bif_types.erl.  Contrary to what Patrik
> suggested, in most cases it's actually pretty easy to understand what's
> going on.  For example, the relevant line (in 'maint') is 1270. It currently
> reads:
>
>     ['links'] -> t_tuple([InfoItem, t_list(t_pid())]);
>
> Change it to:
>
>     ['links'] -> t_tuple([InfoItem, t_list(t_sup(t_pid(), t_port()))]);
>
> Then on the top-level just issue 'make hipe'.  The next time you try to run
> dialyzer it will automatically find out that the PLT is out of date and will
> rebuild it.
>
> Kostis

Sure, have done that, patch is available in
https://github.com/paulgray/otp/tree/process_info_links_dialyzer_fix

Thanks,
Michal Ptaszek


More information about the erlang-bugs mailing list