diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7de3811bb..a05713bb1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Changed
- handling of demonitors (#281)
+- handling of process_info(..., messages) (#283)
### Fixed
- fixed stacktrace information (#276)
diff --git a/src/concuerror.erl b/src/concuerror.erl
index 2213b4b3b..aa762f8ef 100644
--- a/src/concuerror.erl
+++ b/src/concuerror.erl
@@ -176,8 +176,9 @@ start(Options, LogMsgs) ->
maybe_cover_compile() ->
Cover = os:getenv("CONCUERROR_COVER"),
- case Cover =/= false of
+ case get(concuerror_cover) =:= undefined andalso Cover =/= false of
true ->
+ put(concuerror_cover, Cover),
case cover:is_compiled(?MODULE) of
false ->
{ok, Modules} = application:get_key(concuerror, modules),
@@ -191,8 +192,8 @@ maybe_cover_compile() ->
%%------------------------------------------------------------------------------
maybe_cover_export(Args) ->
- Cover = os:getenv("CONCUERROR_COVER"),
- case Cover =/= false of
+ Cover = erase(concuerror_cover),
+ case Cover =/= undefined of
true ->
Hash = binary:decode_unsigned(erlang:md5(term_to_binary(Args))),
Out = filename:join([Cover, io_lib:format("~.16b", [Hash])]),
diff --git a/src/concuerror_callback.erl b/src/concuerror_callback.erl
index c4d563fa3..50bca882d 100644
--- a/src/concuerror_callback.erl
+++ b/src/concuerror_callback.erl
@@ -311,15 +311,11 @@ built_in(erlang, Display, 1, [Term], _Location, Info)
end,
concuerror_logger:print(Info#concuerror_info.logger, standard_io, Chars),
{{didit, true}, Info};
-%% Process dictionary has been restored here. No need to report such ops.
+%% Inner process dictionary has been restored here. No need to report such ops.
+%% Also can't fail, as only true builtins reach this code.
built_in(erlang, Name, _Arity, Args, _Location, Info)
when Name =:= get; Name =:= get_keys; Name =:= put; Name =:= erase ->
- try
- {{didit, erlang:apply(erlang, Name, Args)}, Info}
- catch
- error:Reason -> {{error, Reason}, Info}
- end;
-%% XXX: Temporary
+ {{didit, erlang:apply(erlang, Name, Args)}, Info};
built_in(erlang, hibernate, 3, Args, _Location, Info) ->
[Module, Name, HibArgs] = Args,
self() ! {start, Module, Name, HibArgs},
@@ -682,8 +678,13 @@ run_built_in(erlang, process_info, 2, [Pid, Item], Info) when is_atom(Item) ->
catch error:badarg -> []
end;
messages ->
- #concuerror_info{message_queue = Queue} = TheirInfo,
- [M || #message{data = M} <- queue:to_list(Queue)];
+ #concuerror_info{logger = Logger} = TheirInfo,
+ Msg =
+ "Concuerror does not properly support"
+ " erlang:process_info(Other, messages),"
+ " returning an empty list instead.~n",
+ ?unique(Logger, ?lwarning, Msg, []),
+ [];
message_queue_len ->
#concuerror_info{message_queue = Queue} = TheirInfo,
queue:len(Queue);
@@ -1852,8 +1853,8 @@ exiting(Reason, Stacktrace, InfoIn) ->
FunFold = fun(Fun, Acc) -> Fun(Acc) end,
FunList =
[fun ets_ownership_exiting_events/1,
- link_monitor_handlers(links, fun handle_link/4, Links),
- link_monitor_handlers(monitors, fun handle_monitor/4, Monitors)],
+ link_monitor_handlers(fun handle_link/4, Links),
+ link_monitor_handlers(fun handle_monitor/4, Monitors)],
NewInfo = ExitInfo#concuerror_info{exit_reason = Reason},
FinalInfo = lists:foldl(FunFold, NewInfo, FunList),
?debug_flag(?loop, exited),
@@ -1911,17 +1912,14 @@ handle_monitor({Ref, P, As}, S, Reason, InfoIn) ->
instrumented(call, MFArgs, exit, InfoIn),
NewInfo.
-link_monitor_handlers(Type, Handler, LinksOrMonitors) ->
+link_monitor_handlers(Handler, LinksOrMonitors) ->
fun(Info) ->
#concuerror_info{exit_reason = Reason} = Info,
- HandleActive =
+ Fold =
fun({LinkOrMonitor, S}, InfoIn) ->
- case S =:= active orelse Type =:= monitors of
- true -> Handler(LinkOrMonitor, S, Reason, InfoIn);
- false -> InfoIn
- end
+ Handler(LinkOrMonitor, S, Reason, InfoIn)
end,
- lists:foldl(HandleActive, Info, LinksOrMonitors)
+ lists:foldl(Fold, Info, LinksOrMonitors)
end.
%%------------------------------------------------------------------------------
diff --git a/src/concuerror_dependencies.erl b/src/concuerror_dependencies.erl
index e1027776b..455012412 100644
--- a/src/concuerror_dependencies.erl
+++ b/src/concuerror_dependencies.erl
@@ -393,14 +393,17 @@ dependent_process_info(#builtin_event{mfargs = {_,_,[Pid, links]}},
when UnLink =:= link; UnLink =:= unlink -> true;
_ -> false
end;
-dependent_process_info(#builtin_event{mfargs = {_,_,[Pid, Msg]}},
- Other)
- when Msg =:= messages; Msg =:= message_queue_len ->
+dependent_process_info(#builtin_event{mfargs = {_,_,[Pid, message_queue_len]}},
+ Other) ->
case Other of
#message_event{recipient = Recipient} ->
Recipient =:= Pid;
#receive_event{recipient = Recipient, message = M} ->
Recipient =:= Pid andalso M =/= 'after';
+ #builtin_event{actor = Recipient, mfargs = {M, F, [_, Args]}} ->
+ Recipient =:= Pid andalso
+ {M, F} =:= {erlang, demonitor} andalso
+ try lists:member(flush, Args) catch _:_ -> false end;
_ -> false
end;
dependent_process_info(#builtin_event{mfargs = {_, _, [Pid, registered_name]}},
@@ -431,6 +434,7 @@ dependent_process_info(#builtin_event{mfargs = {_,_,[_, Safe]}},
Safe =:= current_stacktrace;
Safe =:= dictionary;
Safe =:= heap_size;
+ Safe =:= messages; %% If fixed, it should be an observer of message races
Safe =:= reductions;
Safe =:= stack_size;
Safe =:= status
diff --git a/src/concuerror_instrumenter.erl b/src/concuerror_instrumenter.erl
index db1b81417..77a6b93cd 100644
--- a/src/concuerror_instrumenter.erl
+++ b/src/concuerror_instrumenter.erl
@@ -179,6 +179,8 @@ is_unsafe({erlang, F, A}) ->
StringF = atom_to_list(F),
not erl_safe(StringF)
end;
+is_unsafe({erts_internal, garbage_collect, _}) ->
+ false;
is_unsafe({Safe, _, _})
when
Safe =:= binary
@@ -230,7 +232,6 @@ erl_safe("fun_info" ++ _) -> true;
erl_safe("function_exported" ) -> true;
erl_safe("garbage_collect" ) -> true;
erl_safe("get_module_info" ) -> true;
-erl_safe("hash" ) -> true;
erl_safe("hibernate" ) -> false; %% Must be instrumented.
erl_safe("insert_element" ) -> true;
erl_safe("iolist_size" ) -> true;
diff --git a/tests/suites/basic_tests/results/process_info-test_message_queue_len-inf-dpor.txt b/tests/suites/basic_tests/results/process_info-test_message_queue_len-inf-dpor.txt
new file mode 100644
index 000000000..747ee2754
--- /dev/null
+++ b/tests/suites/basic_tests/results/process_info-test_message_queue_len-inf-dpor.txt
@@ -0,0 +1,485 @@
+Concuerror AFS2018+build.2177.ref65f5340 started at 21 Aug 2018 12:15:41
+ Options:
+ [{after_timeout,infinity},
+ {assertions_only,false},
+ {assume_racing,false},
+ {depth_bound,500},
+ {disable_sleep_sets,false},
+ {dpor,optimal},
+ {entry_point,{process_info,test_message_queue_len,[]}},
+ {exclude_module,[]},
+ {files,["/Users/stavros.aronis/git/Concuerror/tests/suites/basic_tests/src/process_info.erl"]},
+ {first_process_errors_only,false},
+ {ignore_error,[]},
+ {instant_delivery,true},
+ {interleaving_bound,infinity},
+ {keep_going,true},
+ {non_racing_system,[]},
+ {print_depth,20},
+ {quiet,true},
+ {scheduling,round_robin},
+ {scheduling_bound_type,none},
+ {show_races,false},
+ {strict_scheduling,false},
+ {symbolic_names,true},
+ {timeout,5000},
+ {treat_as_normal,[]},
+ {use_receive_patterns,true}]
+################################################################################
+Interleaving #1
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+
in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} = ! {bar,}
+ in process_info.erl line 46
+ 7: : {ok,} = ! {ok,}
+ in process_info.erl line 47
+ 8: : exits normally
+ 9: : {ok,} = ! {ok,}
+ in process_info.erl line 51
+ 10: : exits normally
+ 11: : [{message_queue_len,3}] = erlang:process_info(, [message_queue_len])
+ in process_info.erl line 57
+ 12: : exits normally
+ 13: : receives message ({ok,})
+ in process_info.erl line 40
+################################################################################
+Interleaving #2
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+ in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} = ! {bar,}
+ in process_info.erl line 46
+ 7: : {ok,} = ! {ok,}
+ in process_info.erl line 47
+ 8: : exits normally
+ 9: : {ok,} = ! {ok,}
+ in process_info.erl line 51
+ 10: : exits normally
+ 11: : receives message ({ok,})
+ in process_info.erl line 40
+ 12: : [{message_queue_len,2}] = erlang:process_info(, [message_queue_len])
+ in process_info.erl line 57
+ 13: : exits normally
+################################################################################
+Interleaving #3
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+ in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} = ! {bar,}
+ in process_info.erl line 46
+ 7: : {ok,} = ! {ok,}
+ in process_info.erl line 47
+ 8: : exits normally
+ 9: : [{message_queue_len,2}] = erlang:process_info(, [message_queue_len])
+ in process_info.erl line 57
+ 10: : exits normally
+ 11: : receives message ({ok,})
+ in process_info.erl line 40
+ 12: : {ok,} = ! {ok,}
+ in process_info.erl line 51
+ 13: : exits normally
+################################################################################
+Interleaving #4
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+ in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} = ! {bar,}
+ in process_info.erl line 46
+ 7: : {ok,} = ! {ok,}
+ in process_info.erl line 47
+ 8: : exits normally
+ 9: : receives message ({ok,})
+ in process_info.erl line 40
+ 10: : [{message_queue_len,1}] = erlang:process_info(, [message_queue_len])
+ in process_info.erl line 57
+ 11: : exits normally
+ 12: : {ok,} = ! {ok,}
+ in process_info.erl line 51
+ 13: : exits normally
+################################################################################
+Interleaving #5
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+ in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} = ! {bar,}
+ in process_info.erl line 46
+ 7: : {ok,} = ! {ok,}
+ in process_info.erl line 51
+ 8: : {ok,} = ! {ok,}
+ in process_info.erl line 47
+ 9: : exits normally
+ 10: : exits normally
+ 11: : [{message_queue_len,3}] = erlang:process_info(, [message_queue_len])
+ in process_info.erl line 57
+ 12: : exits normally
+ 13: : receives message ({ok,})
+ in process_info.erl line 40
+################################################################################
+Interleaving #6
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+ in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} = ! {bar,}
+ in process_info.erl line 46
+ 7: : {ok,} = ! {ok,}
+ in process_info.erl line 51
+ 8: : {ok,} = ! {ok,}
+ in process_info.erl line 47
+ 9: : exits normally
+ 10: : exits normally
+ 11: : receives message ({ok,})
+ in process_info.erl line 40
+ 12: : [{message_queue_len,2}] = erlang:process_info(, [message_queue_len])
+ in process_info.erl line 57
+ 13: : exits normally
+################################################################################
+Interleaving #7
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+ in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} = ! {bar,}
+ in process_info.erl line 46
+ 7: : {ok,} = ! {ok,}
+ in process_info.erl line 51
+ 8: : exits normally
+ 9: : [{message_queue_len,2}] = erlang:process_info(, [message_queue_len])
+ in process_info.erl line 57
+ 10: : exits normally
+ 11: : receives message ({ok,})
+ in process_info.erl line 40
+ 12: : {ok,} = ! {ok,}
+ in process_info.erl line 47
+ 13: : exits normally
+################################################################################
+Interleaving #8
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+ in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} = ! {bar,}
+ in process_info.erl line 46
+ 7: : {ok,} = ! {ok,}
+ in process_info.erl line 51
+ 8: : exits normally
+ 9: : receives message ({ok,})
+ in process_info.erl line 40
+ 10: : [{message_queue_len,1}] = erlang:process_info(, [message_queue_len])
+ in process_info.erl line 57
+ 11: : exits normally
+ 12: : {ok,} = ! {ok,}
+ in process_info.erl line 47
+ 13: : exits normally
+################################################################################
+Interleaving #9
+--------------------------------------------------------------------------------
+Errors found:
+* Blocked at a 'receive' ("deadlocked"; other processes have exited):
+ in process_info.erl line 41
+ Mailbox contents: [{bar,},{ok,}]
+--------------------------------------------------------------------------------
+Event trace:
+ 1: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 2: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 3: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 4: :
= erlang:spawn(erlang, apply, [#Fun,[]])
+ in erlang.erl line 2687
+ 5: : exits normally
+ 6:
: {bar,} =