MySQL UDF – wrong ELF class: ELFCLASS32

functionsMySQL

I'm having a problem creating a MySQL udf on my server (I was able to do it locally on OS X). I am compiling it like this on the server:

gcc $(mysql_config --cflags) -I /usr/include/mysql -I. -shared udf_median.cc -o udf_median.so

Here is the output of mysql_config –cflags

mysql_config --cflags
-I/usr/include/mysql -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -fasynchronous-unwind-tables  -fPIC -g -fabi-version=2 -fno-omit-frame-pointer -fno-strict-aliasing -DMY_PTHREAD_FASTMUTEX=1

So from what I can tell, MySQL is compiled for 32bit (it was done via x86_64 RPM). I had to install a bunch of different packages to get it to compile (32 bit packages, I think).

When I try to do:

CREATE AGGREGATE FUNCTION median RETURNS REAL SONAME 'udf_median.so';

I get:

Can't open shared library 'udf_median.so' (errno: 11 /usr/lib64/mysql/plugin/udf_median.so: wrong ELF class: ELFCLASS32)

From what I can tell this is a conflict between 32 and 64 bit but I'm not sure on how to fix it. I tried to put the .so in /usr/lib/mysql/plugin/ however MySQL doesn't seem to be recognizing that directory.

Anyone have any recommendations?

Edit

So if I try to compile it without the mysql_config like this:

gcc -shared -fPIC -I /usr/include/mysql -o udf_median.so udf_median.cc

I get these errors:

In file included from udf_median.cc:36:
/usr/include/mysql/m_string.h: In function ‘const uchar* skip_trailing_space(const uchar*, size_t)’:
/usr/include/mysql/m_string.h:261: error: cast from ‘const uchar*’ to ‘intptr’ loses precision
/usr/include/mysql/m_string.h:263: error: cast from ‘const uchar*’ to ‘intptr’ loses precision
/usr/include/mysql/m_string.h:265: error: cast from ‘const uchar*’ to ‘intptr’ loses precision

Best Answer

Unfortunately, mysql_config contains quite a bit of black magic and quite a bit of blatant sketchiness. It's notoriously untrustworthy if you have more than one copy of it or the version doesn't match your server build.

Unfortunately, too, if you're using one from a distro (not official binaries) then that utility may not even be in the same package as the server... it's bundled with the client, which could easily be 32 bit and work just fine with a 64-bit server.

$ mysql_config
The program 'mysql_config' can be found in the following packages:
 * libmysqlclient-dev
 * libmariadbclient-dev
Try: sudo apt-get install <selected package>

Not confidence-inspiring.

$ mysql_config --version
5.5.40

Neat, I don't even have server on this particular system, and never have.

So, that gives you a sense of how much hocus pocus this little utility can sometimes offer up.

Fundamentally, though, there's this: wrong ELF class: ELFCLASS32 means you compiled the plugin for 32 bit, but your server is indeed 64 bit.

The missing piece from your compiler flags is -m64. If you add that and remove the -m32 (I'm not sure where that's coming from... mysql_config doesn't include either one on my test system) then you should be able to get that plugin to compile and install.

You have the plugin in the correct directory, or the system wouldn't have found the file to complain about the architecture it was compiled for.