LINUX.ORG.RU

Почему Firebird при обращении к UDF закрывает соединение?!


0

1

Господа! Помогите разобраться.

Есть функция:

[user@myhost udf]$ cat str_simple.c
#include <string.h>
#include "/opt/firebird/include/ib_util.h"

char *str_simple(char *str) {

    char *result = ib_util_malloc(strlen(str) + 1);
    memcpy(result, str, strlen(str) + 1);
    return result;
}
[user@myhost udf]$
Для сборки:
[user@myhost udf]$ cat makeudf 
#!/bin/bash

gcc -c -O -fpic $1.c &&
ld -G $1.o -lm -lc -o $1.so &&
rm $1.o &&
mv $1.so /opt/firebird/UDF
[user@myhost udf]$ ./makeudf  str_simple
[user@myhost udf]$
В базе функция объявлена так:
DECLARE EXTERNAL FUNCTION str_simple
CSTRING(256)
RETURNS CSTRING(256) FREE_IT
ENTRY_POINT 'str_simple' MODULE_NAME 'str_simple';
Дальше:
[user@myhost database]$ /opt/firebird/bin/isql base.gdb -USER sysdba -PASS masterkey
Database:  base.gdb, User: sysdba
SQL> SELECT STR_SIMPLE('Текст') FROM RDB$FIELDS;

STR_SIMPLE

=============================================================================== 
Statement failed, SQLSTATE = 08006
Error reading data from the connection.
С чего вдруг закрывается соединение?

Всё это в Linux 3.1.9-2-ARCH ... x86_64 и Firebird-SuperServer 2.5.1.26351_0-4

Ответ на: комментарий от visual

Точно есть в той строке которая подается на вход. Сделал вот так:

[user@myhost udf]$ cat str_simple.c 
#include <stdio.h>
#include <string.h>
#include "/opt/firebird/include/ib_util.h"

void dump(char *str) {

    FILE *file = fopen("file.txt", "a");

    if (file != NULL) {

        int index;
        for (index = 0; index <= strlen(str); index++)
        fprintf(file, "%02x", *(str + index));
        fprintf(file, "\n");
        fclose(file);
    }
}

char *str_simple(char *content) {

    dump(content);
    char *result = ib_util_malloc(4);
    dump("a");
    memcpy(result, "123", 4);
    dump("b");
    return result;
}
[user@myhost udf]$ ...
[user@myhost database]$ /opt/firebird/bin/isql base.gdb -USER sysdba -PASS masterkey
Database:  base.gdb, User: sysdba
SQL> SELECT STR_SIMPLE('123') FROM RDB$FIELDS;

STR_SIMPLE

=============================================================================== 
Statement failed, SQLSTATE = 08006
Error reading data from the connection.
SQL> quit;
[user@myhost database]$ cat /tmp/file.txt
31323300
[user@myhost database]$

Значит dump(content) выполняется, а dump(«a») уже нет.
Что не так с этим ib_util_malloc?!

user0xff
() автор топика
Ответ на: комментарий от visual

Уже и так пробовал.
Вот что получаю:

SQL> SELECT STR_SIMPLE('123') FROM RDB$FIELDS;

STR_SIMPLE

=============================================================================== 
Statement failed, SQLSTATE = 39000
Bad written UDF detected: pointer returned in FREE_IT function was not allocated by ib_util_malloc

user0xff
() автор топика
Ответ на: комментарий от visual

Если вместо ib_util_malloc использовать malloc и убрать FREE_IT из декларации функции в базе - то все, как бы, работает.

Но ведь FREE_IT же нужен для уборки мусора.
А как тогда? FreeBSD? Или в ib_util_malloc глюк?

Странно как то, то что на ibase.ru — у них работает в Linux и не работает во FreeBSD.

user0xff
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.