Description:
When compiled with gcc 3.4.1 MySQL 4.1 or 5.0 prints the following on start up:
kostja@oak:~/mysql/mysql-4.1-root> sql/mysqld
040708 4:42:59 Warning: setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals
mysqld: mf_keycache.c:295: init_key_cache: Assertion `key_cache_block_size >= 512' failed.
mysqld got signal 6;
<cut>
The assertion in init_key_cache fails because key_cache_block_size argument is 0.
This argument is taken from default key cache variable, which is supposed to be
initialized along with dflt_key_cache.
To be more precise, we've got the following calling sequence:
main
-> init_common_variables
-> mysql_init_variables
-> get_or_create_key_cache
-> create_key_cache
This one creates a key cache and partially initializes it from global dflt_key_cache_var.
As dflt_key_cache_var is not initizlied yet key_cache->param_block_size gets assigned 0.
Few lines later init_common_variables calls get_options, which in calls init_variables
to init dflt_key_cache_var and all created so far key cache variables with default
values. (I wonder why key cache creation is so compliacated)
This is done by means of the follo
if (options->var_type & GET_ASK_ADDR &&
(variable= (*getopt_get_addr)("", 0, options)))
init_one_value(options, variable, options->def_value);
wing check in mysys/my_getopt.c:
where options->var_type is of type enum get_opt_var_type
The problem is that this check is never true when compiled with gcc-3.4.1.
Despite that var_type is initialized with mask of (GET_ULONG | GET_ASK_ADDR),
it never gets combination of this values, only the first one.
In other words, as GET_ASK_ADDR is not in enum get_opt_var_type its value is never
assigned to var_type.
This is a simple test to of the problem:
kostja@oak:~> cat foo.cc
#include <stdio.h>
int main()
{
enum my_enum { ULONG= 1, DUMMY=2 };
my_enum e= (my_enum) (ULONG | 128);
printf("%d\n", (unsigned) e);
}
kostja@oak:~> g++ foo.cc; ./a.out
1
kostja@oak:~>
It turns out that such behaviour is 100% standard, which says:
An expression of arithmetic or enumeration type can be converted to enumeration type
explicitly. The value is unchanged if it is in the range of enumeration type; otherwise
the resulting enumeration value is unspecified.
Indeed, all earlier versions of gcc would print here 129, as does gcc 3.3.1:
kostja@oak:~> /usr/bin/g++ foo.cc;./a.out
129
How to repeat:
Compile with 3.4.1 and run
Suggested fix:
change type of my_options::var_type to ulong.
Check the rest of variables which accept bitmask of enum values to be of type ulong.