Erreur de segmentation
safadoo
-
Hxyp Messages postés 401 Date d'inscription Statut Membre Dernière intervention -
Hxyp Messages postés 401 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
j'explique mon problème , mon probleme a pour but de recevoir (etant un serveur tcp) des trames Gcode par exemple "G21 G90 G00 X100 Y150 Z120 " et je dois les traduire et les mettre dans une trames , pour cela j'utilise strtok qui scinder la trames a chaque espace tout ca dans une boucle, il fati 2 fois la boucle mais a la troisième fois il entre dans le test de G00 ( car a chaque isolement il regarde ce qu'il y a dans le pointeur recu apr strtok) et il doit la isoler les coordonnées mais j'ai cette erreur de segementation que je ne comprend pas bref voici mon programme :
et il affiche donc ca :
j'ai tester dans le debug mais sa aide pas bcp :
Program received signal SIGSEGV, Segmentation fault.
0xb7f65df4 in ?? () from /lib/i386-linux-gnu/libc.so.6
j'explique mon problème , mon probleme a pour but de recevoir (etant un serveur tcp) des trames Gcode par exemple "G21 G90 G00 X100 Y150 Z120 " et je dois les traduire et les mettre dans une trames , pour cela j'utilise strtok qui scinder la trames a chaque espace tout ca dans une boucle, il fati 2 fois la boucle mais a la troisième fois il entre dans le test de G00 ( car a chaque isolement il regarde ce qu'il y a dans le pointeur recu apr strtok) et il doit la isoler les coordonnées mais j'ai cette erreur de segementation que je ne comprend pas bref voici mon programme :
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "string.h"
#include "charlyrobot.h"
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define PORT 5000
#define TRUE 1 /* Creation d'un type bool */
#define FALSE 0
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
int main(){
int first_time = TRUE;
char connectee[20] = "Connexion etablie";
char *pointeur,*pointeur_tmp,*pointeur_while;
char *cp_buffer_reception,*buffer_envoie;
int get_out = 0;
/* Socket et adressage du serveur */
int i = 0, X_int = 0, Y_int = 0, Z_int = 0;
char *X_char = NULL, *Y_char = NULL, *Z_char = NULL;
int absolu,pouce;
int taille;
SOCKET sock;
SOCKADDR_IN sin;
socklen_t size = sizeof(sin); /* Taille de l'adresse */
char buffer_reception[40] ="";
/* Socket et adressage du client */
SOCKET csock;
SOCKADDR_IN csin;
socklen_t csize = sizeof(sin); /* Taille de l'adresse */
if( (sock = socket( AF_INET, SOCK_STREAM, 0) ) != INVALID_SOCKET ){
printf("Ouverture socket en mode TCP/IP \n");
/********************************* Configuration de la connexion ***********************************************/
sin.sin_addr.s_addr = htonl(INADDR_ANY); /* Adresse IP auto */
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT); /* Port definie 5000 */
printf("Ouverture du port %d \n\n",PORT);
/*********************************************** Etablissement de la connexion *********************************/
if( (bind(sock, (SOCKADDR*)&sin, sizeof(sin) ) ) != SOCKET_ERROR){
/******************** ***********On met la socket en état d'écoute *********************************************/
if( (listen(sock,1) ) != SOCKET_ERROR ){
/******************************* On attend que le client se connecteee *******************************************/
csock = accept(sock, (SOCKADDR*)&csin, &csize );
send(csock, connectee, sizeof(connectee), 0); /* Envoie chaine "caractère envoyé" pour tester la connexion du client au serveur */
if( (recv( csock, buffer_reception, sizeof(buffer_reception), 0 ) ) != SOCKET_ERROR ){
printf("Connexion client socket %d de %s : %d \n",csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port) );
printf("Buffer recue :");
for( i = 0; i < sizeof(buffer_reception) ; i++){
printf( " %c",buffer_reception[i]);
}
printf("\n");
while(get_out == 0){
/**************************************** Puis on recoit les données du client *********************************/
/* On copie le contenu de buffer_reception */
cp_buffer_reception = strdup(buffer_reception);
if(cp_buffer_reception == NULL ){
printf("erreur copie buffer\n");
exit(-1);
}
/* On separe et analyse les données recus pour pouvoir les analysés séparement */
/*On utilise la méthode strtok pour isoler les différentes méthode et coordonnée*/
/* Premier appel de strtok */
if(first_time == TRUE ){
printf("rentrer dans first time vrai\n");
pointeur = strtok( cp_buffer_reception, " " );
first_time = 0;
}
/* puis on cherche les autres séparateur */
else if(first_time == FALSE){
printf("rentrer dans first time faux \n");
pointeur = strtok( NULL , " " );
}
printf("pointeur:%s\n",pointeur);
/************************************************** Test du buffer recu *******************************************************/
if( strcmp( pointeur,"G20" ) == 0 ){
printf("Programmation en pouce\n");
/* On utilise l'unité de mesure pouce, sauf si on rencontre G21 */
/* On utilise un bool qui defini si les coordonnées sont en pouce ou mm, ici pouce vaut TRUE */
pouce = 1; /*1 = TRUE */
}
if( strcmp ( pointeur,"G21" ) == 0 ){
printf("Programmation en mm\n\n");
/* On utilise l'unité de mesure mm, sauf si on rencontre G20 */
/* On utilise un bool qui defini si les coordonnées sont en pouce ou mm, ici pouce vaut FALSE */
pouce = 0; /*0 = FALSE */
}
if( strcmp ( pointeur,"G90" ) == 0 ){
printf("Déplacement en mode absolue donc @0M \n");
/* On utilise que la méthode @0M, sauf si on rencontre G91 */
/* On utilise un bool qui definit si la méthode est absolue ou relative, ici absolue vaut TRUE */
absolu = 1;
}
if( strcmp ( pointeur,"G91" ) == 0 ){
printf("Déplacement en mode relatif donc @0A \n");
/* On utilise que la méthode @0M, sauf si on rencontre G90 */
/* On utilise un bool qui definit si la méthode est absolue ou relative, ici absolue vaut FALSE */
absolu = 0;
}
if( strcmp ( pointeur,"G28" ) == 0 ){
printf(" POM \n");
POM();
}
if( strcmp ( pointeur,"G00" ) == 0 ){
/* Lecture des coordonnées */
printf("juste avant while \n");
while( pointeur != NULL){
printf("test while");
pointeur = strtok( NULL ," ");
//taille = strlen(pointeur); /*On calcule la taille des données contenu dans pointeur */
pointeur_tmp = strndup(pointeur+1,taille-1); /*On copie le contenu a partir des coordonnées */
/* On lit les coordonnées de déplacement */
if( pointeur == 'X' ){
X_int = atoi(pointeur_tmp);
}
else if( pointeur == 'Y' ){
Y_int = atoi(pointeur_tmp);
}
else if( pointeur == 'Z' ){
Z_int = atoi(pointeur_tmp);
}
}
if(pouce == TRUE ){
X_int = X_int * 100;
Y_int = Y_int * 100; /*On convertie les coordonnées en pas du charlyrobot */
Z_int = Z_int * 100;
}
else{
X_int = X_int * 25.4 * 100;
Y_int = Y_int * 25.4 * 100;
Z_int = Z_int * 25.4 * 100;
}
sprintf(X_char,"%d",X_int);
sprintf(Y_char,"%d",Y_int);
sprintf(Z_char,"%d",Z_int);
/* ******************************** Création de "chaine entrante" pour la fonction mouvement *******************************/
/* On entre la méthode */
if(absolu == TRUE ){
/* On ajoute "@0M" au buffer_envoie */
buffer_envoie = "@0M " ;
}
else{
/* On ajoute "@0A" au buffer_envoie */
buffer_envoie = "@0A " ;
}
/* Puis les coordonnées et la vitesse */
/* X */
if( X_char != NULL ){
strcat(buffer_envoie," ");
strcat(buffer_envoie,X_char);
}
else{
strcat(buffer_envoie," 0");
}
/* Ajout de la vitesse */
strcat(buffer_envoie," 1000");
/* Y */
if( Y_char != NULL){
strcat(buffer_envoie," ");
strcat(buffer_envoie,Z_char);
}
else{
strcat(buffer_envoie," 0");
}
/* Ajout de la vitesse */
strcat(buffer_envoie," 1000");
/* Z */
if( Z_char != NULL){
strcat(buffer_envoie," ");
strcat(buffer_envoie,Z_char);
}
else{
strcat(buffer_envoie," ");
strcat(buffer_envoie,"0");
}
/* Ajout de la vitesse */
strcat(buffer_envoie," 1000");
printf("Chaine envoyé :%s \n",buffer_envoie);
Mouvement(buffer_envoie);
}
if( strcmp ( pointeur,"G01" ) == 0 ){
/* TODO Lecture de coordonnées */
}
if( strcmp ( pointeur,"M2" ) == 0 ){
printf("End of program !\n");
get_out = TRUE;
}
} /* Fin du while */
}
else{
printf("erreur revc !\n");
}
}
else{
printf("Erreur listen !\n");
}
}
else{
printf("Erreur bind !\n");
}
/* On ferme les sockets client et serveur */
printf("Fermeture des sockets client et serveur \n");
close(csock);
close(sock);
}
else{
printf("Erreur socket !\n");
}
return EXIT_SUCCESS;
}
et il affiche donc ca :
michel@michel:~/Dropbox/Projet 2013 (1)/Source Mickaël$ ./STRATO Ouverture socket en mode TCP/IP Ouverture du port 5000 Connexion client socket 4 de 127.0.0.1 : 44884 Buffer recue : G 2 1 G 9 0 G 0 0 X 1 0 0 Y 1 5 rentrer dans first time vrai pointeur:G21 Programmation en mm rentrer dans first time faux pointeur:G90 Déplacement en mode absolue donc @0M rentrer dans first time faux pointeur:G00 juste avant while Erreur de segmentation (core dumped)
j'ai tester dans le debug mais sa aide pas bcp :
Program received signal SIGSEGV, Segmentation fault.
0xb7f65df4 in ?? () from /lib/i386-linux-gnu/libc.so.6
A voir également:
- Erreur de segmentation
- Erreur 0x80070643 - Accueil - Windows
- Erreur de lecture reconnecté en 3s - Forum TV & Vidéo
- Erreur 0x80070643 Windows 10 : comment résoudre le problème de la mise à jour KB5001716 - Accueil - Windows
- Erreur 4101 france tv - Forum Lecteurs et supports vidéo
- Erreur 4201 france tv ✓ - Forum Réseaux sociaux
1 réponse
Bonjour,
Il y a plusieurs problèmes déjà remplacez la boucle while par ça :
ensuite il y aura un problème avec les sprintf qui suivent car vous n'allouez pas la mémoire alors que ce ne sont que des pointeurs il faudra alors changer les variables : char *X_char, *Y_char, *Z_char;
par un truc du genre :
char X_char[8],Y_char[8],Z_char[8];
il y aura un autre problème avec buffer_envoie, les strcat n'allouent pas plus de mémoire que sprintf et buffer_envoie n'est qu'un pointeur donc le modifier par, par exemple :
char buffer_envoie[4096];
qui permettra aussi à strcat de fonctionner par la même.
Et il vous faudra modifier les lignes du genre :
ça on ne peut pas le faire après la déclaration d'un pointeur/tableau seulement pendant la déclaration qu'on le peut, bref pouvez utiliser strcpy qui existe pour ce genre de truc :
Après reste un problème dans la façon dont vous vérifiez :
alors que juste au dessus le if avec G00 et le strtok met la var pointeur à NULL enfin faut remanier un peu tout ça.
Edit: pour trouver la ligne qui fait planter le programme compiler avec l'option -g de gcc,
par exemple si le programme se trouve dans main.c, utilisez :
gcc -g main.c -o main
ensuite ne lancez par le programme de cette façon :
./main
mais utiliser le debugger gdb, faites ainsi :
gdb main
puis lorsque gdb est lancé envoyez la commande "run" ou le raccourci "r" :
r
gdb va lancer le programme et quand ça plante il donne de l'info, vous pouvez utiliser la commande "backtrace" ou le raccourci "bt" pour remonter le problème :
bt
Il y a plusieurs problèmes déjà remplacez la boucle while par ça :
printf("juste avant while \n");
pointeur = strtok(NULL," ");
while(pointeur!=NULL){
printf(test while\n");
pointeur_tmp=pointeur;
if(*pointeur_tmp=='X') X_int=atoi(++pointeur);
else if(*pointeur_tmp=='Y') Y_int=atoi(++pointeur);
else if(*pointeur_tmp=='Z') X_int=atoi(++pointeur);
pointeur=strtok(NULL," ");
}
ensuite il y aura un problème avec les sprintf qui suivent car vous n'allouez pas la mémoire alors que ce ne sont que des pointeurs il faudra alors changer les variables : char *X_char, *Y_char, *Z_char;
par un truc du genre :
char X_char[8],Y_char[8],Z_char[8];
il y aura un autre problème avec buffer_envoie, les strcat n'allouent pas plus de mémoire que sprintf et buffer_envoie n'est qu'un pointeur donc le modifier par, par exemple :
char buffer_envoie[4096];
qui permettra aussi à strcat de fonctionner par la même.
Et il vous faudra modifier les lignes du genre :
buffer_envoie = "@0M " ;
ça on ne peut pas le faire après la déclaration d'un pointeur/tableau seulement pendant la déclaration qu'on le peut, bref pouvez utiliser strcpy qui existe pour ce genre de truc :
strcpy(buffer_envoie,"@0M");
Après reste un problème dans la façon dont vous vérifiez :
if( strcmp ( pointeur,"G01" ) == 0 ){
alors que juste au dessus le if avec G00 et le strtok met la var pointeur à NULL enfin faut remanier un peu tout ça.
Edit: pour trouver la ligne qui fait planter le programme compiler avec l'option -g de gcc,
par exemple si le programme se trouve dans main.c, utilisez :
gcc -g main.c -o main
ensuite ne lancez par le programme de cette façon :
./main
mais utiliser le debugger gdb, faites ainsi :
gdb main
puis lorsque gdb est lancé envoyez la commande "run" ou le raccourci "r" :
r
gdb va lancer le programme et quand ça plante il donne de l'info, vous pouvez utiliser la commande "backtrace" ou le raccourci "bt" pour remonter le problème :
bt