| 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: | |
| Category: | MySQL Server: User-defined functions ( UDF ) | Severity: | S2 (Serious) |
| Version: | 5.1.25-rc-log | OS: | Linux (Gentoo) |
| Assigned to: | Hartmut Holzgraefe | CPU Architecture: | Any |
| Tags: | drop function, udf | ||
[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)

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