[erlang-bugs] Bug in HiPE compiled compiler

Kostis Sagonas kostis@REDACTED
Wed Jul 7 09:44:31 CEST 2010


     case atom_to_list(F) of
         "yeccpars2" ++ _ ->
             {syntax_error, Token};
         "yeccgoto_" ++ SymbolL ->
             {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL),
             {missing_in_goto_table, Symbol, State}
     end.
Adam Lindberg wrote:
> Hi,
> 
> The following module produces a compiler error in R13B03 and R13B04:
> 
> -module(a).
> f() -> hipe is broken.
> 
> 
> The error is, just as expected:
> $> erlc a.erl
> a.erl:2: syntax error before: is
> 
> 
> However, if the compiler is HiPE compiled (with NATIVE_LIBS_ENABLED=yes), the following error occurs:
> 
> $> erlc a.erl
> a.erl:none: internal error in parse_module;
> crash reason: {function_clause,[{erl_parse,yeccpars2_6,7},
>                                 {erl_parse,yeccpars0,5},
>                                 {epp,parse_file,1},
>                                 {epp,parse_file,1},
>                                 {epp,parse_file,3},
>                                 {compile,parse_module,1},
>                                 {compile,'-internal_comp/4-anonymous-1-',2},
>                                 {compile,fold_comp,3}]}

I've investigated this issue.

The good news is that there is no problem in the code generated by the 
hipe compiler.

Instead, the problem is that the code of yeccpre.hrl heavily relies on 
generated exceptions having stack traces of particular forms, which is 
currently not something that native code guarantees.

In parsetools/include/yeccpre.hrl there is code which reads:

yecc_error_type(function_clause, [{?MODULE,F,[State,_,_,_,Token,_,_]} | 
_]) ->
     case atom_to_list(F) of
         "yeccpars2" ++ _ ->
             {syntax_error, Token};
         "yeccgoto_" ++ SymbolL ->
             {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL),
             {missing_in_goto_table, Symbol, State}
     end.

while the stack trace that native-compiled code generates has the form:

yecc_error_type(function_clause, [{?MODULE,F,7} | _]) ->

If one can live with uninformative syntax errors, one solution is to add 
such a clause for yecc_error_type/2 and return some other error terms 
for this case, which should then be handled in function yeccparse0/5. 
In other words, add a clause:

yecc_error_type(function_clause, [{?MODULE,F,7} | _]) ->
     case atom_to_list(F) of
         "yeccpars2" ++ _ ->
             syntax_error;
         "yeccgoto_" ++ SymbolL ->
             {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL),
             {missing_in_goto_table, Symbol}
     end.

This is relatively easy.

Another solution is to add an attribute to yeccpre.hrl that prohibits 
native code compilation of this module:

-compile(no_native).

Perhaps this is the best solution for the time being.

Of course, a better solution would be for native code to generate the 
exact same stack traces as BEAM code, but this is very complicated and 
will not happen soon (if at all).  However, even if that were available, 
I still believe that writing Erlang code that relies on stack traces 
having a specific form is not kosher.

I will let the OTP folks at Ericsson take a decision on what to do about 
this one.

Kostis


More information about the erlang-bugs mailing list