From: | Jaime Soler <jaime(dot)soler(at)gmail(dot)com> |
---|---|
To: | Fernando Magariños <mancha(dot)at(dot)me(at)gmail(dot)com> |
Cc: | pgsql-es-ayuda(at)lists(dot)postgresql(dot)org |
Subject: | Re: Segmentation fault en una función en C |
Date: | 2024-08-27 09:10:23 |
Message-ID: | CAKVUGgTGvvwpage6vUz7d2EVTiHmtN_MYX1TWoDjUy6eck3nJg@mail.gmail.com |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-es-ayuda |
En tu caso, tu función devuelve un número variable de elementos y no veo
que reserves memoria para ellos de forma variable , puedes mirar el código
de la función del enlace
https://github.com/postgres/postgres/blob/master/src/tutorial/funcs.c#L89-L103
y que te guíe en la reserva de memoria y ampliación de la misma cuando los
resultados de la consulta son variables.
Un saludo
El mar, 27 ago 2024 a las 1:52, Fernando Magariños (<mancha(dot)at(dot)me(at)gmail(dot)com>)
escribió:
>
> 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(at)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 */
>
>
>
From | Date | Subject | |
---|---|---|---|
Next Message | Fernando Magariños | 2024-08-27 19:03:53 | Re: Segmentation fault en una función en C |
Previous Message | Fernando Magariños | 2024-08-26 23:35:45 | Segmentation fault en una función en C |