[erlang-questions] Hipe and memory alignment (Yikes! erts_alloc() returned misaligned address)
Mikael Pettersson
mikpe@REDACTED
Thu Aug 5 10:07:32 CEST 2010
Paul Guyot writes:
>
> Le 4 août 2010 à 23:19, Mikael Pettersson a écrit :
>
> > Now, it is possible that the alignment is wrong, esp. if the data
> > segment for whatever reason turns out to be tiny. Please rebuild
> > the erlang VM with the following patch and do what you normally do
> > to trigger the Yikes! message. It should tell us a little bit more
> > about the allocation parameters.
> >
> > FWIW, I've never heard of anyone being able to trigger this warning
> > before.
>
> Mikael,
>
> Thank you for your quick reply.
> I just invoke erl on FreeBSD 8.0 GENERIC running on amd64 with erlang configured with --enable-native-libs.
>
> Apprently, it's quite common with FreeBSD:
> http://www.erlang.org/cgi-bin/ezmlm-cgi/4/41055
> http://www.erlang.org/cgi-bin/ezmlm-cgi/4/41237
Still, that's only two messages, with $Subject not mentioning HiPE,
thus easily missed.
> Your patch reveals that the hipe loader tries to allocate 0 byte, which FreeBSD optimizes by giving only 2 bytes (where MacOS X 10.6 gives 16).
>
> > ./bin/erl
> Yikes! erts_alloc() returned 0x80169917e for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169917c for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169917a for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699176 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699174 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699172 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169916e for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169916c for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169916a for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699166 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699164 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699162 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169915e for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169915c for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169915a for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699156 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699154 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699152 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169914e for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169914c for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169914a for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699146 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699144 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699142 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169913e for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169913c for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169913a for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699136 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699134 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699132 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169912e for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169912c for align 8 nrbytes 0
> Erlang R14A (erts-5.8) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]
>
> Yikes! erts_alloc() returned 0x80169912a for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699126 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699124 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x801699122 for align 8 nrbytes 0
> Yikes! erts_alloc() returned 0x80169911e for align 8 nrbytes 0
> Eshell V5.8 (abort with ^G)
> Yikes! erts_alloc() returned 0x80169911c for align 8 nrbytes 0
> 1>
>
>
> Avoiding the allocation when data size is 0 (which means there are only terms in the constants map, I guess), just removes the warning.
>
> Paul
>
> diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
> index f289b81..d7747f6 100644
> --- a/lib/kernel/src/hipe_unified_loader.erl
> +++ b/lib/kernel/src/hipe_unified_loader.erl
> @@ -654,7 +654,10 @@ bif_address(Name) when is_atom(Name) ->
> %%
> create_data_segment(DataAlign, DataSize, DataList) ->
> %%io:format("create_data_segment: \nDataAlign: ~p\nDataSize: ~p\nDataList: ~p\n",[DataAlign,DataSize,DataList]),
> - DataAddress = hipe_bifs:alloc_data(DataAlign, DataSize),
> + DataAddress = case DataSize of
> + 0 -> 0;
> + _ -> hipe_bifs:alloc_data(DataAlign, DataSize)
> + end,
> enter_data(DataList, [], DataAddress, DataSize).
>
> enter_data(List, ConstMap2, DataAddress, DataSize) ->
>
>
The logic change is Ok but could be done either here or in the VM.
Doing it in the VM is safer.
Part of the problem is the poor warning message from the VM which
fails to clearly identify the context where it occurs. Concretely,
the message should include the string "hipe".
Therefore I'd rather do the logic change in the VM and at the same
time prefix the warning with __FUNCTION__ not "Yikes!".
Try this. I'll send it to erlang-patches if it works for you.
/Mikael
--- otp_src_R14A/erts/emulator/hipe/hipe_bif0.c.~1~ 2010-02-19 19:04:06.000000000 +0100
+++ otp_src_R14A/erts/emulator/hipe/hipe_bif0.c 2010-08-05 09:57:48.000000000 +0200
@@ -440,9 +440,12 @@ BIF_RETTYPE hipe_bifs_alloc_data_2(BIF_A
align != sizeof(long) && align != sizeof(double)))
BIF_ERROR(BIF_P, BADARG);
nrbytes = unsigned_val(BIF_ARG_2);
+ if (nrbytes == 0)
+ BIF_RET(make_small(0));
block = erts_alloc(ERTS_ALC_T_HIPE, nrbytes);
if ((unsigned long)block & (align-1))
- fprintf(stderr, "Yikes! erts_alloc() returned misaligned address %p\r\n", block);
+ fprintf(stderr, "%s: erts_alloc(%lu) returned %p which is not %lu-byte aligned\r\n",
+ __FUNCTION__, (unsigned long)nrbytes, block, (unsigned long)align);
BIF_RET(address_to_term(block, BIF_P));
}
More information about the erlang-questions
mailing list