In Erlang, if a process is running code from module a when module a is reloaded, it doesn't get automatically upgraded to the new version. The old version of the code is kept as long as any process is using it, and the process is said to be running "old code".

However, only one old version is kept, so if the process doesn't switch to the new version before the module is reloaded for a second time, the process will be killed by the code server. This can be confusing, as there is often no trace of the process dying, and even if there is, you only get to know that the process was killed, but not why.

While chasing down a problem related to this, I came up with this patch to the code server:

diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 00ad923..c4d5fd6 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1414,6 +1414,7 @@ do_purge(Mod0) ->
 do_purge([P|Ps], Mod, Purged) ->
     case erlang:check_process_code(P, Mod) of
    true ->
+       catch info_msg("Killing ~p for old code from ~p", [P, Mod]),
        Ref = erlang:monitor(process, P),
        exit(P, kill),
        receive

That led me straight to the module that was being reloaded, and let me fix the problem by ensuring that the process switched to new code.

This patch is probably not suitable for inclusion in the official Erlang/OTP sources, but I hope it can be useful when developing.

How can you know when the code server kills your process, and why?