[C] Bus Error

di il
13 risposte

[C] Bus Error

Buonasera ragazzi,

non sono un grande esperto di C quindi chiedo a voi spiegazioni in merito ad una situazione anomala che mi si è presentata.

Ho scritto un programma in C su Lubuntu (installato su macchina virtuale) processore pc:AMD, il programma consente di avere una comunicazione tcp tra peer.

Tale programma nella mia macchina funziona tranquillamente.

Ho passato tale programma ad un mio collega il quale ha un pc con Ubuntu (non macchina virtuale) con processore INTEL.

quando compila il programma non ottiene errori ma, in fase di esecuzione ad un certo punto ottiene un Bus Error.

Non ho idea del perché, confido in un vostro chiarimento.

Grazie e buona serata.

13 Risposte

  • Re: [C] Bus Error

    UP
  • Re: [C] Bus Error

    Ci vorrebbe il codice, il bus error è quando vuoi accedere ad una posizione della memoria che la cpu non può accedervi,oppure un per cosi dire semplice errore di allineamento o per un problema con i file della memoria virtuale, quindi le cause possono essere molteplici e bisogna indagare sulla causa che al 100% è dovuta al codice e non alla distro o alla architetura hardware.
  • Re: [C] Bus Error

    E' necessario il codice.
  • Re: [C] Bus Error

    Buongiorno ragazzi e grazie per le risposte.

    Il codice e' un po lungo , magari posso prvare a vedere se si blocca sempre in un punto preciso e postare il codice di quella parte.

    Tuttavia, la cosa che mi ha dato sospetti e' che , su due pc con lubuntu funziona su uno ubuntu no
  • Re: [C] Bus Error

    Non è detto che da una parte "sembri" funzionare e dall'altra no ... sicuramente c'è un errore nel codice. Se non lo posti (almeno la parte che ti sembra la causa) rimarrai con il dubbio.
  • Re: [C] Bus Error

    Ok, dunque provo inanzitutto a descrivere brevemente la situazione.

    Si tratta di un progetto p2p per lo scambio di file tra peer (torrent like)

    In particolare, ho un Bootstrap sempre attivo che fa da governance, ossia "accoglie" i nuovi nodi (peer) che entrano nella rete. I peer fanno riferimento a dei superpeer.

    Mi sembra che al mio collega dava errore anche in fase di entrata di un nuovo nodo (peer/superpeer) nella rete.

    Posto dunque codice di quella parte

    Bootstrap:
    
    void avviaBootstrap(int BOOTSTRAP_PORT) {
    
    
    	if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* crea il socket */
    		perror("errore in socket");
    		exit(1);
    	}
    
    int reuse0=1;
    int status = 0;
    status =setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse0, sizeof(reuse0));
     if (-1 == status)
        {
            perror("setsockopt(...,SO_REUSEADDR,...)");
        }
    	memset((void *) &server_address, 0, sizeof(server_address));
    	server_address.sin_family = AF_INET;
    	server_address.sin_addr.s_addr = htonl(INADDR_ANY); /* il server accetta
    	 connessioni su una qualunque delle sue intefacce di rete */
    	server_address.sin_port = htons(BOOTSTRAP_PORT); /* numero di porta del server */
    
    	/* assegna l'indirizzo al socket */
    	if ((bind(server_sockfd, (struct sockaddr *) &server_address,
    			sizeof(server_address))) < 0) {
    		perror("errore in bind");
    		exit(1);
    	}
    
    	/*  Create a connection queue */
    	if (listen(server_sockfd, BACKLOG) < 0) {
    		perror("errore in listen");
    		exit(1);
    	}
    
    	// Now wait for clients and requests.
    	for (;;) {
    		printf("server waiting...\n");
    
    		client_len = sizeof(client_address);
    
    		/* accetta una connessione con un client */
    		if ((client_sockfd = accept(server_sockfd,
    				(struct sockaddr *) &client_address, &client_len)) < 0) {
    			perror("errore in accept");
    			exit(1);
    		}
    
    		//receive the MSG
    		bytecount = recv(client_sockfd, buff, BUFLEN - 1, 0);
    		if (bytecount == -1) {
    			perror("recv");
    			exit(1);
    		}
    
    		buff[bytecount] = '\0';
    		strcpy(MSG_ricevuto, buff);
    
    		printf("MSG Received lato boot: \"%s\"\n", MSG_ricevuto);
    
    
                      //gestiamo il messaggio ricevuto:
    
                        //  (1) Vediamo se e' Join Peer o Join SuperPeer
                        //  (2) Se Join SuperPeer chiamiamo l'opportuna funzione e restituiamo ACK
                        //  (3) Se Join Peer chiamiamo l'opportuna funzione e restituiremo al Peer l'ip del superpeer scelto
    
       // NEL DETTAGLIO :
            //vediamo chi ci ha contattato:
                      gestione_messaggiBootstrap(MSG_ricevuto);
            //in base a quello che è successo ho dei valori diversi nelle variabili ipSuperGlobal e portSuperGlobal
            //se ho ricevuto il Join SuperPeer avrò : ipSuperGlobal="ACK" , portSuperGlobal="";
            //se invece ho ricevuto il Join Peer avrò: ipSuperGlobal=ipSuperScelto, portSuperGlobal=portSuperScelto
    
                      //fine gestione messaggio ricevuto
    
    
             //concateno ipSuperGlobal e portSuperGlobal
    //char ritorno[100];
    //printf("ipsuperglobal2 :%s\n",ipSuperGlobal);
    //printf("portsuperglobal2 :%s\n",portSuperGlobal);
    
    printf("arrayGlobal : %s\n",arrayGlobal);
    
    
    //strcpy(ritorno,"");
      //      strcpy(ritorno,ipSuperGlobal);
        //    strcat(ritorno,"&&");
          //  strcat(ritorno,portSuperGlobal);
    //printf("ritorno lato boot %s \n",ritorno);
              
                    //a questo punto invio a chi mi ha contattato la risposta:
                           //send the reply
    			//if (send(client_sockfd, messaggioPeer, strlen(messaggioPeer) + 1, 0)
                            if (send(client_sockfd, arrayGlobal, strlen(arrayGlobal) + 1, 0)
    					== -1) {
    				perror("send");
    				exit(1);
    			}
    }
    
    } //fine funzione gestisce avvio Bootstrap
    
    


    La funzione gestione_messaggiBootstrap:
    
    void gestione_messaggiBootstrap(char stringa[MAX_STRING_LEN]) {
    
    
     MYSQL mysql;
            MYSQL_ROW row;        // la riga
            MYSQL_RES* result;
            MYSQL_FIELD* field;     // il campo ritornato
    
    
    	int pos5, stlun;
    	char ssss[200];
    	int i = 0;
    	stlun = strlen(stringa); //lunghezza stringa
    	for (i = 0; i < stlun - 1; i++) {
    		ssss[i] = 'z';
    	}
    	for (i = 0; i < stlun - 1; i++) {
    		char* appo = substring(stringa, i, 1);
    		if (appo)
    			ssss[i] = *appo;
    	}
    	for (i = 0; i < stlun - 1; i++) {
    		printf("elem %c\n", ssss[i]);
    	}
    	pos5 = 0;
    	stlun = 0;
    	pos5 = five_pos(ssss); //posizione quinta &
    	stlun = strlen(stringa); //lunghezza stringa
    
    	int begin1 = 0;
    	int end1 = 2;
    	char* comando = substring(stringa, begin1, end1);
    
    	int begin2 = 4;
    	int end2 = 1;
    	char* nodo = substring(stringa, begin2, end2);
    
    	int begin3 = 7;
    	int end3 = pos5 - 7;
    	printf("pos5 %i", pos5);
    	char* ip = substring(stringa, begin3, end3);
    
    	int begin4 = pos5 + 2;
    	int end4 = 4;
    	char* porta = substring(stringa, begin4, end4);
    	int portai;
    	portai = atoi(porta);
    
    	int begin5 = pos5 + 8;
    	int end5 = stlun - begin5;
    	char* altro = substring(stringa, begin5, end5);
    
    //stampo: EVENTUALMENTE DA RIMUOVERE
    	printf("comando    = %s\n", comando);
    	printf("nodo    = %s\n", nodo);
    	printf("ip    = %s\n", ip);
    	printf("porta    = %s\n", porta);
    	printf("altro    = %s\n", altro);
    
    
    //da qui in poi gestisco effettivamente il messaggio
    // prima ho spacchettato il messaggio...
    //
    //vediamo che tipo di messaggio e' (JOIN,UPDATE,...)
       //vediamo se e' JOIN SuperPeer
    
    	if (strcmp(comando, "/J") == 0) {
                      printf("devo gestire join");
    		// il comando e' JOIN, vediamo chi l'ha invocato (Peer o SuperPeer)
    		if (strcmp(nodo, "S") == 0) {
                                printf(" join superpeer");
    			//il JOIN e' stato invocato dal superpeer quindi :
    			gest_join_superpeer(ip, portai, altro);
                            // return("Join SuperPeer OK");
    		}
                       else if(strcmp(nodo, "P") == 0) {
                                printf("devo gestire Join Peer");
    			//il JOIN e' stato invocato dal peer quindi :
    			gest_join_peer(ip, portai, altro);
    
    
                            
    		          }
              }
    else if(strcmp(comando,"/B")==0)
    {
       gest_join_bis(ip,portai,altro);
    }
    
    
    	
    
    }
    


    Invece, lato superpeer la funzione per contattare il Bootstrap ed entrare nella rete:
    
    void client(char* ipLocale, char* ipDestinatario, int BOOTSTRAP_PORT) {
    //CLIENT
    	int sockfd;
    	struct sockaddr_in servaddr;
    	int bytecount;
    	char buff[MAXLINE];
    
    	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { /* crea il socket */
    		perror("errore in socket");
    		exit(1);
    	}
    
    	memset((void *) &servaddr, 0, sizeof(servaddr)); /* azzera servaddr */
    	servaddr.sin_family = AF_INET; /* assegna il tipo di indirizzo */
    	servaddr.sin_port = htons(BOOTSTRAP_PORT); /* assegna la porta del server */
    	/* assegna l'indirizzo del server prendendolo dalla riga di comando.
    	 L'indirizzo šš una stringa e deve essere convertito in intero in
    	 network byte order. */
    
    	if (inet_pton(AF_INET, ipDestinatario, &servaddr.sin_addr) <= 0) {
    		fprintf(stderr, "errore in inet_pton per %s\n", ipDestinatario);
    		exit(1);
    	}
    
    	/* stabilisce la connessione con il server */
    	if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
    		perror("errore in connect");
    		exit(1);
    	}
    
    //compongo il messaggio:
      //char* MSG = componi_messaggio("/J","S","190.1.2.3","3333","vuoto");
    
    
    	//Invia msg al bootstrap
    	if (send(sockfd, ritorno, strlen(ritorno) + 1, 0) == -1) {
    		perror("send");
    		exit(1);
    	}
    
    	//receive the message from server  (riceve risposta)
    	bytecount = recv(sockfd, buff, BUFLEN - 1, 0);
    	if (bytecount == -1) {
    		perror("recv");
    		exit(1);
    	}
    
    	buff[bytecount] = '\0';
    	strcpy(MSG_ricevuto, buff);
    
               if(strcmp(buff,"ACK&&ACK")==0){
    printf("connessione avvenuta!! \n");
    }
    	//printf("MSG Received: \"%s\"\n", MSG_ricevuto);
    
    }
    
  • Re: [C] Bus Error

    UP
  • Re: [C] Bus Error

    Non sei in grado di identificare la funzione o il blocco di codice in cui avviene il problema?
  • Re: [C] Bus Error

    No, ho gia ristretto di molto in campo di azione

    non ho molte informazione perche' sul mio pc funziona, mentre l'ho visto non funzionare sul pc del collega una sola volta..

    Questo bus error non so proprio da cosa possa dipendere... Magari Dal processore, o dal S.O.
  • Re: [C] Bus Error

    No ... è un problema di codice che si manifesta solo in determinate situazioni che magari non succedono nel caso in cui lo esegui sul tuo PC.

    Devi per forza aggiungere delle righe che scrivano in un log e far girare il programma dal tuo amico nella speranza che si manifesti il problema. A quel punto esamina il file di log e individua la riga precisa.
  • Re: [C] Bus Error

    oregon ha scritto:


    No ... è un problema di codice che si manifesta solo in determinate situazioni che magari non succedono nel caso in cui lo esegui sul tuo PC.
    cosa intendi?

    le operazioni sono standard nel senso che seguiamo un ordine ben preciso, non puo aver fatto nulla di diverso da quello che faccio io.
  • Re: [C] Bus Error

    Ad esempio, se il codice scrive in memoria in una zona non appartenente al tuo processo, nel tuo caso, a seconda dello stato momentaneo della memoria, potresti scrivere "sporcando" memoria se nza ottenere errori. In un'altra situazione della memoria in un altro sistema, potresti finire in zone di memoria non allocate al processo.
  • Re: [C] Bus Error

    Che brutta cosa

    troppo imprevedibile per essere gestita in maniera puntuale...
Devi accedere o registrarti per scrivere nel forum
13 risposte