Re: Fonction C: Segmentation fault

From: Cédric Villemain <cedric(dot)villemain(at)dalibo(dot)com>
To: pgsql-fr-generale(at)postgresql(dot)org
Cc: Samuel ROZE <samuel(dot)roze(at)gmail(dot)com>
Subject: Re: Fonction C: Segmentation fault
Date: 2009-10-14 17:43:44
Message-ID: 200910141943.49370.cedric.villemain@dalibo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-fr-generale

Le mercredi 14 octobre 2009 19:32:26, Samuel ROZE a écrit :
> Bonjour à tous,
>
> Je souhaites créer une fonction "parse_url" afin de pouvoir récupérer
> l'hostname, le path, le schéma ou autre chose à partir d'une adresse URL
> (text).
>
> Je souhaites donc créer une fonction C. Seulement, j'ai quelques soucis
> pour la création d'une fonction de base. La fonction doit retourner un
> type composite (i.e. une colonne "scheme" et une colonne "host" avec des
> valeurs de base, pour le moment (pour faire ma première fonction C pour
> PostgreSQL). Bref, voilà le code que j'ai.
>
> Fichier: parse_url.c
> ------------------------------------------------------------------------
> /*
> * parse_url.c
> *
> * Created on: 14 oct. 2009
> * Author: Samuel ROZE <samuel(dot)roze(at)gmail(dot)com>
> */
> #include "postgres.h"
> #include <string.h>
> #include "fmgr.h"
> // Tuple building functions and macros
> #include "access/heapam.h"
> #include "funcapi.h"
>
> #include "parse_url.h"
>
> #ifdef PG_MODULE_MAGIC
> PG_MODULE_MAGIC;
> #endif
>
> PG_FUNCTION_INFO_V1(parse_url);
> Datum parse_url (PG_FUNCTION_ARGS)
> {
> // Vars about the params
> text *str = PG_GETARG_TEXT_P(0);
> int32 length = VARSIZE(str);
>
> // Vars about the pg_url instance
> pg_url *ret = palloc(sizeof(pg_url));
>
> // Some vars which will used to create the composite output type
> TupleDesc tupdesc;
> Datum values[8]; // 8 values
> HeapTuple tuple;
> bool *nulls;
> int tuplen;
>
> // Check NULLs values
> if(PG_ARGISNULL(0) || PG_ARGISNULL(1)) {
> PG_RETURN_NULL();
> }
>
> // Parse URL
> ret->scheme = parse_url_alloc("schema", 7);
> ret->host = parse_url_alloc("host", 5);
>
> // Add datas into the values Datum
> values[0] = PointerGetDatum(ret->scheme);
> values[1] = PointerGetDatum(ret->host);
>
> // Convert values into a composite type
> tuplen = tupdesc->natts;
> nulls = palloc(tuplen * sizeof(bool));
>
> // build tuple from datum array
> tuple = heap_form_tuple(tupdesc, values, nulls);
> // Free null values
> pfree(nulls);
>
> // Return the composite type
> PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
> }
>
> char *parse_url_alloc(const char *s, int length)
> {
> char *p;
>
> p = (char *) palloc(length+1);
> if (p != NULL) {
> memcpy(p, s, length);
> p[length] = 0;
> return p;
> }
> }
> ------------------------------------------------------------------------
>
> Fichier: parse_url.h
> ------------------------------------------------------------------------
> /*
> * parse_url.h
> *
> * Created on: 14 oct. 2009
> * Author: Samuel ROZE <samuel(dot)roze(at)gmail(dot)com>
> */
>
> #ifndef PARSE_URL_H
> #define PARSE_URL_H
>
> Datum parse_url (PG_FUNCTION_ARGS);
> char *parse_url_alloc(const char *s, int length);
>
> typedef struct pg_url {
> char *scheme;
> char *user;
> char *pass;
> char *host;
> unsigned short port;
> char *path;
> char *query;
> char *fragment;
> } pg_url;
>
> #endif /* PARSE_URL_H */
> ------------------------------------------------------------------------
>
> Pour le compilation, voilà ce que j'ai fait:
> ------------------------------------------------------------------------
> $ gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Winline
> -Wdeclaration-after-statement -Wendif-labels -fno-strict-aliasing
> -fwrapv -fpic -I. -I/usr/include/postgresql/server
> -I/usr/include/postgresql/internal -D_GNU_SOURCE -c -o parse_url.o
> parse_url.c -I/usr/include/postgresql/
> -I/usr/local/pgsql/include/server/
> ------------------------------------------------------------------------
> $ gcc -shared -o parse_url.so parse_url.o
> ------------------------------------------------------------------------
>
> Ça marche bien. Quelques petites erreurs:
> ------------------------------------------------------------------------
> parse_url.c: In function ‘parse_url’:
> parse_url.c:25: warning: unused variable ‘length’
> parse_url.c: In function ‘parse_url_alloc’:
> parse_url.c:73: warning: control reaches end of non-void function
> parse_url.c: In function ‘parse_url’:
> parse_url.c:51: warning: ‘tupdesc’ may be used uninitialized in this
> function
> ------------------------------------------------------------------------
>
> Pour la création de la fonction dans PostgreSQL:
> ------------------------------------------------------------------------
> CREATE FUNCTION parse_url (text) RETURNS record AS
> '/root/PgSQL-parse_url/parse_url.so', 'parse_url' LANGUAGE C;
> ------------------------------------------------------------------------
>
> Pour l'éxécution:
> ------------------------------------------------------------------------
> SELECT * FROM parse_url('http://www.google.fr') as ("schema" text, "query"
> text);
> ------------------------------------------------------------------------
>
> L'erreur suivante m'est retournée:
> ------------------------------------------------------------------------
> server closed the connection unexpectedly
> This probably means the server terminated abnormally
> before or while processing the request.
> ------------------------------------------------------------------------

Je n'ai pas le temps de suite de bien lire le code, mais souvent cela peut
etre lié a un type de retour de fonction C différent de ce que réclame le sql.

Par exemple le sql attend du text et recoit autre chsoe (un char...)

>
> Et j'ai dans les logs:
> ------------------------------------------------------------------------
> LOG: processus serveur (PID 26272) a été arrêté par le signal 11 :
> Segmentation fault LOG: arrêt des autres processus serveur actifs
> LOG: tous les processus serveur se sont arrêtés, réinitialisation
> LOG: le système de bases de données a été interrompu ; dernier lancement
> connu à 2009-10-14 19:07:19 CEST LOG: le système de bases de données n'a
> pas été arrêté proprement ; restauration automatique en cours
> LOG: enregistrement de longueur nulle à 0/43855468
> LOG: la ré-exécution n'est pas nécessaire
> LOG: lancement du processus autovacuum
> LOG: le système de bases de données est prêt pour accepter les connexions
> ------------------------------------------------------------------------
>
> Est-ce que quelqu'un d'entre vous voit le problème ?
>
> Merci d'avance.
> Cordialement, Samuel ROZE.
>

--
Cédric Villemain
Administrateur de Base de Données
Cel: +33 (0)6 74 15 56 53
http://dalibo.com - http://dalibo.org

In response to

Responses

Browse pgsql-fr-generale by date

  From Date Subject
Next Message Samuel ROZE 2009-10-14 17:46:55 Re: Fonction C: Segmentation fault
Previous Message Samuel ROZE 2009-10-14 17:32:26 Fonction C: Segmentation fault