Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [C] Errore Run-Time Check Failure #2-Stack around the variable 'record' was corrupted

    Salve a tutti...
    è da una settimana che cerco di risolvere questo problema ma non so proprio da cosa possa dipendere; sto cercando di scrivere un programma che gestisca una elenco telefonico.
    Ho scritto una funzione "aggiungiRecord" che dopo essere stata eseguita mi lancia l'errore seguente:


    codice:
    Run-Time Check Failure #2-Stack around the variable 'record' was corrupted
    il codice è :

    codice:
    int aggiungiRecord(int sock){  		
    Record record;  		
    char permessi[RISPOSTA];         
    char risposta[RISPOSTA];  		                    
    /* Invio al server il tipo di servizio desiderato */  
               while(send(sock, "AGGIUNGI", RISPOSTA,0) <= 0){                    
     if(errno != EINTR){                             
    if(errno == ECONNRESET || errno == EPIPE){                                     
    printf("\n\nCONNESSIONE INTERROTTA, il server si è disconnesso in maniera scorretta!");fflush(stdout);                                     
    return -1;                             }                             
    else{                                    
     printf("Lettura fallita\n");fflush(stdout);                                    
     perror("Errore tipo");fflush(stdout);                                     
    return -1;                             
    }                     
    }                     
    printf("Errore durante la system call, ripeto\n");fflush(stdout);             }  			                                      
    
    /* Resetto il valore della stringa permessi */  
               memset(permessi, 0, strlen(permessi));                   
    /* Ricevo il tipo di permesso dal server */             
    while(recv(sock, permessi, RISPOSTA,0) <= 0){                    
     if(errno != EINTR){                            
     if(errno == ECONNRESET || errno == EPIPE){                                     
    printf("\n\nCONNESSIONE INTERROTTA, il server si è disconnesso in maniera scorretta!");fflush(stdout);                                    
     return -1;                             
    }                             
    else{                                     
    printf("Lettura fallita\n");fflush(stdout);                                    
     perror("Errore tipo");fflush(stdout);                                    
     return -1;                             
    }                     
    }                     
    printf("Errore durante la system call, ripeto\n");fflush(stdout);            
     }                   
    
    /* Ho i permessi sufficienti per questa operazione */             
    if(strcmp("NO", permessi) != 0){                           
    
    /* Resetto i valori della struct recordTemp */ 					
    memset(record.nome, 0, sizeof(record.nome)); 					memset(record.cognome, 0, sizeof(record.cognome)); 					memset(record.numeroTelefono, 0, sizeof(record.numeroTelefono));  
                                           
    /* Resetto il valore della stringa risposta */                     
    memset(risposta, 0, RISPOSTA);                            
    /* Digito il nome da aggiungere */                     
    printf("\nInserisci nome e premi INVIO   ");fflush(stdout);                    
     while(scanf("%s", record.nome) == -1){                            
     if(errno != EINTR){                                     
    printf("\nErrore scanf\n");                                    
     chiusuraClient();                             
    }                     
    }                           
    /* Invio il nome al server */                     
    while(send(sock, record.nome,strlen(record.nome),0) <= 0){                            
     if(errno != EINTR){                                     
    if(errno == ECONNRESET || errno == EPIPE){                                             
    printf("\n\nCONNESSIONE INTERROTTA, il server si è disconnesso in maniera scorretta!");fflush(stdout);                                             
    return -1;                                     
    }                                     
    else{                                            
     printf("Lettura fallita\n");fflush(stdout);                                             
    perror("Errore tipo");fflush(stdout); 
                                                return -1;                                     
    }                            
     }                             
    printf("Errore durante la system call, ripeto\n");fflush(stdout);                     }                           
    /* Digito il cognome da aggiungere */ 
                        printf("\nInserisci cognome e premi INVIO   ");fflush(stdout);                     while(scanf("%s", record.cognome) == -1){                             
    if(errno != EINTR){                                     
    printf("\nErrore scanf\n");                                    
     chiusuraClient();                             
    }                     
    }                           
    /* Invio il cognome al server */                    
    
     while(send(sock, record.cognome, strlen(record.cognome),0) <= 0){
                                 if(errno != EINTR){
                                         if(errno == ECONNRESET || errno == EPIPE){
                                                 printf("\n\nCONNESSIONE INTERROTTA, il server si è disconnesso in maniera scorretta!");fflush(stdout);                                             
    return -1;                                     
    }                                    
     else{                                             
    printf("Lettura fallita\n");fflush(stdout);
                                                 perror("Errore tipo");fflush(stdout);
                                                 return -1;                                     }                             }                             
    printf("Errore durante la system call, ripeto\n");fflush(stdout);                     }                                 
    /* Digito il numero di telefono da aggiungere */
                         printf("\nInserisci numero di telefono e premi INVIO   ");fflush(stdout);                    
     while(scanf("%s", record.numeroTelefono) == -1){                             
    if(errno != EINTR){                                     
    printf("\nErrore scanf\n");                                     
    chiusuraClient();                             
    }                     
    }                          
     /* Invio il numero di telefono al server */                     
    while(send(sock, record.numeroTelefono, strlen(record.numeroTelefono),0) <= 0){                             
    if(errno != EINTR){                                    
     if(errno == ECONNRESET || errno == EPIPE){                                             
    printf("\n\nCONNESSIONE INTERROTTA, il server si è disconnesso in maniera scorretta!");fflush(stdout);                                            
     return -1;                                     
    }                                     
    else{                                             
    printf("Lettura fallita\n");fflush(stdout);                                            
     perror("Errore tipo");fflush(stdout);                                            
     return -1;                                    
     }                             
    }                            
     printf("Errore durante la system call, ripeto\n");fflush(stdout);                     }                                 
    /* Ricevo la risposta dal server */                     
    while(recv(sock, risposta, RISPOSTA,0) <= 0){                             
    if(errno != EINTR){                                    
     if(errno == ECONNRESET || errno == EPIPE){                                             
    printf("\n\nCONNESSIONE INTERROTTA, il server si è disconnesso in maniera scorretta!");fflush(stdout);                                            
     return -1;                                     
    }                                     
    else{                                             
    printf("Lettura fallita Numero tel\n");fflush(stdout);                                             perror("Errore tipo");fflush(stdout);                                             
    return -1;                                     
    }                             
    }                             
    printf("Errore durante la system call, ripeto\n");fflush(stdout);                     
    }
                               /* Il record è già  presente nell'archivio */                     if(strcmp(risposta, "NO") == 0){                            
     printf("\nTentativo fallito. Record già  presente nell'archivio!\n");fflush(stdout);                             
    premiInvio();                             
    return 1;                     
    }                           
    /* Operazione conclusa con successo */                     
    else{                             
    printf("\nOperazione conclusa con successo!\n");fflush(stdout);                             premiInvio();                            
     return 1;                     
    }             
    }                        
     /* Non ho i permessi sufficienti per questa operazione */             
    else{                    
     printf("\nPermessi non sufficienti per quest'operazione!\n");                     premiInvio();                     
    return 1;             
    }     
    }
    mentre la struct di Record l'ho scritta così:

    codice:
     typedef struct{
                 char nome[NOME];             
                 char cognome[COGNOME];             
                 char numeroTelefono[NUMERO];     
                 }Record;

    vi prego datemi una mano...non so proprio come risolvere...grazie!!!

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Stai corrompendo lo stack in qualche modo con qualche scrittura/copia non lecita.

    Una possibile causa può essere questa istruzione

    codice:
        memset(permessi, 0, strlen(permessi));
    che è sicuramente errata in quanto, essendo "permessi" (in quel punto del codice) dichiarata ma non inizializzata, la strlen() restituisce un numero impredicibile che può essere anche maggiore della dimensione del buffer.

    Non è detto che sia quella la causa dell'errore ma di sicuro è un'istruzione non corretta.
    every day above ground is a good one

  3. #3
    Le scanf che hai scritto non fanno alcun controllo sulla lunghezza della stringa acquisita, per cui possono sforare i buffer di record.

    Per inciso, la scanf restituisce il numero di campi correttamente acquisiti, per cui per verificare se c'è stato un errore di acquisizione normalmente si scrive if(scanf(...)!=numero_campi_da_acquisire) ...
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Grazie mille ad entrambi per avermi risposto...
    comunque problema risolto...aveva ragione
    YuYevon anche se non riesco a capire perche l'errore si riferisse alla variabile "record" mentre il problema si trovava in "permessi"...
    grazie

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Sia "record" che "permessi" sono variabili locali della funzione, pertanto sono allocate nello stesso segmento di memoria del processo (o meglio del thread), lo stack. Evidentemente il "trabordamento" della memset() va a corrompere la memoria relativa alla variabile "record", probabilmente sovrascrivendo i byte di padding che il compilatore aggiunge tra una variabile e l'altra per il detecting run-time degli stack overflow (ed è proprio il tuo caso). Il fatto che la variabile interessata sia proprio "record" può dipendere dal fatto che questa è allocata in memoria "vicino" a "permessi", essendo peraltro dichiarata immediatamente prima all'interno del codice. Un'analisi più accurata si può fare chiaramente solo con un po' di debugging a basso livello, con gli strumenti forniti dalla piattaforma di sviluppo.

    Fai comunque attenzione anche alle scanf() e considera la possibilità di sostituirle con la funzione fgets() con la quale puoi eseguire un controllo sulla dimensione del buffer in cui scrivi.
    every day above ground is a good one

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.