Firebird UDF on Linux resets the server when it is set to return by reference

I am trying to create a simple UDF for firebird on Linux (in C compiled with GCC). The problem is that when I set the "return mechanism" as "by reference", when I call the function, the server crashes. When it is "by value," there is no problem.

Here are the functions I'm trying to write in C:

It works:

double round(double *); 
double round(val)
double *val;
{
    *val = *val * 100;
    *val = (*val>= 0) ? (long)(*val + 0.5) : (long)(*val - 0.5);
    *val = *val / 100;
    return *val;
}

But this causes a server crash on a call:

char * proper_case(str)
char * str;
{
    return str;
}

Here is the DDL:

DECLARE EXTERNAL FUNCTION "ROUND"
    DOUBLE PRECISION
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'round' MODULE_NAME 'my_udfs.so';

DECLARE EXTERNAL FUNCTION PROPCASE
    CSTRING(10000)
RETURNS CSTRING(10000) FREE_IT
ENTRY_POINT 'proper_case' MODULE_NAME 'my_udfs.so';

I call the second function:

select propcase('abrakadabra') from rdb$database;

Firebird server crashes and the only error message I have is:

Statement failed, SQLSTATE = -902
Error reading data from the connection.

Can anyone advise? Any help would be appreciated!

The only information I forgot to provide is how I compile the .so file (maybe the key is here):

gcc -c -O -fpic my_udf.c
ld -G my_udf.o -lm -lc -o my_udf.so
cp my_udf.so /usr/lib/firebird/2.1/UDF/my_udfs.so
+5
2

AFAIK, Firebird ( , , FREE_IT), . ib_util_malloc(), ( , ):

char * proper_case(str)
char * str;
{
    char* ret = (char*)ib_util_malloc(strlen(str) + 1);
    strcpy(ret, str); // or run the actual logic here
    return ret;
}

EDIT: Firebird, UDF lib:

pChar EXPORT IB_UDF_lower(const char *s)
{
if (!s) return 0;

char* buf = (char *) ib_util_malloc(strlen(s) + 1);
char* p = buf;
while (*s) {
    if (*s >= 'A' && *s <= 'Z') {
        *p++ = *s++ - 'A' + 'a';
    }
    else
        *p++ = *s++;
}
*p = '\0';

return buf;
}
+2

, , . - /.

, .

UDF :

gcc -c -O -fpic my_udf.c
ld -G my_udf.o -lm -lc -o my_udf.so
cp my_udf.so /usr/lib/firebird/2.1/UDF/my_udfs.so

, Firebird . Python :

from ctypes import *
libc = CDLL("path/to/my_udf.so")
libc.IB_UDF_lower("abrakadabra")

Python "ib_util_malloc". "malloc", .

, , GCC , , .

0

All Articles