Skip to content

Conversation

@jechol
Copy link
Contributor

@jechol jechol commented Dec 10, 2025

Problem

Tools like Kino modify dbg_callback at runtime to customize dbg/2 behavior. Previously, this runtime modification would trigger unnecessary recompilation on server start, even though the config hadn't actually changed.

This is problematic for Phoenix projects with code_reloader: true.

Solution

Store the initial dbg_callback value in initial_dbg_callback when the :elixir app starts. Mix compiler now compares against initial_dbg_callback instead of dbg_callback.

The key insight is that dbg/2 is a compile-time macro, so runtime modifications to dbg_callback don't affect already-compiled code. Only actual config changes (reflected in initial_dbg_callback) should trigger recompilation.

Changes

  • lib/elixir/src/elixir.erl: Store initial_dbg_callback on app start
  • lib/mix/lib/mix/compilers/elixir.ex: Compare against initial_dbg_callback
  • Added test case for runtime modification scenario

I'm currently using Elixir 1.19.4 with Kino in a Phoenix project and experiencing this issue. A backport to v1.19 would be appreciated.

@jechol jechol force-pushed the fix-dbg-callback-runtime-modification branch 2 times, most recently from ede3662 to 50540bb Compare December 10, 2025 07:36
When :elixir app starts, store the dbg_callback value in dbg_callback_initial.
Mix compiler now compares against dbg_callback_initial instead of dbg_callback.

This prevents unnecessary recompilation when tools like Kino modify
dbg_callback at runtime. Previously, such runtime modifications would trigger
a full recompilation of all files using dbg/2, even though the config hadn't
actually changed.

The key insight is that dbg/2 is a compile-time macro, so runtime modifications
to dbg_callback don't affect already-compiled code. Only actual config changes
(reflected in dbg_callback_initial) should trigger recompilation.

This is a more general solution than detecting specific wrapping patterns,
as it works with any tool that modifies dbg_callback at runtime.
@jechol jechol force-pushed the fix-dbg-callback-runtime-modification branch from 50540bb to a260b1f Compare December 10, 2025 07:37
@jechol jechol changed the title Store initial dbg_callback to ignore runtime modifications Fix unnecessary recompilation when dbg_callback is modified at runtime Dec 10, 2025
@josevalim
Copy link
Member

Great find @jechol! Really nicely done change too. I have added a comment on where to best store it and we can ship this!

Per José's feedback, store initial_dbg_callback in elixir_config
instead of using application:set_env. This is more consistent with
how other Elixir internal configs are managed.
@jechol
Copy link
Contributor Author

jechol commented Dec 10, 2025

Done! Updated to use elixir_config instead of application env. Thanks for the quick review!

@josevalim josevalim merged commit c80a3b1 into elixir-lang:main Dec 10, 2025
11 checks passed
@josevalim
Copy link
Member

💚 💙 💜 💛 ❤️

josevalim pushed a commit that referenced this pull request Dec 10, 2025
#15007)

When :elixir app starts, store the dbg_callback value in dbg_callback_initial.
Mix compiler now compares against dbg_callback_initial instead of dbg_callback.

This prevents unnecessary recompilation when tools like Kino modify
dbg_callback at runtime. Previously, such runtime modifications would trigger
a full recompilation of all files using dbg/2, even though the config hadn't
actually changed.

The key insight is that dbg/2 is a compile-time macro, so runtime modifications
to dbg_callback don't affect already-compiled code. Only actual config changes
(reflected in dbg_callback_initial) should trigger recompilation.

This is a more general solution than detecting specific wrapping patterns,
as it works with any tool that modifies dbg_callback at runtime.
@josevalim
Copy link
Member

Backported it too!

@jechol jechol deleted the fix-dbg-callback-runtime-modification branch December 10, 2025 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants