I have a problem described in the title. I have an Edify language parser that runs without errors when I building it on arm but fails when I try to use it with x86. I traced segfault to yy_scan_bytes function, more precisely to this code:
YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) {
YY_BUFFER_STATE b;
char * buf;
yy_size_t n;
int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
buf = (char *) yyalloc(n );
if ( ! buf ) {
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
}
for ( i = 0; i < _yybytes_len; ++i ) {
buf[i] = yybytes[i]; // <==========
}
The full code is here: https://github.com/twaik/edify_x86_failing_code I've got it from AROMA Installer source. That's everything I discovered after debug. Thanks.
Trying to build your code gives me these errors:
main.c: In function ‘parse_string’: main.c:27:5: warning: implicit declaration of function ‘yy_switch_to_buffer’ [-W implicit-function-declaration] yy_switch_to_buffer(yy_scan_string(str)); ^~~~~~~~~~~~~~~~~~~ main.c:27:25: warning: implicit declaration of function ‘yy_scan_string’ [-Wimplicit-function-declaration] yy_switch_to_buffer(yy_scan_string(str));
That means that the compiler assumes that yy_switch_to_buffer()
and yy_scan_string()
return an int
, as it does for all functions that are not declared before use (as per the c89 standard). But that is not the case (the first returns void
, and the second a pointer (YY_BUFFER_STATE
)). Notice that on x86_64, the size of a pointer is not the same as the size of an int
.
Adding some band-aid prototypes like
void yy_switch_to_buffer(void*);
void *yy_scan_string(const char*);
to main.c
, before their use in parse_string()
may stop the segfaulting.
A better fix would be to arrange in the Makefile that the lexer be run with the --header-file=lex-header.h
option, and then include lex-header.h
from main.c
. Or even better, wrap all lex-specific code in some simple functions, and put the prototypes of those functions in a header included from both main.c
and the *.l
file.