Valgrind 对未初始化的字节大喊大叫 [英] Valgrind yells about an uninitialised bytes
问题描述
Valgrind 抛出这个错误:
Valgrind throws me out this error:
==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 行是调用函数 lockUp 的那一行):
What's the problem? I can't find what uninitialised byte it is yelling about. Here are the criminal lines of code (the mentioned 289 line is the one which calls the function lockUp):
Request request;
Response response;
fillRequest(&request, MANADDUSER, getpid(), argument1, NULL, NULL, 0, 0);
lockUp(&request, &response, NULL);
这里是函数原型和结构声明:
Here the functions prototype and structs declaration:
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;
推荐答案
你的 Request
结构有数组 name1
、name2
等包含以空字符结尾的字符串.当你填充它们时,你不会写越空终止符.稍后当您将结构写入文件时,valgrind 会抱怨,因为这些字节未初始化.可能还有其他未初始化的字节(例如编译器插入的填充).
Your Request
structure has arrays name1
, name2
, etc. which contain null-terminated strings. When you fill them, you don't write past the null terminator. Later when you write the structure to the file, valgrind complains because these bytes are uninitialized. There may also be other uninitialized bytes (for example, padding inserted by the compiler).
这不一定是一个问题,除了一个小的安全问题:内存中可能包含敏感信息的先前内容将被写入文件.
This is not necessarily a problem, other than a small security issue: The previous contents of memory, which may hold sensitive information, will get written to the file.
您可以在填充其字段之前将结构设置为 0 以避免此错误.
You can memset the structure to 0 before filling its fields to avoid this error.
这篇关于Valgrind 对未初始化的字节大喊大叫的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!