Hola, para la versión 9 de PostgreSQL escribí varias funciones en C que
eran invocadas desde SQL. Al compilarlas para la versión 15, tengo el
problema mencionado en el Asunto del mensaje: al ejecutar cualquiera de
ellas, termina la ejecución del servidor por el segmentation fault:

2024-08-26 16:30:02.801 CST   [1177]LOG:  server process (PID 10357) was
terminated by signal 11: Segmentation fault
2024-08-26 16:30:02.801 CST   [1177]DETAIL:  Failed process was running:
select nombre, apeuno, apedos, entnac, sexo, fecnac, '0'::text as hm,
crea_curp(nombre::text, apeuno::text, apedos::text, entnac::integer,
sexo::text, fecnac::text, '0'::text) from mini_retrapo limit 18;
2024-08-26 16:30:02.801 CST   [1177]LOG:  terminating any other active
server processes
2024-08-26 16:30:02.802 CST prueba_extensiones mancha [13868]FATAL:  the
database system is in recovery mode
2024-08-26 16:30:02.808 CST   [1177]LOG:  all server processes terminated;
reinitializing
2024-08-26 16:30:03.052 CST   [13869]LOG:  database system was interrupted;
last known up at 2024-08-26 16:29:55 CST
2024-08-26 16:30:10.351 CST   [13869]LOG:  database system was not properly
shut down; automatic recovery in progress

Hice unas pruebas y llegué a la conclusión que el problema se manifiesta
dependiendo del número de registros seleccionados o del número de
argumentos que recibe la función.

El texto del ejemplo minimo:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <regex.h>
#include <locale.h>
#include <regex.h>
#include "postgres.h"
#include "executor/executor.h"
#include "utils/builtins.h"
#include "fmgr.h"

PG_MODULE_MAGIC;
void _PG_init(void);
void _PG_fini(void);
Datum c_crea_curp (PG_FUNCTION_ARGS);

#define DBUG 1

PG_FUNCTION_INFO_V1(c_crea_curp);

Datum c_crea_curp(PG_FUNCTION_ARGS)
{
  char *nombre, *apepat, *apemat, *sexo, *fecnac, *lahm;
  char salida[2048];
  int laent;
  nombre = text_to_cstring(PG_GETARG_TEXT_PP(0));
  apepat = text_to_cstring(PG_GETARG_TEXT_PP(1));
  apemat = text_to_cstring(PG_GETARG_TEXT_PP(2));
  laent  =                   PG_GETARG_INT32(3);
  sexo   = text_to_cstring(PG_GETARG_TEXT_PP(4));
  fecnac = text_to_cstring(PG_GETARG_TEXT_PP(5));
  lahm   = text_to_cstring(PG_GETARG_TEXT_PP(6));
  sprintf(salida, "%s|%s|%s|%d|%s|%s|%s", nombre, apepat,
 apemat, laent, sexo, fecnac, lahm);
  elog(NOTICE, "entrada:>%s<>%s<>%s<>%d<>%s<>%s<>%s<",
  nombre, apepat, apemat, laent, sexo, fecnac, lahm);
  PG_RETURN_TEXT_P(CStringGetTextDatum(salida));
}

Al momento de cargarlo y ejecutarlo, si lo hago sobre 8 registros, lo hace
sin problema, pero si lo hago sobre 28 ya aroja el seg fault.

mancha@duanne:~/trabajo/Padrinos$ psql prueba_extensiones
psql (15.7)
Type "help" for help.

prueba_extensiones=# create or replace function crea_curp (text, text,
text, integer, text, text, text) returns text as
'/home/mancha/lib/inicio_curp.so', 'c_crea_curp' language c IMMUTABLE;
CREATE FUNCTION
prueba_extensiones=# select nombre, apeuno, apedos, entnac, sexo, fecnac,
'0'::text as hm, crea_curp(nombre::text, apeuno::text, apedos::text,
entnac::integer, sexo::text, fecnac::text, '0'::text) from mini_retrapo
limit 8;
NOTICE:  entrada:>LUZ<>FLORES<>GARCIA<>30<>M<>1929-12-25<>0<
NOTICE:  entrada:>ROSA MARIA<>FRANCO<>LOA<>9<>M<>1971-04-19<>0<
NOTICE:  entrada:>ALFREDO<>FRANCO<>PEREZ<>9<>H<>1978-01-16<>0<
NOTICE:  entrada:>MATEO<>FARIAS<>RUIZ<>16<>H<>2015-07-05<>0<
NOTICE:  entrada:>BELEN<>FABIAN<>SORIANO<>9<>M<>2018-07-29<>0<
NOTICE:  entrada:>RAUL<>FRANCO<>ROMO<>14<>H<>1948-07-19<>0<
NOTICE:  entrada:>LAURA<>FABIAN<>NERI<>21<>M<>1992-02-19<>0<
NOTICE:  entrada:>DAFNE<>FELIX<>AYALA<>25<>M<>2016-10-09<>0<
   nombre   | apeuno | apedos  | entnac | sexo |   fecnac   | hm |
      crea_curp
