fix native code crash when calling unloaded module with on_load function

Paul Guyot <>
Wed Jun 30 15:02:27 CEST 2010

Le 30 juin 2010 à 14:31, Mikael Pettersson a écrit :

> As reported in erlang-bugs, the following sequence of events crashes the VM:
> 1. Module M1 is loaded and in native mode.
> 2. Module M2 is not loaded, in emulated mode, and has an on_load function.
> 3. M1 calls some function in M2. This works.
> 4. M1 again calls some function in M2. This segfaults.
> The reason for the crash is that when the beam loader fixes up export
> entries after a successful on_load function call, it erroneously clears
> the ->code[3] field in that module's export entries.  This is redundant
> (no code in beam relies on ->code[3] being NULL), inconsistent with
> modules without on_load functions (there ->code[3] remains a valid beam
> instruction after the module is loaded), and breaks native code which needs
> the old ->address value in an export entry to remain valid after a module
> load step (before the load ->address points to ->code[3], after the load
> ->address points to the real code but uses of the old ->address value
> remain so ->code[3] must remain valid).
> Thus the fix for the crash is to simply not clear ->code[3].
> This patch fixes R14A and should also fix R13B04.
> (There does exist a performance bug in this area, but it is unrelated
> to the on_load feature so will be fixed separately.)

Hello Mikael,

Did you have a chance to check the patch I submitted to erlang-patch and which is available here:

My impression is that if we do not clear ep->code[3], this still points to call_error_handler. Instead of not clearing the value and relying to its initial assignation, I replaced the beam instruction to call_error_handler with a new beam instruction (call_from_hipe_stub) that simply jumps to the function.

> --- otp_src_R14A/erts/emulator/beam/beam_bif_load.c.~1~	2010-06-11 17:30:16.000000000 +0200
> +++ otp_src_R14A/erts/emulator/beam/beam_bif_load.c	2010-06-30 13:17:03.000000000 +0200
> @@ -337,7 +337,6 @@ BIF_RETTYPE finish_after_on_load_2(BIF_A
> 		ep->code[0] == BIF_ARG_1 &&
> 		ep->code[4] != 0) {
> 		ep->address = (void *) ep->code[4];
> -		ep->code[3] = 0;
> 		ep->code[4] = 0;
> 	    }
> 	}


+33.175000290 - 62 bis rue Gay-Lussac, 75005 Paris

More information about the erlang-patches mailing list