c - 调用用 C 编写的 Postgres 函数时出现分段错误,导致 Postgres 服务器崩溃
问题描述
我有一个用 C 代码编写的 postgresql 函数。
当我尝试运行它时,我在我的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;
现在,我已验证代码生成了正确的 ID,但在最后一步中失败了。当我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);
}
我的脚本生成文件:
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})
解决方案
当我执行那个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
推荐阅读
- python - 平均神经网络性能取决于 KFold 交叉验证中使用的折叠数
- c++ - ObjC / C++ 相同的代码具有不同的错误
- javascript - 从按钮传递两个不同的值并选择切换
- react-native - 意想不到的元素
在发现 - c# - 使用为孩子制作的环境扩展 Process.Start 命令的环境变量
- c - fread 二进制文件截断数据
- urlencode - 如何在 URL 中对以下字符串“+”进行编码以打开 PDF 文件
- windows - 为什么 conda 无法在 Windows 上正确安装 tensorflow gpu?
- image - 从 Flutter/Dart 访问受 AWS S3 保护的图像?
- ms-access - Access 2016 使表查询停止工作