У меня есть функция postgresql, написанная на языке C.

Когда я пытаюсь запустить его, в моем файле postgresql-9.5-main.log появляется следующее:

2021-02-28 17:28:00 CST [1393-180] LOG:  server process (PID 31043) was terminated by signal 11: Segmentation fault

Находясь в psql, я получаю следующее сообщение:

server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.

Это также приводит к сбою всех других программ, использующих Postgres. Однако Postgres немедленно перезагружается.

Я также пробовал запустить это на сервере 13.1, и произошла та же ошибка.

Код для построения функции из psql:

CREATE OR REPLACE FUNCTION
 int_to_id(BIGINT)
 RETURNS TEXT AS 'int_to_id',
 'int_to_id'
LANGUAGE 'c' 
STRICT;

Теперь я убедился, что код выдает правильные идентификаторы, и на последнем шаге он не работает. То же самое происходит, когда я заменяю result постоянной строкой, например "HELLO". Мне интересно, что-то не так с моим кодом или есть другая ошибка

Код C выглядит следующим образом:

#include "postgres.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

const char charmap[36] = {
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't',
    'u',
    'v',
    'w',
    'x',
    'y',
    'z'
};

Datum int_to_id(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(int_to_id);

Datum int_to_id(PG_FUNCTION_ARGS){
    char result[11] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
    int64 x =  PG_GETARG_INT64(0);
    long base_val = 1L;
    for (int i = 1; i <= 10; i++){
        
        if (x > base_val - 1L || i == 1){
           result[10 - i] = charmap[ ((int)(x / base_val)) % 36];
        } 
        base_val = base_val * 36L;
    }

    text * textval = cstring_to_text(result);
    PG_RETURN_TEXT_P(textval);
}

Мой make-файл для сценария:

MODULES = int_to_id

PG_CONFIG = pg_config
PGXS = $(shell $(PG_CONFIG) --pgxs)
INCLUDEDIR = $(shell $(PG_CONFIG) --includedir-server)
LIBDIR = $(shell pg_config --pkglibdir)
FCFLAGS = -fPIC
include $(PGXS)

clean: 
    rm *.o
    rm *.so

int_to_id.so: int_to_id.o
    cc  -shared -o int_to_id.so int_to_id.o

int_to_id.o: int_to_id.c
    cc ${FCFLAGS} -o int_to_id.o -c int_to_id.c $(CRFLAGS) -I $(INCLUDEDIR) 

install:
    $(shell cp int_to_id.so ${LIBDIR})
0
Max Candocia 1 Мар 2021 в 02:48

1 ответ

Лучший ответ

Когда я выполняю это Makefile, я получаю:

Makefile:11: warning: overriding recipe for target 'clean'
/usr/pgsql-13/lib/pgxs/src/makefiles/pgxs.mk:342: warning: ignoring old recipe for target 'clean'
Makefile:21: warning: overriding recipe for target 'install'
/usr/pgsql-13/lib/pgxs/src/makefiles/pgxs.mk:241: warning: ignoring old recipe for target 'install'
cc -fPIC -o int_to_id.o -c int_to_id.c  -I /usr/pgsql-13/include/server 
int_to_id.c: In function ‘int_to_id’:
int_to_id.c:63:22: warning: implicit declaration of function ‘cstring_to_text’ [-Wimplicit-function-declaration]
   63 |     text * textval = cstring_to_text(result);
      |                      ^~~~~~~~~~~~~~~
int_to_id.c:63:22: warning: initialization of ‘text *’ {aka ‘struct varlena *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
cc  -shared -o int_to_id.so int_to_id.o
/usr/lib64/ccache/clang -Wno-ignored-attributes -fno-strict-aliasing -fwrapv -O2  -I. -I./ -I/usr/pgsql-13/include/server -I/usr/pgsql-13/include/internal  -D_GNU_SOURCE -I/usr/include/libxml2  -I/usr/include -flto=thin -emit-llvm -c -o int_to_id.bc int_to_id.c
int_to_id.c:63:22: warning: implicit declaration of function 'cstring_to_text' is invalid in C99 [-Wimplicit-function-declaration]
    text * textval = cstring_to_text(result);
                     ^
int_to_id.c:63:12: warning: incompatible integer to pointer conversion initializing 'text *' (aka 'struct varlena *') with an expression of type 'int' [-Wint-conversion]
    text * textval = cstring_to_text(result);
           ^         ~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.

Это означает, что вы забыли включить заголовок, определяющий cstring_to_text:

#include "utils/builtins.h"

После этого функция не вылетает на моем PostgreSQL v13, но я тщательно ее не тестировал.

Вы не должны переопределять цели clean и install в Makefile.

1
Laurenz Albe 1 Мар 2021 в 10:51