Errore Bus in un programma in c client server

di il
15 risposte

Errore Bus in un programma in c client server

Salve a tutti sto facendo un programma per una chat/condivisione file tra clienti molto semplice...il programma si occupa di mandare messaggi tra clienti (ed eventuali file) tramite socket. Se i clienti sono online li visualizzano in in diretta altrimenti vengono salvati in un array per poi essere visualizzati se il cliente lo richiede...mi funziona perfettamente per tutte le operazioni solo che ho notato che se un cliente manda 2 o + messaggi (a clienti offline) e successivamente richiede i propri messaggi pendenti mi da errore di bus.
La cosa strana è che solo questa combinazione di operazioni genera errore e ancora più strana è che se uso valgrind per capire dove sta l'errore le operazioni vanno tutte a buon fine.
Non posto il codice perchè è molto molto lungo, volevo sentire qualche commento su quello che ho scritto qui sopra (se già magari qualcuno puo' avere una mezza idea) e nel caso poi postare parti di codice per riuscire a trovare una soluzione.

15 Risposte

  • Re: Errore Bus in un programma in c client server

    Cosa intendi per "errore di bus"? L'applicativo si impianta?
    Se si impianta e riesci a ottenere questo piantamento sul tuo pc allora ti consiglio di identificare il punto, all'interno del codice, che manifesta il problema: debuggando oppure attivando delle informazioni di debug (ad es. in Linux gcc dando -g in compilazione e attivando la generazione del core dump) oppure inserendo delle printf() (o scritture su un txt di log) nei punti principali.
  • Re: Errore Bus in un programma in c client server

    E' sicuramente un problema legato ad un puntatore, che punta ad un buffer non allocato o il cui valore è sbagliato.
  • Re: Errore Bus in un programma in c client server

    Grazie mille per le risposte immediate

    oregon ha scritto:


    E' sicuramente un problema legato ad un puntatore, che punta ad un buffer non allocato o il cui valore è sbagliato.
    si è quello che ho pensato anche io però non capisco perchè utilizzando valgrind funziona perfettamente.
    Effettivamente con qualche printf ho notato che effettivamente una variabile non viene inizializzata ma non capisco perchè se eseguo il comando da solo o con altre operazioni funziona mentre con 2 o + messaggi da inviare e dopo richiesta dei messaggi pendenti funziona solo con valgrind (Questo è il punto fondamentale che vorrei capire)
  • Re: Errore Bus in un programma in c client server

    maffo95 ha scritto:


    Grazie mille per le risposte immediate

    oregon ha scritto:


    E' sicuramente un problema legato ad un puntatore, che punta ad un buffer non allocato o il cui valore è sbagliato.
    si è quello che ho pensato anche io però non capisco perchè utilizzando valgrind funziona perfettamente.
    SEMBRA funzionare perché valgrind modifica lo stato della memoria allocata e quindi, i dati che prima andavano a finire in zone vietate (con relativa eccezione) adesso "sporcano" zone di memoria del processo senza "apparenti" conseguenze.
  • Re: Errore Bus in un programma in c client server

    E quindi scusa come trovo una soluzione? Vado nel dettaglio così magari riesci a spiegarmi bene una possibile soluzione... il puntatore che mi da problemi è un size_t del client dove devo memorizzare quanti messaggi pendenti deve leggere, quindi io sulla socket ho pensato di fare così essendo un numero piccolo casto il numero come char e mi diventa il corrispettivo in ASCII e scrivo il carattere sulla socket quando il client la legge prende il carattere e lo casta *(size_t*) è giusto come ragionamento? Perchè ripeto il comando se eseguito senza i messaggi da inviare prima va...Se in questa maniera mi va ad intaccare zone vietate c'è un modo per far si che questo non accada?
  • Re: Errore Bus in un programma in c client server

    Se non si vede il codice in dettaglio è impossibile rispondere.
  • Re: Errore Bus in un programma in c client server

    Ti mando la parte riguardante questo bug

    Server:
    user->data.hdr.len=2;                                                //2 in quanto per ipotesi MaxHistMsgs non sarà mai >126 (per come è stato implementato il client)                                    
    	user->data.buf=malloc(sizeof(char)*2);
    	int dim;
    	if(chiede->len >= MaxHistMsgs) dim=MaxHistMsgs; else dim=chiede->len;  //segno i messaggi pendenti
    	user->data.buf[0]=(char)dim;                                                //dim in ASCII
    	user->data.buf[1]='\0';                                                            //carattere di fine stringa anche se è solo un carattere
    	user->hdr.op=OP_OK;
    	lock_acquire(&key[n]);
    	err=sendMsg(c_sk,user);
    	lock_release(&key[n]);
    Client (non modificabile dato dal professore):
    if (readData(connfd, &msg.data) <= 0) {
    	    perror("reply data");
    	    return -1; 
    	}	
    	// numero di messaggi che devo ricevere
        size_t nmsgs = *(size_t*)(msg.data.buf);
    	char *FILENAMES[nmsgs]; // NOTA: si suppone che nmsgs non sia molto grande
    	size_t nfiles=0;
    readData:
    data->buf=malloc(sizeof(char)*dim);
    	while(dim>0){                            //leggo messaggio
    		fatto=read((int)fd,data->buf,dim);
    		if(fatto<=0){
    			if(errno==EINTR){
    				continue;
    			}
    			return fatto;		
    		}
    		dim-=fatto;
    	}
    sendMsg:
    while(dim>0){                                    //mando il messaggio
    		fatto=write((int)fd,msg->buf,dim);
    		if(fatto==-1){
    			if(errno==EINTR){
    				continue;
    			}
    			return -1;		
    		}
    		dim-=fatto;
    	}
    send e read data devono essere generali per qualsiasi cosa da inviare la dim la passo sempre come un carattere ASCII (per avere la lunghezza da leggere per ogni "porzione" della socket)
  • Re: Errore Bus in un programma in c client server

    Ma se fai un po' di debugging, in quale riga si presenta l'errore?
  • Re: Errore Bus in un programma in c client server

    Quando deve leggere nel client questa variabile:

    size_t nmsgs = *(size_t*)(msg.data.buf);

    con un po' di printf ho notato che non riesce proprio a castare msg.data.buf cioè se faccio:

    printf("%d\n",msg.data.buf[0]);

    mi da il valore che mi aspetto quindi la lettura della socket è corretta...è quando fa l'inizializzazione di nmsgs che non funziona

    P.S.
    ho notato che se faccio:

    size_t nmsgs = *(size_t*)(msg.data.buf[0]);

    funziona tutto correttamente il problema è che il client come ho già detto non lo posso modificare
  • Re: Errore Bus in un programma in c client server

    Scusa, ma se il client fa una cosa del genere

    size_t nmsgs = *(size_t*)(msg.data.buf);

    vuol dire che si attende che msg.data.buf sia un puntatore a un dato numerico (non una null string) e un dato di tipo size_t.
    Quindi nella readData dovrai allocare

    data->buf=malloc(sizeof(size_t));

    e leggere tale valore. La sendMsg dovrà inviare il dato dello stesso tipo-
  • Re: Errore Bus in un programma in c client server

    oregon ha scritto:


    Scusa, ma se il client fa una cosa del genere

    size_t nmsgs = *(size_t*)(msg.data.buf);

    vuol dire che si attende che msg.data.buf sia un puntatore a un dato numerico (non una null string) e un dato di tipo size_t.
    Quindi nella readData dovrai allocare

    data->buf=malloc(sizeof(size_t));

    e leggere tale valore. La sendMsg dovrà inviare il dato dello stesso tipo-
    Non posso farlo perchè la sendMsg (come la read) è una funzione generale per tutti gli scambi di messaggi non posso avere funzioni diverse per ogni scambio di messaggi. E in più nel client msg.data.buf è allocata come stringa (in quanto nella stessa operazione conteneva una stringa da passare al server). La mia idea era quella di passare i numeri in generale (tipo in questo caso) trasformandoli in caratteri ASCII per poi "riportarli" a numeri tramite cast
  • Re: Errore Bus in un programma in c client server

    Guarda ... io non vedo tutto il codice ma solo quello che mostri tu. Nel client (che non puoi modificare) c'è questa linea che è chiara

    size_t nmsgs = *(size_t*)(msg.data.buf);

    Nella readData tu allochi dim elementi di tipo char ... ma quanto vale questo dim nella readData?
  • Re: Errore Bus in un programma in c client server

    La dim nella read come nella send è la dimensione della stringa che il client deve leggere dalla socket che in questo caso particolare è 2 il primo è il numero dei messaggi pendenti scritto come carattere ASCII mentre il secondo è il carattere di fine stringa... So che per questa procedura sembra una cosa fatta male perché basterebbe dirli di leggere solo il carattere ma le funzioni (read e send) devono essere in generale come ti ho già detto e più che altro in una situazione del genere non funziona mentre da solo o con altre operazioni funziona tranquillamente...ma tu intendi di passarli direttamente la posizione del puntatore in memoria? Perché sarebbe una soluzione che non vorrei fare per un fatto di sicurezza del programma (cosa che porta punteggio nel progetto)
  • Re: Errore Bus in un programma in c client server

    oregon ha scritto:


    Scusa, ma se il client fa una cosa del genere

    size_t nmsgs = *(size_t*)(msg.data.buf);

    vuol dire che si attende che msg.data.buf sia un puntatore a un dato numerico (non una null string) e un dato di tipo size_t.
    Quindi nella readData dovrai allocare

    data->buf=malloc(sizeof(size_t));

    e leggere tale valore. La sendMsg dovrà inviare il dato dello stesso tipo-
    Posso provare a fare una cosa del genere ma nella reaf il buf è una stringa quindi non penso funzioni perché comunque sia per poterla trascrive dovrei sempre trasformare il numero in un carattere
Devi accedere o registrarti per scrivere nel forum
15 risposte