Elixir: Issue when profiling Flow with Eprof

Created on 31 Jan 2018  Â·  11Comments  Â·  Source: elixir-lang/elixir

Environment

~ :> elixir --version
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Elixir 1.6.0 (compiled with OTP 20)
~ :> uname -a
Darwin Paulos-MacBook-Pro.local 14.5.0 Darwin Kernel Version 14.5.0: Sun Jun  4 21:40:08 PDT 2017; root:xnu-2782.70.3~1/RELEASE_X86_64 x86_64```

Current behavior

Hi!

First of all, thank you for the work you all do. :heart: Elixir

I'm here to run an issue by you regarding profiling and Flow. More specifically, Eprof.

I ran into the issue in my project and started digging a little deeper. Almost always the problem is me, but I figured I'd at least raise this here in case other people run into the same problem.

profile.cprof and profile.fprof work as expected, but there is a FunctionClauseError when using `profile.eprof.

Here is a dummy project to demonstrate the issue. I wrote a couple of tests based on the tests for the profilers and you can see the error when running mix test.

You will get the full stacktrace by using the dummy project, but here is the main error message:

     ** (FunctionClauseError) no function clause matching in Mix.Tasks.Profile.Eprof.extract_results/1

     The following arguments were given to Mix.Tasks.Profile.Eprof.extract_results/1:

         # 1
         [{#PID<0.208.0>, [{{:erlang, :exit, 2}, {1, 2}}, {{:erlang, :list_to_tuple, 1}, {1, 5}}, {{:erlang, :process_info, 2}, {1, 2}}, {{:erlang, :whereis, 1}, {1, 6}}, {{:erlang, :spawn_opt, 1}, {2, 11}}, {{:erlang, :system_info, 1}, {6, 23}}, {{:erlang, :monitor, 2}, {3, 9}}, {{:erlang, :demonitor, 2}, {8, 18}}, {{:erlang, :send, 2}, {3, 5}}, {{:erlang, :send, 3}, {2, 17}}, {{:lists, :member, 2}, {1, 1}}, {{:lists, :reverse, 2}, {2, 12}}, {{:lists, :keyfind, 3}, {11, 31}}, {{:erlang, :iolist_to_binary, 1}, {1, 6}}, {{:unicode, :characters_to_binary, 2}, {1, 7}}, {{:binary, :last, 1}, {2, 8}}, {{:erlang, :dt_spread_tag, 1}, {1, 4}}, {{:erlang, :dt_restore_tag, 1}, {1, 3}}, {{:maps, :to_list, 1}, {1, 1}}, {{:maps, :put, 3}, {4, 4}}, {{:maps, :remove, 2}, {4, 3}}, {{:gen_server, :call, 3}, {1, 7}}, {{:proc_lib, :proc_info, 2}, {1, 3}}, {{:proc_lib, :get_ancestors, 0}, {1, 2}}, {{:proc_lib, :get_my_name, 0}, {1, 2}}, {{:proc_lib, :sync_wait_mon, 2}, {1, 3}}, {{:proc_lib, :start, 5}, {1, 1}}, {{:proc_lib, :spawn_opt_mon, 4}, {1, 3}}, {{:proc_lib, :check_for_monitor, 1}, {1, 3}}, {{GenServer, :whereis, 1}, {1, 1}}, {{GenServer, :start, 3}, {1, 1}}, {{GenServer, :do_start, 4}, {1, 1}}, {{GenServer, :do_send, 2}, {1, 0}}, {{GenServer, :cast_msg, 1}, {1, 1}}, {{GenServer, :cast, 2}, {1, 0}}, {{GenServer, :call, 3}, {1, 0}}, {{Enumerable.List, :reduce, 3}, {3, 3}}, {{:erlang, :spawn_opt, 4}, {1, 1}}, {{:erlang, :spawn_monitor, 1}, {1, 2}}, {{:erlang, :apply, 2}, {1, 7}}, {{Flow.Window, :global, 0}, {2, 8}}, {{Enumerable.Flow, :reduce, 3}, {1, 1}}, {{Enum, :"-reduce/3-lists^foldl/2-0-", 3}, {2, 1}}, {{Enum, :"-reverse/1-fun-0-", ...}, {5, ...}}, {{Enum, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.209.0>, [{{:erlang, :exit, 2}, {1, 3}}, {{:erlang, :integer_to_list, 1}, {1, 1}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :make_ref, 0}, {9, 13}}, {{:erlang, :function_exported, 3}, {1, 1}}, {{:erlang, :process_flag, 2}, {1, 2}}, {{:erlang, :process_info, 2}, {1, 1}}, {{:erlang, :put, 2}, {2, 3}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :spawn_opt, 1}, {1, 5}}, {{:erlang, :monitor, 2}, {14, 21}}, {{:erlang, :demonitor, 2}, {9, 14}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 6}}, {{:erlang, :send, 2}, {1, 1}}, {{:erlang, :send, 3}, {9, 44}}, {{:erlang, :++, 2}, {25, 24}}, {{:lists, :member, 2}, {15, 16}}, {{:lists, :reverse, 2}, {7, 6}}, {{:lists, :keymember, 3}, {1, 1}}, {{:lists, :keyfind, 3}, {37, 41}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 1}}, {{:gen_server, :handle_common_reply, 8}, {4, 3}}, {{:gen_server, :handle_msg, 6}, {5, 4}}, {{:gen_server, :try_terminate, 3}, {1, 1}}, {{:gen_server, :try_handle_call, 4}, {1, 2}}, {{:gen_server, :try_dispatch, 4}, {4, 4}}, {{:gen_server, :try_dispatch, 3}, {4, 7}}, {{:gen_server, :decode_msg, 9}, {5, 4}}, {{:gen_server, :loop, 7}, {5, 6}}, {{:gen_server, :init_it, 2}, {1, 2}}, {{:gen_server, :init_it, 6}, {2, 2}}, {{:gen_server, :reply, 2}, {1, 3}}, {{:gen_server, :start_link, 3}, {1, 1}}, {{:proc_lib, :proc_info, 2}, {1, 2}}, {{:proc_lib, :get_ancestors, 0}, {1, 2}}, {{:proc_lib, :get_my_name, 0}, {1, 2}}, {{:proc_lib, :crash_report, 4}, {1, 1}}, {{:proc_lib, :trans_init, 3}, {1, 3}}, {{:proc_lib, :make_dummy_args, 2}, {2, 2}}, {{:proc_lib, :init_ack, ...}, {1, ...}}, {{:proc_lib, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.210.0>, [{{:erlang, :group_leader, 0}, {9, 10}}, {{:erlang, :integer_to_list, 1}, {1, 1}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :function_exported, 3}, {1, 1}}, {{:erlang, :process_flag, 2}, {1, 1}}, {{:erlang, :process_info, 2}, {9, 11}}, {{:erlang, :put, 2}, {2, 3}}, {{:erlang, :setelement, 3}, {47, 62}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :spawn_opt, 1}, {9, 40}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 2}}, {{:erlang, :++, 2}, {1, 1}}, {{:lists, :member, 2}, {18, 19}}, {{:lists, :keysearch, 3}, {9, 11}}, {{:lists, :keyfind, 3}, {38, 39}}, {{:maps, :merge, 2}, {10, 16}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 0}}, {{:gen_server, :handle_common_reply, 8}, {9, 8}}, {{:gen_server, :handle_msg, 6}, {18, 22}}, {{:gen_server, :try_terminate, 3}, {1, 1}}, {{:gen_server, :try_handle_call, 4}, {9, 21}}, {{:gen_server, :try_dispatch, 4}, {9, 8}}, {{:gen_server, :try_dispatch, 3}, {9, 15}}, {{:gen_server, :decode_msg, 9}, {19, 19}}, {{:gen_server, :loop, 7}, {19, 35}}, {{:gen_server, :init_it, 2}, {1, 3}}, {{:gen_server, :init_it, 6}, {1, 1}}, {{:gen_server, :reply, 2}, {9, 25}}, {{:error_logger, :notify, 1}, {9, 9}}, {{:error_logger, :info_report, 2}, {9, 11}}, {{:proc_lib, :proc_info, 2}, {9, 19}}, {{:proc_lib, :get_ancestors, 0}, {9, 18}}, {{:proc_lib, :get_my_name, 0}, {9, 22}}, {{:proc_lib, :crash_report, 4}, {1, 1}}, {{:proc_lib, :trans_init, 3}, {1, 3}}, {{:proc_lib, :make_dummy_args, 2}, {2, 2}}, {{:proc_lib, :init_ack, 2}, {1, 4}}, {{:proc_lib, :sync_wait, 2}, {9, 21}}, {{:proc_lib, :start_link, ...}, {9, ...}}, {{:proc_lib, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.211.0>, [{{:erlang, :integer_to_list, 1}, {1, 1}}, {{:erlang, :list_to_atom, 1}, {1, 2}}, {{:erlang, :function_exported, 3}, {7, 9}}, {{:erts_internal, :open_port, 2}, {1, 9}}, {{:erlang, :put, 2}, {2, 3}}, {{:erlang, :throw, 1}, {1, 2}}, {{:erts_internal, :port_command, 3}, {6, 29}}, {{:erts_internal, :port_close, 1}, {1, 5}}, {{:erlang, :bump_reductions, 1}, {6, 15}}, {{:erlang, :monitor, 2}, {4, 9}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 52}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {1, 2}}, {{:erlang, :++, 2}, {5, 9}}, {{:lists, :member, 2}, {5, 6}}, {{:lists, :reverse, 2}, {8, 8}}, {{:lists, :keyfind, 3}, {6, 8}}, {{:erlang, :make_fun, 3}, {1, 1}}, {{:erlang, :iolist_size, 1}, {1, 1}}, {{:prim_file, :internal_name2native, 1}, {1, 1}}, {{:erlang, :dt_spread_tag, 1}, {7, 7}}, {{:erlang, :dt_restore_tag, 1}, {7, 7}}, {{:erlang, :dt_append_vm_tag_data, 1}, {6, 6}}, {{:maps, :get, 2}, {8, 9}}, {{:maps, :put, 3}, {16, 19}}, {{Map, :get_and_update!, 3}, {8, 18}}, {{Map, :get_and_update, 3}, {8, 8}}, {{Map, :get, 3}, {8, 17}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 1}}, {{:gen_server, :terminate, 8}, {1, 1}}, {{:gen_server, :handle_common_reply, 8}, {12, 13}}, {{:gen_server, :handle_msg, 6}, {12, 13}}, {{:gen_server, :try_terminate, 3}, {1, 2}}, {{:gen_server, :try_dispatch, 4}, {12, 18}}, {{:gen_server, :try_dispatch, 3}, {12, 25}}, {{:gen_server, :decode_msg, 9}, {12, 13}}, {{:gen_server, :loop, 7}, {12, 22}}, {{:gen_server, :init_it, 2}, {1, 3}}, {{:gen_server, :init_it, ...}, {1, ...}}, {{GenStage.Streamer, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.212.0>, [{{:erlang, :erase, 1}, {1, 1}}, {{:erlang, :phash2, 2}, {6, 6}}, {{:erlang, :integer_to_list, 1}, {1, 1}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :make_ref, 0}, {3, 7}}, {{:erlang, :function_exported, 3}, {9, 10}}, {{:erlang, :put, 2}, {16, 17}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :monitor, 2}, {5, 7}}, {{:erlang, :demonitor, 2}, {1, 1}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 3}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {6, 14}}, {{:erlang, :++, 2}, {1, 1}}, {{:lists, :member, 2}, {2, 2}}, {{:lists, :reverse, 2}, {5, 5}}, {{:lists, :keyfind, 3}, {16, 20}}, {{:maps, :to_list, 1}, {2, 3}}, {{:maps, :get, 2}, {18, 18}}, {{:maps, :from_list, 1}, {2, 3}}, {{:maps, :is_key, 2}, {1, 1}}, {{:maps, :put, 3}, {34, 41}}, {{:maps, :remove, 2}, {2, 2}}, {{:binary, :split, 3}, {2, 6}}, {{:maps, :take, 2}, {1, 1}}, {{Map, :pop, 3}, {1, 1}}, {{Map, :pop, 2}, {1, 2}}, {{Map, :get_and_update!, 3}, {10, 19}}, {{Map, :get_and_update, 3}, {10, 9}}, {{Map, :get, 3}, {10, 19}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 1}}, {{:gen_server, :handle_common_reply, 8}, {12, 11}}, {{:gen_server, :handle_msg, 6}, {12, 11}}, {{:gen_server, :try_terminate, 3}, {1, 1}}, {{:gen_server, :try_dispatch, 4}, {12, 11}}, {{:gen_server, :try_dispatch, 3}, {12, 21}}, {{:gen_server, :decode_msg, ...}, {12, ...}}, {{:gen_server, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.213.0>, [{{:erlang, :erase, 1}, {1, 1}}, {{:erlang, :integer_to_list, 1}, {1, 1}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :make_ref, 0}, {3, 7}}, {{:erlang, :function_exported, 3}, {9, 9}}, {{:erlang, :put, 2}, {6, 8}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :monitor, 2}, {5, 8}}, {{:erlang, :demonitor, 2}, {1, 1}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 12}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {2, 8}}, {{:erlang, :++, 2}, {1, 1}}, {{:lists, :member, 2}, {2, 2}}, {{:lists, :reverse, 2}, {1, 1}}, {{:lists, :keyfind, 3}, {16, 19}}, {{:maps, :to_list, 1}, {1, 0}}, {{:maps, :get, 2}, {17, 16}}, {{:maps, :from_list, 1}, {1, 1}}, {{:maps, :is_key, 2}, {1, 1}}, {{:maps, :put, 3}, {32, 36}}, {{:maps, :remove, 2}, {2, 2}}, {{:maps, :take, 2}, {1, 1}}, {{Map, :pop, 3}, {1, 0}}, {{Map, :pop, 2}, {1, 1}}, {{Map, :get_and_update!, 3}, {9, 17}}, {{Map, :get_and_update, 3}, {9, 8}}, {{Map, :get, 3}, {9, 16}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 1}}, {{:gen_server, :handle_common_reply, 8}, {11, 10}}, {{:gen_server, :handle_msg, 6}, {11, 9}}, {{:gen_server, :try_terminate, 3}, {1, 2}}, {{:gen_server, :try_dispatch, 4}, {11, 10}}, {{:gen_server, :try_dispatch, 3}, {11, 19}}, {{:gen_server, :decode_msg, 9}, {11, 10}}, {{:gen_server, :loop, ...}, {11, ...}}, {{:gen_server, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.214.0>, [{{:erlang, :erase, 1}, {1, 1}}, {{:erlang, :integer_to_list, 1}, {1, 1}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :make_ref, 0}, {3, 5}}, {{:erlang, :function_exported, 3}, {9, 8}}, {{:erlang, :put, 2}, {6, 6}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :monitor, 2}, {5, 6}}, {{:erlang, :demonitor, 2}, {1, 1}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 7}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {2, 5}}, {{:erlang, :++, 2}, {1, 0}}, {{:lists, :member, 2}, {2, 1}}, {{:lists, :reverse, 2}, {1, 0}}, {{:lists, :keyfind, 3}, {16, 15}}, {{:maps, :to_list, 1}, {1, 1}}, {{:maps, :get, 2}, {17, 15}}, {{:maps, :from_list, 1}, {1, 1}}, {{:maps, :is_key, 2}, {1, 1}}, {{:maps, :put, 3}, {32, 33}}, {{:maps, :remove, 2}, {2, 2}}, {{:maps, :take, 2}, {1, 1}}, {{Map, :pop, 3}, {1, 0}}, {{Map, :pop, 2}, {1, 1}}, {{Map, :get_and_update!, 3}, {9, 16}}, {{Map, :get_and_update, 3}, {9, 7}}, {{Map, :get, 3}, {9, 16}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 1}}, {{:gen_server, :handle_common_reply, 8}, {11, 10}}, {{:gen_server, :handle_msg, 6}, {11, 9}}, {{:gen_server, :try_terminate, 3}, {1, 1}}, {{:gen_server, :try_dispatch, 4}, {11, 10}}, {{:gen_server, :try_dispatch, 3}, {11, 19}}, {{:gen_server, :decode_msg, ...}, {11, ...}}, {{:gen_server, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.215.0>, [{{:erlang, :erase, 1}, {1, 1}}, {{:erlang, :integer_to_list, 1}, {1, 0}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :make_ref, 0}, {3, 4}}, {{:erlang, :function_exported, 3}, {9, 8}}, {{:erlang, :put, 2}, {6, 5}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :monitor, 2}, {5, 6}}, {{:erlang, :demonitor, 2}, {1, 1}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 6}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {2, 4}}, {{:erlang, :++, 2}, {1, 0}}, {{:lists, :member, 2}, {2, 1}}, {{:lists, :reverse, 2}, {1, 0}}, {{:lists, :keyfind, 3}, {16, 14}}, {{:maps, :to_list, 1}, {1, 0}}, {{:maps, :get, 2}, {17, 15}}, {{:maps, :from_list, 1}, {1, 1}}, {{:maps, :is_key, 2}, {1, 0}}, {{:maps, :put, 3}, {32, 33}}, {{:maps, :remove, 2}, {2, 2}}, {{:maps, :take, 2}, {1, 0}}, {{Map, :pop, 3}, {1, 0}}, {{Map, :pop, 2}, {1, 1}}, {{Map, :get_and_update!, 3}, {9, 16}}, {{Map, :get_and_update, 3}, {9, 8}}, {{Map, :get, 3}, {9, 15}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 1}}, {{:gen_server, :handle_common_reply, 8}, {11, 10}}, {{:gen_server, :handle_msg, 6}, {11, 9}}, {{:gen_server, :try_terminate, 3}, {1, 1}}, {{:gen_server, :try_dispatch, 4}, {11, 10}}, {{:gen_server, :try_dispatch, ...}, {11, ...}}, {{:gen_server, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.216.0>, [{{:erlang, :erase, 1}, {4, 3}}, {{:erlang, :integer_to_list, 1}, {1, 1}}, {{:erlang, :list_to_atom, 1}, {1, 3}}, {{:erlang, :make_ref, 0}, {1, 0}}, {{:erlang, :function_exported, 3}, {12, 11}}, {{:erlang, :put, 2}, {2, 2}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :monitor, 2}, {5, 6}}, {{:erlang, :demonitor, 2}, {4, 3}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 2}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {9, 13}}, {{:erlang, :++, 2}, {2, 2}}, {{:lists, :member, 2}, {5, 4}}, {{:lists, :reverse, 2}, {2, 1}}, {{:lists, :keyfind, 3}, {22, 19}}, {{:maps, :to_list, 1}, {1, 0}}, {{:maps, :get, 2}, {7, 6}}, {{:maps, :is_key, 2}, {4, 3}}, {{:maps, :put, 3}, {25, 32}}, {{:maps, :remove, 2}, {8, 8}}, {{:maps, :take, 2}, {4, 3}}, {{Map, :update, 4}, {3, 3}}, {{Map, :pop, 3}, {4, 3}}, {{Map, :pop, 2}, {4, 7}}, {{Map, :get_and_update!, 3}, {7, 15}}, {{Map, :get_and_update, 3}, {7, 6}}, {{Map, :get, 3}, {7, 12}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 0}}, {{:gen_server, :handle_common_reply, 8}, {9, 8}}, {{:gen_server, :handle_msg, 6}, {9, 8}}, {{:gen_server, :try_terminate, 3}, {1, 1}}, {{:gen_server, :try_dispatch, ...}, {9, ...}}, {{:gen_server, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.217.0>, [{{:erlang, :erase, 1}, {4, 3}}, {{:erlang, :integer_to_list, 1}, {1, 0}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :make_ref, 0}, {1, 0}}, {{:erlang, :function_exported, 3}, {12, 11}}, {{:erlang, :put, 2}, {2, 2}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :monitor, 2}, {5, 6}}, {{:erlang, :demonitor, 2}, {4, 3}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 2}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {9, 11}}, {{:erlang, :++, 2}, {2, 1}}, {{:lists, :member, 2}, {5, 4}}, {{:lists, :reverse, 2}, {1, 0}}, {{:lists, :keyfind, 3}, {22, 20}}, {{:maps, :to_list, 1}, {1, 0}}, {{:maps, :get, 2}, {7, 6}}, {{:maps, :is_key, 2}, {4, 3}}, {{:maps, :put, 3}, {23, 24}}, {{:maps, :remove, 2}, {8, 7}}, {{:maps, :take, 2}, {4, 3}}, {{Map, :update, 4}, {1, 1}}, {{Map, :pop, 3}, {4, 3}}, {{Map, :pop, 2}, {4, 7}}, {{Map, :get_and_update!, 3}, {7, 14}}, {{Map, :get_and_update, 3}, {7, 6}}, {{Map, :get, 3}, {7, 12}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 0}}, {{:gen_server, :handle_common_reply, 8}, {9, 8}}, {{:gen_server, :handle_msg, 6}, {9, 8}}, {{:gen_server, :try_terminate, ...}, {1, ...}}, {{:gen_server, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.218.0>, [{{:erlang, :erase, 1}, {4, 3}}, {{:erlang, :integer_to_list, 1}, {1, 0}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :make_ref, 0}, {1, 0}}, {{:erlang, :function_exported, 3}, {12, 11}}, {{:erlang, :put, 2}, {2, 2}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :monitor, 2}, {5, 6}}, {{:erlang, :demonitor, 2}, {4, 3}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 2}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {9, 11}}, {{:erlang, :++, 2}, {2, 1}}, {{:lists, :member, 2}, {5, 4}}, {{:lists, :reverse, 2}, {1, 0}}, {{:lists, :keyfind, 3}, {22, 20}}, {{:maps, :to_list, 1}, {1, 0}}, {{:maps, :get, 2}, {7, 6}}, {{:maps, :is_key, 2}, {4, 3}}, {{:maps, :put, 3}, {23, 24}}, {{:maps, :remove, 2}, {8, 7}}, {{:maps, :take, 2}, {4, 3}}, {{Map, :update, 4}, {1, 0}}, {{Map, :pop, 3}, {4, 3}}, {{Map, :pop, 2}, {4, 7}}, {{Map, :get_and_update!, 3}, {7, 14}}, {{Map, :get_and_update, 3}, {7, 6}}, {{Map, :get, 3}, {7, 12}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 0}}, {{:gen_server, :handle_common_reply, 8}, {9, 8}}, {{:gen_server, :handle_msg, ...}, {9, ...}}, {{:gen_server, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.219.0>, [{{:erlang, :erase, 1}, {4, 4}}, {{:erlang, :integer_to_list, 1}, {1, 1}}, {{:erlang, :list_to_atom, 1}, {1, 1}}, {{:erlang, :make_ref, 0}, {1, 0}}, {{:erlang, :function_exported, 3}, {12, 11}}, {{:erlang, :put, 2}, {2, 2}}, {{:erlang, :throw, 1}, {1, 1}}, {{:erlang, :monitor, 2}, {5, 6}}, {{:erlang, :demonitor, 2}, {4, 4}}, {{:erlang, :raise, 3}, {2, 1}}, {{:erlang, :get_stacktrace, 0}, {2, 3}}, {{:erlang, :send, 2}, {2, 2}}, {{:erlang, :send, 3}, {9, 12}}, {{:erlang, :++, 2}, {2, 1}}, {{:lists, :member, 2}, {5, 4}}, {{:lists, :reverse, 2}, {1, 0}}, {{:lists, :keyfind, 3}, {22, 20}}, {{:maps, :to_list, 1}, {1, 1}}, {{:maps, :get, 2}, {7, 6}}, {{:maps, :is_key, 2}, {4, 3}}, {{:maps, :put, 3}, {23, 24}}, {{:maps, :remove, 2}, {8, 8}}, {{:maps, :take, 2}, {4, 4}}, {{Map, :update, 4}, {1, 0}}, {{Map, :pop, 3}, {4, 3}}, {{Map, :pop, 2}, {4, 7}}, {{Map, :get_and_update!, 3}, {7, 14}}, {{Map, :get_and_update, 3}, {7, 6}}, {{Map, :get, 3}, {7, 12}}, {{:gen_server, :terminate_reason, 3}, {1, 1}}, {{:gen_server, :terminate, 10}, {1, 0}}, {{:gen_server, :terminate, 8}, {1, 0}}, {{:gen_server, :handle_common_reply, ...}, {9, ...}}, {{:gen_server, ...}, {...}}, {{...}, ...}, {...}, ...]}, {#PID<0.220.0>, [{{:erlang, :monitor, 2}, {5, 6}}, {{:erlang, :send, 2}, {5, 7}}, {{:erlang, :send, 3}, {8, 12}}, {{:erlang, :++, 2}, {1, 1}}, {{:erlang, :--, 2}, {4, 4}}, {{:lists, :member, 2}, {4, 3}}, {{:maps, :keys, 1}, {1, 1}}, {{:maps, :put, 3}, {4, 4}}, {{GenServer, :whereis, 1}, {4, 7}}, {{:erlang, :apply, 2}, {1, 1}}, {{Enum, :member?, 2}, {4, 7}}, {{GenStage, :"-init_stream/2-fun-0-", 2}, {1, 1}}, {{GenStage, :"-subscriptions_monitor/3-fun-0-", 5}, {4, 7}}, {{GenStage, :"-subscriptions_monitor/3-lists^foldl/2-0-", 3}, {5, 4}}, {{GenStage, :subscriptions_monitor, 3}, {1, 2}}, {{GenStage, :loop_monitor, 5}, {6, 7}}, {{GenStage, :init_monitor, 2}, {1, 1}}]}]

     Attempted function clauses (showing 2 out of 2):

         defp extract_results([])
         defp extract_results([{_pid, call_results}])

Here is the link to those calls that cry in the Elixir repo.

So here is my question:

  • Is it fair to conclude that we can't use Eprof with Flow at this time?
  • Or... is it me that's the issue :(, haha.

Thank you!

cc: @costaraphael

Mix Bug Starter

Most helpful comment

@m13m It is because mix uses the elixir executable that's available in the environment. So simply running the mix executable in the bin folder does not ensure that you are using the newly compiled version that is in the same folder. That's why you have to export the PATH again prepending the newly compiled ones.

All 11 comments

I looked at the profile.eprof task code, and it seems like it's only handling when there's no output and when there's only a single PID outputting data. (code)

I could come up with a PR, but how should this scenario be handled? Some ideas I thought about:

  • Aggregating the results from all the PIDs (simpler)
  • Changing the output format to display individual results for each PID (more powerful)
  • Both, with the first one by default and the second one behind a flag
  • Displaying a nice error message if dealing with this case doesn't make sense

What do you guys think?

Let's go with:

Changing the output format to display individual results for each PID (more powerful)

We cannot aggregate because different processes will run different stacktraces and the above will also be consistent with the results from Erlang.

The fix is hopefully easy, it should be a matter of traversing the list, adding a line that shows the PID at the top.

Could you also please investigate if this issue happens on the other profilers? Thank you!

@josevalim if you are talking about cprof and fprof I wrote tests to prove that they are not affected, at least in this use case I observed. Just eprof.

Beautiful!

José Valimwww.plataformatec.com.br
http://www.plataformatec.com.br/Founder and Director of R&D

Ping. :)

On it, we will get you a PR by the EOD. Thanks Jose

On Feb 5, 2018, at 05:23, José Valim notifications@github.com wrote:

Ping. :)

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@costaraphael I tried your code snippet in pull request with the latest build still I'm getting this error

