[C] [PostgreSQL] PqExec et Segmentation Fault
SangJun
-
Pierrot le developpeur fou -
Pierrot le developpeur fou -
Bonjour,
Comment se fait que PgExec génère une erreur de segmentation pour une requête qui s'exécute "manuellement" si on la copie-colle sur PgAdmin?
J'ai beau retourner le problème dans tout les sens, je ne vois pas comment m'en sortir. Je copie-colle le code pour donner un peu plus de détails.
Merci de votre aide
[CODE]#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
static void exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int bande()
{
const char *conninfo;
PGconn *conn;
PGresult *res;
int nFields;
int i, j;
char maRequete[250];
int i = 1; int j = 2;
conninfo = "***chaine pour se connecter***";
/* Make a connection to the database */
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
exit_nicely(conn);
}
/* Start a transaction block */
res = PQexec(conn, "BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
/*
* Should PQclear PGresult whenever it is no longer needed to avoid memory
* leaks
*/
PQclear(res);
while(j<=nbPoints)
{ strcpy(maRequete,"***une requete***");
printf("%s \n",maRequete);
res = PQexec(conn,maRequete);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn));
fprintf(stderr, "maRequete= %s \n", maRequete);
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
if (i==1) //Si c'est le premier segment, on crée le premier polygone
{
strcpy(maRequete,"***une requete***");
res = PQexec(conn,maRequete);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn));
fprintf(stderr, "maRequete= %s \n", maRequete);
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
}else // Sinon on fait une union avec le nouveau polygone
{
strcpy(maRequete,"***une requete***");
printf("%s\n",maRequete);
res = PQexec(conn,maRequete); /* Instruction qui génère l'erreur de segmentation */
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn));
fprintf(stderr, "maRequete= %s \n", maRequete);
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
}
i++;
j++;
}
/* end the transaction */
res = PQexec(conn, "END");
PQclear(res);
/* close the connection to the database and cleanup */
PQfinish(conn);
return 0;
}[/CODE]
Comment se fait que PgExec génère une erreur de segmentation pour une requête qui s'exécute "manuellement" si on la copie-colle sur PgAdmin?
J'ai beau retourner le problème dans tout les sens, je ne vois pas comment m'en sortir. Je copie-colle le code pour donner un peu plus de détails.
Merci de votre aide
[CODE]#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
static void exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}
int bande()
{
const char *conninfo;
PGconn *conn;
PGresult *res;
int nFields;
int i, j;
char maRequete[250];
int i = 1; int j = 2;
conninfo = "***chaine pour se connecter***";
/* Make a connection to the database */
conn = PQconnectdb(conninfo);
/* Check to see that the backend connection was successfully made */
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
exit_nicely(conn);
}
/* Start a transaction block */
res = PQexec(conn, "BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
PQclear(res);
exit_nicely(conn);
}
/*
* Should PQclear PGresult whenever it is no longer needed to avoid memory
* leaks
*/
PQclear(res);
while(j<=nbPoints)
{ strcpy(maRequete,"***une requete***");
printf("%s \n",maRequete);
res = PQexec(conn,maRequete);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn));
fprintf(stderr, "maRequete= %s \n", maRequete);
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
if (i==1) //Si c'est le premier segment, on crée le premier polygone
{
strcpy(maRequete,"***une requete***");
res = PQexec(conn,maRequete);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn));
fprintf(stderr, "maRequete= %s \n", maRequete);
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
}else // Sinon on fait une union avec le nouveau polygone
{
strcpy(maRequete,"***une requete***");
printf("%s\n",maRequete);
res = PQexec(conn,maRequete); /* Instruction qui génère l'erreur de segmentation */
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn));
fprintf(stderr, "maRequete= %s \n", maRequete);
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
}
i++;
j++;
}
/* end the transaction */
res = PQexec(conn, "END");
PQclear(res);
/* close the connection to the database and cleanup */
PQfinish(conn);
return 0;
}[/CODE]
A voir également:
- [C] [PostgreSQL] PqExec et Segmentation Fault
- Segmentation fault (core dumped) ✓ - Forum Programmation
- Erreur de segmentation c ✓ - Forum C
- Zsh: segmentation fault ✓ - Forum Programmation
- Zsh segmentation fault ✓ - Forum Assembleur
- Erreur segmentation fault (core dumped) - Forum C
18 réponses
J'ai eu le meme probleme qui m'a fait perdre du temps.
En fait, c'etait la taille alloué pour ma requete qui était trop faible.
char maRequete[250];
Si ta requete est une chaine de caractere de plus de 250 lettres. Ton PQExec générera une erreur de segmentation
Met char maRequete[400]; ou plus et ca marchera
En fait, c'etait la taille alloué pour ma requete qui était trop faible.
char maRequete[250];
Si ta requete est une chaine de caractere de plus de 250 lettres. Ton PQExec générera une erreur de segmentation
Met char maRequete[400]; ou plus et ca marchera
Salut,
Tu es sous Linux?
Je te suggère t'enquêter un ptit coup pour connaître la ligne "coupable":
langage c c c erreur de segmentation
Tu es sous Linux?
Je te suggère t'enquêter un ptit coup pour connaître la ligne "coupable":
langage c c c erreur de segmentation
Je me retrouve avec :
:-/
(gdb) run Starting program: /dea/fsauvage/nouveau [Thread debugging using libthread_db enabled] [New Thread -1212294464 (LWP 18936)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1212294464 (LWP 18936)] 0xb7fca5c9 in PQconsumeInput () from /usr/lib/libpq.so.4 (gdb) bt #0 0xb7fca5c9 in PQconsumeInput () from /usr/lib/libpq.so.4 #1 0xb7fcaf07 in PQgetResult () from /usr/lib/libpq.so.4 #2 0xb7fcb2c5 in PQputCopyEnd () from /usr/lib/libpq.so.4 #3 0xb7fcb50f in PQexec () from /usr/lib/libpq.so.4 #4 0x080495fe in bande () at bande.c:254 #5 0x08049841 in main () at bande.c:315
:-/
C'est donc ça l'important:
C'est à dire l'appel de fonction ou méthode le plus profond sans entrer dans une librairie externe.
Ton problème se situe dans la fonction bande à la ligne 254 de bande.c
Regarde si par là tu utilises un pointeur non initialisé ou un truc du style...
Ca correspond à quelle ligne en fait?
#4 0x080495fe in bande () at bande.c:254
C'est à dire l'appel de fonction ou méthode le plus profond sans entrer dans une librairie externe.
Ton problème se situe dans la fonction bande à la ligne 254 de bande.c
Regarde si par là tu utilises un pointeur non initialisé ou un truc du style...
Ca correspond à quelle ligne en fait?
Voilà qui sera plus clair
#include <stdio.h> #include <stdlib.h> #include "libpq-fe.h" static void exit_nicely(PGconn *conn) { PQfinish(conn); exit(1); } int bande() { const char *conninfo; PGconn *conn; PGresult *res; int nFields; int i, j; char maRequete[250]; int i = 1; int j = 2; conninfo = "***chaine pour se connecter***"; /* Make a connection to the database */ conn = PQconnectdb(conninfo); /* Check to see that the backend connection was successfully made */ if (PQstatus(conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn)); exit_nicely(conn); } /* Start a transaction block */ res = PQexec(conn, "BEGIN"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn)); PQclear(res); exit_nicely(conn); } /* * Should PQclear PGresult whenever it is no longer needed to avoid memory * leaks */ PQclear(res); while(j<=nbPoints) { strcpy(maRequete,"***une requete***"); printf("%s \n",maRequete); res = PQexec(conn,maRequete); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn)); fprintf(stderr, "maRequete= %s \n", maRequete); PQclear(res); exit_nicely(conn); } PQclear(res); if (i==1) //Si c'est le premier segment, on crée le premier polygone { strcpy(maRequete,"***une requete***"); res = PQexec(conn,maRequete); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn)); fprintf(stderr, "maRequete= %s \n", maRequete); PQclear(res); exit_nicely(conn); } PQclear(res); }else // Sinon on fait une union avec le nouveau polygone { strcpy(maRequete,"***une requete***"); printf("%s\n",maRequete); res = PQexec(conn,maRequete); /* Instruction qui génère l'erreur de segmentation */ if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn)); fprintf(stderr, "maRequete= %s \n", maRequete); PQclear(res); exit_nicely(conn); } PQclear(res); } i++; j++; } /* end the transaction */ res = PQexec(conn, "END"); PQclear(res); /* close the connection to the database and cleanup */ PQfinish(conn); return 0; }
Non, pas de problème
Dans le code entier nbPoints est initialisé (c'est le nombre de points d'une LINE d'un SIG). De plus je code pour le moment en aillant pris un seul exemple où ce nombre est égal à 9 et c'est au 2nd tour de boucle (donc if (i==1) //Si c'est le premier segment, on crée le premier polygone ne pose pas de problème) que le problème survient.
Dans le code entier nbPoints est initialisé (c'est le nombre de points d'une LINE d'un SIG). De plus je code pour le moment en aillant pris un seul exemple où ce nombre est égal à 9 et c'est au 2nd tour de boucle (donc if (i==1) //Si c'est le premier segment, on crée le premier polygone ne pose pas de problème) que le problème survient.
En apparence dans ton code je ne vois pas de problème.
Il y aurait peut être un segmentation fault par exemple si tu passais en paramètre une connexion ou une requête qui n'a pas été initialisée dans PQexec, mais il semblerais que ça ne soit pas le cas.
Juste avant la ligne critique qui génère l'erreur tu fais un affichage de ta requête, rajoute un
fflush(stdout);
pour être sûr que tout s'affiche bien avant l'erreur (bien que normalement le caractère "\n" s'en occupe tout seul).
Et puis avant ce fflush, fait un affichage du statut de ta connexion pour vérifier si tout va bien
=> if(PQstatus(conn) != CONNECTION_OK) ......
Il y aurait peut être un segmentation fault par exemple si tu passais en paramètre une connexion ou une requête qui n'a pas été initialisée dans PQexec, mais il semblerais que ça ne soit pas le cas.
Juste avant la ligne critique qui génère l'erreur tu fais un affichage de ta requête, rajoute un
fflush(stdout);
pour être sûr que tout s'affiche bien avant l'erreur (bien que normalement le caractère "\n" s'en occupe tout seul).
Et puis avant ce fflush, fait un affichage du statut de ta connexion pour vérifier si tout va bien
=> if(PQstatus(conn) != CONNECTION_OK) ......
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Il y a un problème avec ta connexion....
Déjà, pour éviter des problèmes qui pourraient venir d'on ne sait où, n'oublie pas d'inclure string.h et math.h
Rééssaie ensuite pour voir, je pense que l'erreur restera mais on ne sait jamais.
De toutes façon il faut que tu inclues ces fichiers.
Déjà, pour éviter des problèmes qui pourraient venir d'on ne sait où, n'oublie pas d'inclure string.h et math.h
Rééssaie ensuite pour voir, je pense que l'erreur restera mais on ne sait jamais.
De toutes façon il faut que tu inclues ces fichiers.
Il semblerais que non puisque cos et sin ne sont pas reconnues.
De toutes façon c'est pas grave, même après plusieurs include, les fichiers d'en-tête des librairies standards ne se laisse pas inclure plusieurs fois...
De toutes façon c'est pas grave, même après plusieurs include, les fichiers d'en-tête des librairies standards ne se laisse pas inclure plusieurs fois...
Cos et sin étaient reconnues puisque dans le premier tour de boucle j'obtenais des résultats faisant appel à ces fonctions.
M'enfin, je reste toujours avec ma connexion en échec sans aucun moyen de comprendre pourquoi :'(
M'enfin, je reste toujours avec ma connexion en échec sans aucun moyen de comprendre pourquoi :'(
Je ne saurais pas te dire...
Il y a un problème avec ta variable conn. Pourquoi ça je ne sais pas...
Tu libères les ressources comme il faut, peut être qu'il y a une erreur de requête que tu ne detectes pas et qui fait foirer ta connexion...
Il y a un problème avec ta variable conn. Pourquoi ça je ne sais pas...
Tu libères les ressources comme il faut, peut être qu'il y a une erreur de requête que tu ne detectes pas et qui fait foirer ta connexion...
1ier tour de boucle :
2ème tour de boucle :
{ strcpy(maRequete,"*** une requête ***"); res = PQexec(conn,maRequete); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn)); fprintf(stderr, "maRequete= %s \n", maRequete); PQclear(res); exit_nicely(conn); } xA = atof(PQgetvalue(res, 0, 0)); yA = atof(PQgetvalue(res, 0, 1)); xB = atof(PQgetvalue(res, 0, 2)); yB = atof(PQgetvalue(res, 0, 3)); PQclear(res); if (i==1) //Si c'est le premier segment, on crée le premier polygone { strcpy(maRequete,"*** autre requête ***"); res = PQexec(conn,maRequete); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn)); fprintf(stderr, "maRequete= %s \n", maRequete); PQclear(res); exit_nicely(conn); } PQclear(res); }else // Sinon on fait une union avec le nouveau polygone { /*c'est un else donc on ne s'en préoccupe pas } i++; j++; }
2ème tour de boucle :
{ strcpy(maRequete,"*** une requête ***"); res = PQexec(conn,maRequete); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn)); fprintf(stderr, "maRequete= %s \n", maRequete); PQclear(res); exit_nicely(conn); } PQclear(res); if (i==1) //Si c'est le premier segment, on crée le premier polygone { //i=2 }else // Sinon on fait une union avec le nouveau polygone { strcpy(maRequete,"*** 3ème requête ***"); /*Test pour l'erreur de PqExec*/ fflush(stdout); printf("OK1\n"); if(PQstatus(conn) != CONNECTION_OK) { printf("PQstatus(conn) != CONNECTION_OK\n"); } printf("OK2\n",maRequete); res = PQexec(conn,maRequete); printf("OK2\n"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SELECT failed: %s \n", PQerrorMessage(conn)); fprintf(stderr, "maRequete= %s \n", maRequete); PQclear(res); exit_nicely(conn); } PQclear(res); } i++; j++; }
Essaie de faire des tests de PQstatus après les executions diverses de requête pour savoir d'où ça vient....
J'ai fait des tests en changeant de taille ma variable maRequete (et d'une autre chaine que je concatène à maRequete) et l'erreur intervient plus tard.
La POO c'est tellement mieux :(
La POO c'est tellement mieux :(
J'avais posté un message concernant une erreur dûe à une suite de requêtes reliées par des ";"
En exécutant chaque requête une à une, je n'ai plus d'erreur. Je me suis rendu compte que c'était assez stupide comme erreur donc j'ai supprimé le post.
Par contre, j'ai toujours le problème de la taille de la chapine de caractère (500000 c'est bien pratique mais c'est une valeur prise au hasard)
En exécutant chaque requête une à une, je n'ai plus d'erreur. Je me suis rendu compte que c'était assez stupide comme erreur donc j'ai supprimé le post.
Par contre, j'ai toujours le problème de la taille de la chapine de caractère (500000 c'est bien pratique mais c'est une valeur prise au hasard)