Bug #37347 MySQL server segfault when dropping an UDF function
Submitted: 11 Jun 2008 14:45 Modified: 15 Jun 2008 12:26
Reporter: Patrick Allaert Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: User-defined functions ( UDF ) Severity:S2 (Serious)
Version:5.1.25-rc-log OS:Linux (Gentoo)
Assigned to: Hartmut Holzgraefe
Tags: drop function, udf

[11 Jun 2008 14:45] Patrick Allaert
Description:
MySQL segfault when dropping an UDF function when the shared object file has been changed on the file system.

How to repeat:
Create a dummy UDF file (lightspeed.c):

char lightspeed_init() {
    return 0;
}

long long lightspeed() {
    return 299792458;
}

void lightspeed_deinit() {
}

Compile it with:

gcc -fPIC -o lightspeed.so lightspeed.c

Copy the file and create the function.

recompile it, now with:

gcc -O2 -fPIC -o lightspeed.so lightspeed.c

Copy the file again

drop the function with:

drop function lightspeed;
ERROR 2013 (HY000): Lost connection to MySQL server during query

On server side I see a segmentation fault error
[11 Jun 2008 15:21] Patrick Allaert
C file used for the UDF

Attachment: lightspeed.c (text/x-csrc), 325 bytes.

[15 Jun 2008 12:26] Hartmut Holzgraefe
This is expected behavior due to the library init/deinit functions that the gnu linker puts into the shared library which are then called on dlopen() and dlclose(). The page the _fini() shutdown function is on is often only swapped in when the library is actually unloaded and if the library has changed already the _fini() function is then most likely no longer at the expected position -> invalid code is called -> crash.

You can work around this by adding -nostartfiles to your linker options, for me with

  gcc -shared -nostartfiles -fPIC -O2 -o lightspeed.so lightspeed.c

loading and dropping worked fine even when replacing the lightspeed.so with one compiled with a different -O# setting between CREATE and DROP.

Checking with "nm lightspeed.so" you can see that the lightspeed.so created with -nostartfiles has way less symbols in it which also shows by its size (~1.6K instead of ~10K on my system).

In general it is best practice though to first drop all functions from a UDF library and only then to replace the .so file.
[15 Jun 2008 12:45] Hartmut Holzgraefe
And for those using autotools and libtool:

here you need to add "-Xcompiler -nostartfiles" to the libname_la_LDFLAGS

(i'm about to change CodeGen_MySQL_UDF accordingly)