Stratus3D/eflambe

Help using eflambe on Elixir

Opened this issue · 11 comments

Hi,

thank you for your work, I'm giving it a try but face errors I can't interpret.

I run my application by building a release, executing it and then using the remote command to interact with the VM.

There, I run the following command:

 :eflambe.capture({Wsdataselect.Controller, :manage_query, 2}, 1, [output_format: :brendan_gregg, open: :speedscope])
{:error,
 {:undef,
  [
    {:meck, :new, [Wsdataselect.Controller, [:unstick, :passthrough]], []},
    {:eflambe_meck, :shim, 4,
     [
       file: ~c"/home/schaeffj/factory/vcs/wsdataselect/deps/eflambe/src/eflambe_meck.erl",
       line: 28
     ]},
    {:eflambe_server, :init, 1,
     [
       file: ~c"/home/schaeffj/factory/vcs/wsdataselect/deps/eflambe/src/eflambe_server.erl",
       line: 160
     ]},
    {:gen_server, :init_it, 2, [file: ~c"gen_server.erl", line: 980]},
    {:gen_server, :init_it, 6, [file: ~c"gen_server.erl", line: 935]},
    {:proc_lib, :init_p_do_apply, 3, [file: ~c"proc_lib.erl", line: 241]}
  ]}}

I use Elixir 1.16 on OTP 26

thanks

hi @jschaeff that error seems to be indicating that meck:new/2 is undefined. Can you check and see if meck is contained in your release? meck is a runtime dependency.

I think it came as a dependency of eflambe.

 grep meck mix.lock         
  "eflambe": {:hex, :eflambe, "0.3.1", "ef0a35084fad1f50744496730a9662782c0a9ebf449d3e03143e23295c5926ea", [:rebar3], [{:meck, "0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "58d5997be606d4e269e9e9705338e055281fdf3e4935cc902c8908e9e4516c5f"},
  "meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},

I can also find it in my _build/dev/lib directory.

And in iex, seems to be known:

Interactive Elixir (1.16.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :meck.new
** (UndefinedFunctionError) function :meck.new/0 is undefined or private. Did you mean:

      * new/1
      * new/2

    (meck 0.9.2) :meck.new()
    iex:1: (file)

Is that iex shell running in your release?

I can also find it in my _build/dev/lib directory.

That is your build directory for local dev. Releases are typically generated at _build/<env>/rel/<app>. Please check and confirm meck is part of your release, as that is where you are trying to use it.

You've pinned it. Thank you.

I needed to explicitely put meck in my mix.exs in order to be included in the release. Is this normal ?

Now, with meck explicitely declared and included in the release, the error message changed:

iex(wsdataselect@vogon)3> :eflambe.capture({Wsdataselect.Controller, :manage_query, 2}, 1, [output_format: :brendan_gregg, open: :speedscope])
{:error, {:abstract_code_not_found, Wsdataselect.Controller}}

Same error message if I try with a standard module:

iex(wsdataselect@vogon)1>  :eflambe.capture({Enum, :sort, 1}, 1,  [output_format: :brendan_gregg, open: :speedscope])
{:error, {:abstract_code_not_found, Enum}}

eflambe declares meck as a regular dependency, but the elfambe.app.src file doesn't list meck in the list of applications. That is probably why. I will update the code.

error:{abstract_code_not_found, Mod}
The option passthrough was used but the original module has no abstract code which can be called. Make sure the module is compiled with the compiler option debug_info.

This library can only work with code compiled with debug_info, regardless of where it is run.

Thanks again for your help, I really appreciate it.

Searching documentation about debug_info, I made the following:

In mix.exs:

  def project do
    [
      app: :wsdataselect,
      ...
      elixirc_options: [debug_info: Mix.env() == :dev]
    ]
  end

Cleaned up _build directory and built the release in dev environment, and run it.

Finaly, connect remotely to the BEAM VM

_build/dev/rel/wsdataselect/bin/wsdataselect remote
Erlang/OTP 26 [erts-14.2.5] [source] [64-bit] [smp:20:20] [ds:20:20:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.16.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(wsdataselect@vogon)1> Code.get_compiler_option(:debug_info)
true
iex(wsdataselect@vogon)2> :eflambe.capture({Wsdataselect.Controller, :manage_query, 2}, 1, [output_format: :brendan_gregg, open: :speedscope])
{:error, {:abstract_code_not_found, Wsdataselect.Controller}}
iex(wsdataselect@vogon)3> 

still no luck ...

I have the fealing I do not do it the right way ...

Check out the :strip_beams option for Mix releases - https://hexdocs.pm/mix/Mix.Tasks.Release.html#module-options It defaults to true and strip metadata and debug info. That could be the problem.

I'm looking into this. Thank you.

Side question: all those settings needed, make me wonder if using eflambe into a release is the right way to do ? Sould I use it another way ? Using mix run for instance ? If yes, how to do this ?

Cheers

You nailed it. I added strip_beams: false in my mix.exs and got a nice bggg file. transformed it to svg using https://github.com/brendangregg/FlameGraph and could work with the output.

Thanks again for your work and support.

Still I wonder if there is a more straightforward way to use eflambe ? Would you find it usefull if I write some supplementary exemple in your project's README for running this in an elixir project ?

Uuhhh, I just saw your video tutorial ... I should have started from there. https://www.youtube.com/watch?v=fRNdej-UXKQ

You are welcome to contribute docs (in readme or Erlang files). I figured most folks would not be using eflambe in releases so I didn't document that in the readme. It might be a good addition to the Usage section though.