我坚持使用valgrind这个问题来报告我的代码。我正在将PID添加到全局数组(这样做是因为我想在信号处理程序中打印PID)。
Valgrind似乎对将PID放入数组的代码行有问题:
PIDs[number_of_PIDs] = cPID;
这是我的代码:
pid_t *process_ids; //these need to be global b/c they're used in handler for signal
int process_count = 0; //total number of ACTIVE PIDs
void funct() {
//doing unrelated stuff
int status;
rc = fork();
if(rc==-1) {
//error
}
else if(rc==0) {
//child (this runs first b/c I used sleep on parent)
rc=getpid();
//execvp call
//if execvp fails, kill child process
}
else {
sleep(1);
}
wpid = waitpid(-1, &status, WNOHANG));
if(wpid==0||WIFEEXITED(status)) {
PIDs[i]=rc;
i++;
} else {
//printf statement; PID doesn't get added to list
}
}
220 int main()
221 {
222 //LOCAL VARIABLES
223 gettimeofday(&start_time, NULL); //for calculating total time elapsed
224 FILE *fp; //file pointer for opening 'PID.conf' file
225 //char *process = malloc(sizeof(char)*PATH_MAX); //each process stored here
226 char *process_line;
227 size_t len_buffer = 0;
228 char **args = NULL; //array of char * containing the parsed cmds
229 struct sigaction old; //for handling SIGINT
230 memset(&old, 0, sizeof(old)); //initialize sigaction struct
231 int total_processes; //store total no. of lines for mem allocation of PIDs
232 char *process = NULL;
233 char *token;
234 //test for macD.conf file; if doesn't exist, exit program
235 config_exists();
236
237 //count # of processes
238 total_processes = count_total_processes(); //count no. of processes
239 printf("Total Processes: %d\n", total_processes);
240 process_ids = malloc(sizeof(pid_t)*(total_processes)); //mem for PIDs
241 memset(process_ids, -1, sizeof(pid_t)*total_processes);
242
243 fp = fopen("PID.conf", "r");
244 if(fp == NULL)
245 {
246 printf("error: PID.conf file failed to open. terminating...\n");
247 exit(1);
248 }
249 //free(process_ids);
250 //free(process);
251
252 //check for Ctrl+c and handle it
253 old.sa_handler = &handler; //struct old = handler() funct
254 sigaction(SIGINT, &old, NULL); //catches SIGINT (Ctrl+C)
255
256 //char *token; //storage for each token
257 int arg_size = 0; //store # of args
258
259 //grab each line and process the process
260 while((getline(&process, &len_buffer, fp)) != -1)
261 {
262 arg_size = 0;
263 process_line = (char*)malloc(PATH_MAX*sizeof(char)); //allocate
264 process_line[strlen(process)-1] = 0; //remove newline
265 strcpy(process_line, process); //copied to get non-edited version from strtok
266 token = strtok(process, " ");
267
268 //count number of tokens=path/cmd+args
269 while(token!=NULL) {
270 token = strtok(NULL, " ");
271 arg_size++;
272 }
273
274 //parse the process into the individual cmd and its args
275 process_line[strlen(process_line)-1] = 0;//remove newline from cmd
276 strcpy(process, process_line); //copied cmd to print it later
277 //args = malloc(sizeof(char*)*(arg_size+1));
278 args = funct2(process_line, arg_size); //command to actually parse cmd
279
280 //execute the cmd by creating a fork() + exec() call
281 funct(args, process, args[0]);
282
283 //free process_line as not needed
284 free(process_line);
285 int i;
286 for(i=0;i<arg_size;i++)
287 {
288 free(args[i]);
289 }
290 free(args);
291 } //END OF WHILE LOOP FOR PARSING FILE
292 free(process);
293 //free(process_ids); //free later!
294 fclose(fp); //close file, won't need it anymore
295
296 //check each successful process in array process_ids every 5s
297 while(1)
298 {
299 sleep(5); //sleep for 5s
300 check_status(process_ids); //pass PID array to print status
301 }
302
303 return 0;
304 }
valgrind错误如下:
==6310== LEAK SUMMARY:
==6310== definitely lost: 0 bytes in 0 blocks
==6310== indirectly lost: 0 bytes in 0 blocks
==6310== possibly lost: 0 bytes in 0 blocks
==6310== still reachable: 24 bytes in 1 blocks
==6310== suppressed: 0 bytes in 0 blocks
==6310== Reachable blocks (those to which a pointer was found) are not shown.
==6310== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==6310==
==6310== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==6310==
==6310== 1 errors in context 1 of 1:
==6310== Invalid write of size 4
==6310== at 0x4010F3: funct
==6310== by 0x401496: main
==6310== Address 0x51db388 is 0 bytes after a block of size 24 alloc'd
==6310== at 0x4C2A0B0: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6310== by 0x40134F: main
==6310==
==6310== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
我做错什么了吗?还是在哪里寻找valgrind错误有其他建议?
编辑:我为PID的总数分配内存,但是我还要检查每个PID是否处于活动/运行状态。仅将那些活动的添加到阵列中。
地址0x51db388是在分配大小为24的块之后的0字节
没有办法是“ 8”个PID。 24除以8就是3,而pid_t
几乎可以肯定是4。
您可能分配了六个pid_t
的空间,但是以某种方式最终使用了九个(包括0到8)。我对为什么在块后写入zero字节而不是eight字节感到困惑,但我敢肯定问题出在您的number_of_PIDs
常量中。
关于PID为何看起来可以正确打印的原因,在数组末尾进行写入是未定义的行为。如果没有人使用那里的内存,没有人(例如valgrind)检查等等,那么您可以在那儿写并读回您写的内容,它将起作用。 但是没有保证。而且,编写的内容越多,其他事物(例如malloc库)需要该内存或将其检出的风险就越大,从而导致严重的故障。甚至更糟的是,随机故障可能很难跟踪并且非常耗时。