[erlang-bugs] HiPE crash with crypto and R14A

Paul Guyot pguyot@REDACTED
Sun Jun 27 01:09:04 CEST 2010


Le 26 juin 2010 à 20:37, Paul Davis a écrit :

> Confirmed on Ubuntu 10.04 with R14A from source. I grabbed a backtrace
> as well but it isn't very informative.
> 
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 0xb6484b70 (LWP 23582)]
> 0x00000000 in ?? ()
> (gdb) bt
> #0  0x00000000 in ?? ()
> #1  0xb763b5a4 in ?? ()
> #2  0xb74e82c4 in ?? ()
> Backtrace stopped: previous frame inner to this frame (corrupt stack?)

The crash is not (directly) caused by a NIF but by on_load used on crypto (to load the NIFs). Here is a simpler test case:

---- dummy_with_on_load.erl ----
-module(dummy_with_on_load).
-on_load(on_load/0).
-export([foo/0]).

foo() -> <<"hello">>.
on_load() -> ok.
----

---- hipe_crash.erl ----
-module(hipe_crash).
-export([crash/0]).

crash() ->
    dummy_with_on_load:foo(),
    dummy_with_on_load:foo().
----

erlc dummy_with_on_load.erl
erlc +native hipe_crash.erl
erl -eval 'hipe_crash:crash()'

Notice the lack of +native for dummy_with_on_load.erl, hence it's not (exactly) what the following workaround is about:
http://github.com/erlang/otp/commit/3befa76d1e24108acb5cb757157c2fb3384a8e51

Yet, it might be the same bug.... The crash can be avoided by commenting the following line:

	/*
	 * The on_load function succeded. Fix up export entries.
	 */
	for (i = 0; i < export_list_size(); i++) {
	    Export *ep = export_list(i);
	    if (ep != NULL &&
		ep->code[0] == BIF_ARG_1 &&
		ep->code[4] != 0) {
		ep->address = (void *) ep->code[4];
		ep->code[3] = 0;			<-----
		ep->code[4] = 0;
	    }
	}

http://github.com/erlang/otp/blob/dev/erts/emulator/beam/beam_bif_load.c#L340

I just do not understand yet why resetting code[3] to 0 fixes up the export entry.

The emulator has a copy of the value of ep->code[3] for the exported function (foo in this test case, sha in the previous test case) before on_load is called. on_load is called, ep->code[3] is reset. The first call succeeds nevertheless because there is a copy. However, the second call fails because it is now a call to 0.

Paul



More information about the erlang-bugs mailing list