diff options
author | Björn Gustavsson <[email protected]> | 2016-09-05 16:16:23 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-09-14 12:54:54 +0200 |
commit | c70ca686fe269db6079a2ca1c7e09cdfc0cfa903 (patch) | |
tree | fa9d97ff6a1f50a7532f4ebe38f70937bc035359 /erts/emulator/beam/module.c | |
parent | 176b7c94e4146a65ccd2bd729d58487098dddd9c (diff) | |
download | otp-c70ca686fe269db6079a2ca1c7e09cdfc0cfa903.tar.gz otp-c70ca686fe269db6079a2ca1c7e09cdfc0cfa903.tar.bz2 otp-c70ca686fe269db6079a2ca1c7e09cdfc0cfa903.zip |
Don't leak old code when loading a modules with an on_load function
Normally, calling code:delete/1 before re-loading the code for a
module is unnecessary but causes no problem.
But there will be be problems if the new code has an on_load function.
Code with an on_load function will always be loaded as old code
to allowed it to be easily purged if the on_load function would fail.
If the on_load function succeeds, the old and current code will be
swapped.
So in the scenario where code:delete/1 has been called explicitly,
there is old code but no current code. Loading code with an
on_load function will cause the reference to the old code to be
overwritten. That will at best cause a memory leak, and at worst
an emulator crash (especially if NIFs are involved).
To avoid that situation, we will put the code with the on_load
function in a special, third slot in Module.
ERL-240
Diffstat (limited to 'erts/emulator/beam/module.c')
-rw-r--r-- | erts/emulator/beam/module.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 3eb11f1693..4f36377450 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -85,6 +85,7 @@ static Module* module_alloc(Module* tmpl) obj->old.num_breakpoints = 0; obj->curr.num_traced_exports = 0; obj->old.num_traced_exports = 0; + obj->on_load = 0; return obj; } @@ -201,6 +202,7 @@ void module_start_staging(void) dst_mod->curr = src_mod->curr; dst_mod->old = src_mod->old; + dst_mod->on_load = src_mod->on_load; } /* @@ -214,6 +216,7 @@ void module_start_staging(void) dst_mod->curr = src_mod->curr; dst_mod->old = src_mod->old; + dst_mod->on_load = src_mod->on_load; } newsz = index_table_sz(dst); erts_smp_atomic_add_nob(&tot_module_bytes, (newsz - oldsz)); |