` ** (FunctionClauseError) no function clause matching in Mix.Tasks.Profile.Eprof.extract_results/1
Elixir --version : Elixir 1.7.0-dev (252974ed1) (compiled with OTP 20)

@m13m this is odd, this function was removed in the PR.

You sure you are running the correct build? If yes, is there any stacktrace for the error?

$ ./mix profile.eprof -e "Enum.each(1..2, fn n -> spawn(fn -> List.duplicate(1, n) end) end)" 
Warmup...
** (FunctionClauseError) no function clause matching in Mix.Tasks.Profile.Eprof.extract_results/1    
    The following arguments were given to Mix.Tasks.Profile.Eprof.extract_results/1:
        # 1
        [{#PID<0.89.0>, [{{:erlang, :spawn, 3}, {2, 13}}, {{:erlang, :spawn, 1}, {2, 1}}, {{:erlang, :apply, 2}, {1, 4}}, {{Enum, :"-each/2-fun-0-", 3}, {2, 1}}, {{Enum, :reduce_range_inc, 4}, {2, 2}}, {{Enum, :each, 2}, {1, 1}}, {{:elixir_compiler_1, :"-__FILE__/1-fun-1-", 1}, {2, 1}}, {{:elixir_compiler_1, :"-__FILE__/1-fun-2-", 0}, {1, 1}}]}, {#PID<0.90.0>, [{{:erlang, :apply, 2}, {1, 1}}, {{:elixir_compiler_1, :"-__FILE__/1-fun-0-", 1}, {1, 0}}, {{List, :duplicate, 2}, {1, 0}}, {{:lists, :duplicate, 3}, {2, 1}}, {{:lists, :duplicate, 2}, {1, 0}}]}, {#PID<0.91.0>, [{{:erlang, :apply, 2}, {1, 0}}, {{:elixir_compiler_1, :"-__FILE__/1-fun-0-", 1}, {1, 0}}, {{List, :duplicate, 2}, {1, 0}}, {{:lists, :duplicate, 3}, {3, 0}}, {{:lists, :duplicate, 2}, {1, 0}}]}]
    (mix) lib/mix/tasks/profile.eprof.ex:194: Mix.Tasks.Profile.Eprof.extract_results/1
    (mix) lib/mix/tasks/profile.eprof.ex:169: Mix.Tasks.Profile.Eprof.profile_and_analyse/2
    (mix) lib/mix/tasks/profile.eprof.ex:154: Mix.Tasks.Profile.Eprof.profile/2
    (elixir) lib/enum.ex:737: Enum."-each/2-lists^foreach/1-0-"/2
    (elixir) lib/enum.ex:737: Enum.each/2

Elixir 1.7.0-dev (252974ed1) (compiled with OTP 20)

cc @costaraphael

Try running like this:

# from the root of the Elixir repo
make
export PATH="$(pwd)/bin:$PATH" 
mix profile.eprof -e "Enum.each(1..2, fn n -> spawn(fn -> List.duplicate(1, n) end) end)"

@m13m It is because mix uses the elixir executable that's available in the environment. So simply running the mix executable in the bin folder does not ensure that you are using the newly compiled version that is in the same folder. That's why you have to export the PATH again prepending the newly compiled ones.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

conradwt picture conradwt  Â·  34Comments

wojtekmach picture wojtekmach  Â·  34Comments

p-adams picture p-adams  Â·  36Comments

josevalim picture josevalim  Â·  44Comments

josevalim picture josevalim  Â·  31Comments