2011-04-30 81 views
23

Valgrind的拋出了我這個錯誤:Valgrind的叫喊關於未初始化的字節

==11204== Syscall param write(buf) points to uninitialised byte(s) 
==11204== at 0x4109033: write (in /lib/libc-2.13.so) 
==11204== by 0x8049654: main (mmboxman.c:289) 
==11204== Address 0xbe92f861 is on thread 1's stack 
==11204== 

什麼問題?我無法找到它所咆哮的未初始化的字節。 下面是代碼刑事線(所提到的289行是調用函數鎖止的一個):

Request request;    
Response response;    

fillRequest(&request, MANADDUSER, getpid(), argument1, NULL, NULL, 0, 0); 
lockUp(&request, &response, NULL); 

這裏的功能原型和結構聲明:

void fillRequest(Request *request, char code, pid_t pid, char *name1, char *name2, char *object, int id, size_t size) 
{ 
    int k; 

    request->code = code; 
    request->pid = getpid(); 

    if(name1) for(k=0; k<strlen(name1)+1; k++) request->name1[k] = name1[k]; 
    else   request->name1[0] = '\0'; 

    if(name2) for(k=0; k<strlen(name2)+1; k++) request->name2[k] = name2[k]; 
    else   request->name2[0] = '\0'; 

    if(object) for(k=0; k<strlen(name2)+1; k++) request->name2[k] = name2[k]; 
    else   request->object[0] = '\0'; 

    request->id = id; 
    request->size = size; 
} 

void lockUp(Request *request, Response *response, void **buffer) 
{ 
    int fifofrom, fifoto, lock;  /* file descriptor delle fifo e del lock */ 

    /* locko per l'accesso alle FIFO */ 
    if((lock = open(LOCK, O_RDONLY)) == -1) logMmboxman("error in opening LOCK\n", 1); 
    else          logMmboxman("opened LOCK\n", 0); 

    if(flock(lock, LOCK_EX) == -1)   logMmboxman("error in acquiring LOCK\n", 1);    
    else            logMmboxman("acquired LOCK\n", 0); 

    /* apro la fifoto e scrivo la mia richiesta */ 
    if((fifoto = open(FIFOTOMMBOXD, O_WRONLY)) == -1) logMmboxman("error in opening FIFOTO\n", 1); 
    else            logMmboxman("opened FIFOTO\n", 0); 

    if((write(fifoto, request, sizeof(Request))) != sizeof(Request)) logMmboxman("error in writing FIFOTO\n", 1); 
    else                logMmboxman("written on FIFOTO\n", 0); 
    close(fifoto); 

    /* rimango in attesa della risposta da mmboxd sulla fifofrom */ 
    if((fifofrom = open(FIFOFROMMMBOXD, O_RDONLY)) == -1) logMmboxman("error in opening FIFOFROM\n", 1); 
    else             logMmboxman("opened FIFOFROM\n", 0); 

    if((read(fifofrom, response, sizeof(Response))) != sizeof(Response)) logMmboxman("error in reading FIFOFROM\n", 1); 
    else                 logMmboxman("read from FIFOFROM\n", 0); 
    close(fifofrom); 

    /* se mi deve comunicare un buffer riapro la fifo e lo leggo */ 
    if(response->size) 
    { 
      if((fifofrom = open(FIFOFROMMMBOXD, O_RDONLY)) == -1) logMmboxman("error in opening FIFOFROM again for the buffer\n", 1); 
      else             logMmboxman("opened FIFOFROM again for the buffer\n", 0); 

      *buffer = (void*)malloc(response->size); 

      if(read(fifofrom, *buffer, response->size) != response->size) logMmboxman("error in reading FIFOFROM again for the buffer\n", 1); 
      else               logMmboxman("read from FIFOFROM again for the buffer\n", 0); 
      close(fifofrom);  
    } 

    /* letta la risposta rilascio il lock */ 
    if(flock(lock, LOCK_UN) == -1)   logMmboxman("error in releasing LOCK\n", 1);    
    else          logMmboxman("released LOCK\n", 0); 

    return; 
} 

typedef struct 
{ 
    char code;   
    pid_t pid;   
    char name1[41];  
    char name2[41];  
    char object[101]; 
    int id;    
    size_t size;   
} Request; 

typedef struct 
{ 
    char result;  
    int num;   
    int num2; 
    size_t size;  
} Response; 

回答

35

Request結構具有陣列name1,name2等,它們包含以空字符結尾的字符串。當你填寫它們時,你不會寫過空終止符。後來當你將結構寫入文件時,valgrind會抱怨,因爲這些字節未初始化。還可能有其他未初始化的字節(例如,由編譯器插入的填充)。

這不一定是一個問題,除了一個小的安全問題:以前的內容可能包含敏感信息,將被寫入文件。

您可以在填充其字段之前將結構memset設置爲0以避免此錯誤。

+0

是的,絕對正確。我解決了你建議的memset。非常感謝!!! – 2011-04-30 20:20:48

+11

這實際上是'strncpy'是正確的解決方案的地方 - 這種情況*正是它爲*創建的。 – 2011-04-30 21:46:13