onegrx
Cannot enter pry prompt with dbg or IEx.pry()
Hello,
I am trying to pry some code and the request continues without entering pry(1)> prompt. I use require IEx; IEx.pry or dbg with iex --dbg pry -S mix phx.server . I can see request to pry in the terminal, but after clicking Y it just continues. It seems the same as in I cannot get IEx.pry() to work correctly, however I use Elixir 1.16.0 with OTP 26 (erlang 26.1.2). Also tested on 1.17-dev with the same result.
The problem has occurred in my project, but I also created a demo Phoenix app with mix phx.new demo and only changed a PageController to:
def home(conn, _params) do
# The home page is often custom made,
# so skip the default app layout.
conn
|> foo()
|> render(:home, layout: false)
end
defp foo(conn) do
"Pry is not working?"
|> String.split()
|> Enum.count()
|> dbg
conn
end
When running iex --dbg pry -S mix phx.server the pry console doesn’t show up. However on the other project with Elixir 1.14 it works (dbg was opt-out back then so I just use iex -S mix phx.server). What am I doing wrong?
Marked As Solved
RomanKotov
Possibly newer versions of Elixir using uniform interface for both pry and iex shells (or even using the same code for both cases). I was not aware of this, and even did not notice it. I agree that it is nice to have a separate prompt for debugger - it helps to distinguish a mode, and less confusing.
But it is not critical for me, as long as debugging-related features work.
It seems that Elixir 1.14 had a prefix for pry. But starting from Elixir 1.15.0, pry does not change it, and uses a default one. The same is with newer versions. The pry prefix was removed in this commit. The part of commit description mentions pry(N) will now be styled as iex(N).
Also Liked
josevalim
Recent Erlang versions allow multiline prompts but, to enable it, we no longer can change the prompt on the fly, hence the change.
RomanKotov
Hi, welcome to Elixirforum!
I tried to reproduce this, but it worked for me.
Steps I tried:
- Install Elixir
1.16.0-otp26via asdf. - Install Erlang
26.1.2via asdf. - Create project via
mix phx.new demo --no-ecto. Did not want to set up the database. I havephx.newinstaller for Phoenix1.7.10. - Added
.tool-versionsfile to the root ofdemoproject with relevant versions of Elixir and Erlang. - Installed dependencies.
- Updated the code for
lib/demo_web/controllers/page_controller.exwith your example. - Started the server with
iex --dbg pry -S mix phx.server. - Visited
http://localhost:4000, and reached a breakpoint. It worked for bothdbgandrequire IEx; IEx.pry.
Tested on macOS Sonoma 14.4.1.
Can you try to reproduce the same issue on the other device?
Possibly via an Elixir Docker (Podman) container. If it works there, then possibly something is with your local environment.
I remember it was an similar issue with Elixir 1.15.0 and OTP 25, but it is already resolved.
RomanKotov
Have tested your code on MacOS Sonoma 14.4.1 on MacMini 2018, Intel based.
It worked for me.
What I have tried:
- Cloned a repo
- Installed dependencies
- Started the app with
iex --dbg pry -S mix phx.server - Visited
http://localhost:4000/and reached a breakpoint. - Stopped the application.
- Added another breakpoint (2) with
require IEx; IEx.pry(). - Started the application with
iex -S mix phx.serverand refreshed a page in browser. - Debugger stopped at breakpoint (2).
As I remember, --dbg pry argument appeared at Elixir 1.15.0. dbg macro does not stop at breakpoint without it (though it stopped in Elixir 1.14.x). I mainly use dbg for debug tracing in the code and require IEx; IEx.pry() to set breakpoints (as it always worked).
I think it is not related to the OS, but to the local environment.
Can you try to run your code inside the Docker/Podman?
- Start an Elixir container, something like
docker run --rm -it -p 127.0.0.1:4000:4000 elixir:1.16 bash - Install a git there
apt update && apt install git - Clone your repo
git clone https://github.com/onegrx/pry.git - Visit a repo and install dependencies
cd pry; mix deps.get - Possibly you will want to comment a repo in your configuration. There is no Postgres inside a container. It is not relevant by the way.
- Start the application via
iex --dbg pry -S mix phx.server. - Visit
http://localhost:4000in your browser.
I have written previous commands just to show steps and have not tested them (have not installed Docker on my machine and deleted Podman some time ago). Possibly you will need to install extra dependencies (like PostgreSQL). It should be easy to find solutions for them in the Internet.
I have recently got an interesting error. I played with Erlang and added custom configuration file for it. I have printed a message inside it. When I installed a dependency (erlexec) - the installation process somehow took this message and tried to install dependencies through it. It failed, and I had to update my configuration files. Possibly something similar is in your case, so I suggested to try the same on the other machine.
Erlang looks for configuration in a couple of locations:
~/.erlang~/Library/Application Support/erlang/.erlang- IEX uses
~/.iex.exs - Environment variable
ERL_AFLAGS(you can see its contents viaecho $ERL_AFLAGS). I have added this variable to store shell history.
If breakpoints will work inside the Docker/Podman container, then something is with your local configuration.
RomanKotov
You may also want to update a listening address in the config/dev.exs here inside a container to:
http: [ip: {0, 0, 0, 0}, port: 4000]
It will allow you to reach the server from outside the container.
Have tried to reproduce with Podman on Apple Silicon:
- installed Podman (
brew install podman). - Prepared a machine (
podman machine init). - Started a machine (
podman machine start). - Started the container with
podman run --rm -it -p 127.0.0.1:4000:4000 elixir:1.16 bash. I use--rmflag here, so the container will be deleted after I log out. If you want to keep a container - just remove this flag. - Git is already installed, cloned the repo.
- Tried to install the dependencies, but got this error, and applied the fix. It happens on Apple Silicon chips, so it should be fine on Intel-based one.
- Installed the dependencies via
mix deps.get. - Installed vim to edit files. You may use nano, if you are not familiar with vim (
apt install nano). - Edited the
config/dev.exs- allowed remote connections (ip: {0, 0, 0, 0}thing from above). - Commented
Demo.Repoinlib/demo/application.ex(sole link from my previous message). - Started the application via
iex --dbg pry -S mix phx.server. - Visited
http://localhost:4000in browser. Reached the breakpoint.
RomanKotov
Here is my output:
Interactive Elixir (1.16.2) - press Ctrl+C to exit (type h() ENTER for help)
Rebuilding...
Done in 253ms.
[info] GET /
[debug] Processing with DemoWeb.PageController.home/2
Parameters: %{}
Pipelines: [:browser]
Request to pry #PID<0.664.0> at DemoWeb.PageController.foo/1 (lib/demo_web/controllers/page_controller.ex:18)
Request to pry #PID<0.664.0> at DemoWeb.PageController.foo/1 (lib/demo_web/controllers/page_controller.ex:18)
15: |> String.split()
16: |> Enum.count()
17: |> IO.inspect()
18: |> dbg
19:
20: conn
21: end
Allow? [Yn] y
Interactive Elixir (1.16.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> whereami
Location: lib/demo_web/controllers/page_controller.ex:18
16: |> Enum.count()
17: |> IO.inspect()
18: |> dbg
19:
20: conn
(demo 0.1.0) lib/demo_web/controllers/page_controller.ex:18: DemoWeb.PageController.foo/1
(demo 0.1.0) lib/demo_web/controllers/page_controller.ex:9: DemoWeb.PageController.home/2
(demo 0.1.0) lib/demo_web/controllers/page_controller.ex:1: DemoWeb.PageController.action/2
(demo 0.1.0) lib/demo_web/controllers/page_controller.ex:1: DemoWeb.PageController.phoenix_controller_pipeline/2
(phoenix 1.7.11) lib/phoenix/router.ex:484: Phoenix.Router.__call__/5
(demo 0.1.0) lib/demo_web/endpoint.ex:1: DemoWeb.Endpoint.plug_builder_call/2
(demo 0.1.0) deps/plug/lib/plug/debugger.ex:136: DemoWeb.Endpoint."call (overridable 3)"/2
(demo 0.1.0) lib/demo_web/endpoint.ex:1: DemoWeb.Endpoint.call/2
(phoenix 1.7.11) lib/phoenix/endpoint/sync_code_reload_plug.ex:22: Phoenix.Endpoint.SyncCodeReloadPlug.do_call/4
(bandit 1.4.1) lib/bandit/pipeline.ex:150: Bandit.Pipeline.call_plug!/2
(bandit 1.4.1) lib/bandit/pipeline.ex:36: Bandit.Pipeline.run/4
(bandit 1.4.1) lib/bandit/http1/handler.ex:12: Bandit.HTTP1.Handler.handle_data/3
(bandit 1.4.1) lib/bandit/delegating_handler.ex:18: Bandit.DelegatingHandler.handle_data/3
(bandit 1.4.1) /pry/deps/thousand_island/lib/thousand_island/handler.ex:411: Bandit.DelegatingHandler.handle_continue/2
(stdlib 5.2.1) gen_server.erl:1085: :gen_server.try_handle_continue/3
(stdlib 5.2.1) gen_server.erl:995: :gen_server.loop/7
(stdlib 5.2.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
iex(2)>
Have taken it from container:
- Started the application
- Visited
http://localhost:4000in browser. - Reached a breakpoint, pressed
Y - got into debugger. The debugger did not change the prompt to
pry>, but keptiex>one. - I was able to run debugging-related commands (for example
whereami) in the context of debugged process, though the prompt is stilliex>.
Great, that it is not the case.
I see from your example, that you have reached the breakpoint in Elixir 1.16 too. Can you enter debugger-related commands from there (for example whereami)? If yes, then your debugger is working.
Do I understand correctly, that you expected to see the pry> prompt instead of iex> there (and thought pry did not work)?