------------+--------+---------+--------+------+------------+----+----------------------------------------
 LUZ        | FLORES | GARCIA  |     30 | M    | 1929-12-25 | 0  |
LUZ|FLORES|GARCIA|30|M|1929-12-25|0
 ROSA MARIA | FRANCO | LOA     |      9 | M    | 1971-04-19 | 0  | ROSA
MARIA|FRANCO|LOA|9|M|1971-04-19|0
 ALFREDO    | FRANCO | PEREZ   |      9 | H    | 1978-01-16 | 0  |
ALFREDO|FRANCO|PEREZ|9|H|1978-01-16|0
 MATEO      | FARIAS | RUIZ    |     16 | H    | 2015-07-05 | 0  |
MATEO|FARIAS|RUIZ|16|H|2015-07-05|0
 BELEN      | FABIAN | SORIANO |      9 | M    | 2018-07-29 | 0  |
BELEN|FABIAN|SORIANO|9|M|2018-07-29|0
 RAUL       | FRANCO | ROMO    |     14 | H    | 1948-07-19 | 0  |
RAUL|FRANCO|ROMO|14|H|1948-07-19|0
 LAURA      | FABIAN | NERI    |     21 | M    | 1992-02-19 | 0  |
LAURA|FABIAN|NERI|21|M|1992-02-19|0
 DAFNE      | FELIX  | AYALA   |     25 | M    | 2016-10-09 | 0  |
DAFNE|FELIX|AYALA|25|M|2016-10-09|0
(8 rows)

prueba_extensiones=# select nombre, apeuno, apedos, entnac, sexo, fecnac,
'0'::text as hm, crea_curp(nombre::text, apeuno::text, apedos::text,
entnac::integer, sexo::text, fecnac::text, '0'::text) from mini_retrapo
limit 28;
NOTICE:  entrada:>LUZ<>FLORES<>GARCIA<>30<>M<>1929-12-25<>0<
NOTICE:  entrada:>ROSA MARIA<>FRANCO<>LOA<>9<>M<>1971-04-19<>0<
NOTICE:  entrada:>ALFREDO<>FRANCO<>PEREZ<>9<>H<>1978-01-16<>0<
NOTICE:  entrada:>MATEO<>FARIAS<>RUIZ<>16<>H<>2015-07-05<>0<
NOTICE:  entrada:>BELEN<>FABIAN<>SORIANO<>9<>M<>2018-07-29<>0<
NOTICE:  entrada:>RAUL<>FRANCO<>ROMO<>14<>H<>1948-07-19<>0<
NOTICE:  entrada:>LAURA<>FABIAN<>NERI<>21<>M<>1992-02-19<>0<
NOTICE:  entrada:>DAFNE<>FELIX<>AYALA<>25<>M<>2016-10-09<>0<
NOTICE:  entrada:>JUANA<>FERIA<>PEREZ<>20<>M<>1997-08-25<>0<
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
The connection to the server was lost. Attempting reset: Failed.
!?> \q

Ahora bien, si comento la lectura de los ultimos 5 argumentos:

