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

Patrik Nyblom <>
Mon Oct 22 14:53:03 CEST 2012


Hi Kostis and Michał!

On 10/19/2012 06: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.
You'll be happy to hear that the documentation is derived from the specs 
for most functions, built in or not, in R16 (which was a lot harder in 
R15, due to erl_bif_types). So, what's in the docs will be what's in the 
specs - though for builtin functions, there may be discrepancies between 
the spec and the implementation, as in this case, which is still wrong 
in master (until I fix it :)).
>
>> 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.
>
The thing is that it's kind of wasting time doing a change in maint as 
the mechanism is totally changed in master. Changes to maint in this 
area can not in any way be automatically merged to master - so better to 
do it in the new way and use Michałs valuable time to correct the error 
in master. That's why I said don't go there, not because I thought it 
was hard to fix there :)
> Kostis
Cheers,
/Patrik

>
> _______________________________________________
> erlang-bugs mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-bugs



More information about the erlang-bugs mailing list