Datum c_crea_curp(PG_FUNCTION_ARGS)
{
  char *nombre, *apepat/* , *apemat, *sexo, *fecnac, *lahm */;
  char salida[2048];
  /* int laent; */
  nombre = text_to_cstring(PG_GETARG_TEXT_PP(0));
  apepat = text_to_cstring(PG_GETARG_TEXT_PP(1));
  /* apemat = text_to_cstring(PG_GETARG_TEXT_PP(2)); */
  /* laent  =                   PG_GETARG_INT32(3); */
  /* sexo   = text_to_cstring(PG_GETARG_TEXT_PP(4)); */
  /* fecnac = text_to_cstring(PG_GETARG_TEXT_PP(5)); */
  /* lahm   = text_to_cstring(PG_GETARG_TEXT_PP(6)); */
  /* sprintf(salida, "%s|%s|%s|%d|%s|%s|%s", nombre, apepat, */
  /*  apemat, laent, sexo, fecnac, lahm); */
  /* elog(NOTICE, "entrada:>%s<>%s<>%s<>%d<>%s<>%s<>%s<", */
  /*   nombre, apepat, apemat, laent, sexo, fecnac, lahm); */
  sprintf(salida, "%s|%s", nombre, apepat);
  PG_RETURN_TEXT_P(CStringGetTextDatum(salida));
}

Entonces la función hace lo esperado para los 71 millones de registros.

                       nombre                       |
apeuno                 |           apedos           | entnac | sexo |
fecnac   | hm |                                        crea_curp

----------------------------------------------------+----------------------------------------+----------------------------+--------+------+------------+----+------------------------------------------------------------------------------------------
 LUZ                                                | FLORES
                  | GARCIA                     |     30 | M    | 1929-12-25
| 0  | LUZ|FLORES
 ROSA MARIA                                         | FRANCO
                  | LOA                        |      9 | M    | 1971-04-19
| 0  | ROSA MARIA|FRANCO
.
.
.


También hice pruebas sin hacer el sprintf y regresando de la función
con PG_RETURN_NULL();
y funciona bien si leo sólo dos argumentos o si uso los siete funciona
limitando el select a 8 registros.

Revisé el código de postgresql-15.7/backend/replication/slotfuncs.c,
postgresql-15.7/test/regress/regress.c y los ejemplos contenidos en
postgresql-15.7/src/tutorial

El Makefile es:

MODULES = complex funcs inicio_curp
DATA_built = advanced.sql basics.sql complex.sql funcs.sql syscat.sql

ifdef NO_PGXS
subdir = src/tutorial
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/src/makefiles/pgxs.mk
else
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
endif

%.sql: %.source
rm -f $@; \
C=`pwd`; \
sed -e "s:_OBJWD_:$$C:g" < $< > $@

Tomado del directorio  postgresql-15.7/src/tutorial y la salida del make es:

-*- mode: compilation; default-directory:
"~/trabajo/Padrinos/postgresql-15.7/src/tutorial/" -*-
Compilation started at Mon Aug 26 17:19:31

make -k
gcc -Wall -Wmissing-prototypes -Wpointer-arith
-Wdeclaration-after-statement -Werror=vla -Wendif-labels
-Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security
-fno-strict-aliasing -fwrapv -fexcess-precision=standard
-Wno-format-truncation -fmessage-length=0 -grecord-gcc-switches -O2 -Wall
-D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables
-fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC -I. -I./
-I/usr/include/pgsql/server -I/usr/include/pgsql/internal  -D_GNU_SOURCE
-I/usr/include/libxml2   -c -o inicio_curp.o inicio_curp.c
gcc -Wall -Wmissing-prototypes -Wpointer-arith
-Wdeclaration-after-statement -Werror=vla -Wendif-labels
-Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security
-fno-strict-aliasing -fwrapv -fexcess-precision=standard
-Wno-format-truncation -fmessage-length=0 -grecord-gcc-switches -O2 -Wall
-D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables
-fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC
inicio_curp.o -L/usr/lib/postgresql15/lib64  -L/usr/lib64  -Wl,--as-needed
 -shared -o inicio_curp.so
/usr/bin/clang -Wno-ignored-attributes -fno-strict-aliasing -fwrapv
-Wno-unused-command-line-argument -O2  -I. -I./ -I/usr/include/pgsql/server
-I/usr/include/pgsql/internal  -D_GNU_SOURCE -I/usr/include/libxml2
 -flto=thin -emit-llvm -c -o inicio_curp.bc inicio_curp.c

Compilation finished at Mon Aug 26 17:19:32

¿Alguna idea de lo que estoy haciendo mal o si se trata de un bug de
aparición reciente?

Agradezco la atención y los comentarios que presten a éste mensaje.

--
Saludos.

/* Los nombres,  endidad de nacimiento y fecha de nacimiento de los
registros mostrados son ficticios */

Reply via email to