简体   繁体   English

Valgrind错误

[英]Valgrind Errors

I am having trouble deciphering the Valgrind output that I am getting. 我无法解读我得到的Valgrind输出。 For example I have an error that says I am doing an illegal write of size 1. So I added one to the malloc and that doesn't change anything. 例如,我有一个错误,说我在非法写入大小为1的文件。因此,我在malloc中添加了一个,这并没有改变任何内容。 Since I have never used Valgrind before, I thought it would be best to get some help after searching online yielded no responses. 由于我以前从未使用过Valgrind,因此我认为最好是在在线搜索没有反应后寻求帮助。 Please be aware that I am not looking for the answer so I have not reproduced my code. 请注意,我不是在寻找答案,所以我没有复制我的代码。 I would like to be pushed in the correct direction so that I can combat future errors. 我想朝着正确的方向前进,以便我能够应对未来的错误。 Thanks! 谢谢!

==28881== Memcheck, a memory error detector
==28881== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==28881== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==28881== Command: ./sws root
==28881==
==28892== Conditional jump or move depends on uninitialised value(s)
==28892==    at 0x4C286D9: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x4040B7: get_headers (html.c:280)
==28892==    by 0x402D77: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Conditional jump or move depends on uninitialised value(s)
==28892==    at 0x4C286D9: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x4040C5: get_headers (html.c:280)
==28892==    by 0x402D77: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Conditional jump or move depends on uninitialised value(s)
==28892==    at 0x4C286D9: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x4040D3: get_headers (html.c:280)
==28892==    by 0x402D77: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Conditional jump or move depends on uninitialised value(s)
==28892==    at 0x4C286D9: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x4040E1: get_headers (html.c:280)
==28892==    by 0x402D77: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2874C: strcpy (mc_replace_strmem.c:311)
==28892==    by 0x4041E1: get_headers (html.c:299)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2875F: strcpy (mc_replace_strmem.c:311)
==28892==    by 0x4041E1: get_headers (html.c:299)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be034 is 4 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x4041F7: get_headers (html.c:300)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2838C: strcat (mc_replace_strmem.c:176)
==28892==    by 0x4041F7: get_headers (html.c:300)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be034 is 4 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2839F: strcat (mc_replace_strmem.c:176)
==28892==    by 0x4041F7: get_headers (html.c:300)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be061 is 15 bytes before a block of size 40 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x403E53: get_headers (html.c:224)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x40420D: get_headers (html.c:301)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x40420D: get_headers (html.c:301)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2838C: strcat (mc_replace_strmem.c:176)
==28892==    by 0x40420D: get_headers (html.c:301)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be061 is 15 bytes before a block of size 40 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x403E53: get_headers (html.c:224)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x404223: get_headers (html.c:302)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x404239: get_headers (html.c:303)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2838C: strcat (mc_replace_strmem.c:176)
==28892==    by 0x404239: get_headers (html.c:303)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be098 is 0 bytes after a block of size 40 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x403E53: get_headers (html.c:224)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C286E4: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x402E0F: read_page (networking.c:348)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Syscall param socketcall.sendto(msg) points to unaddressable byte(s)
==28892==    at 0x5121052: send (send.c:28)
==28892==    by 0x40276D: send_msg (networking.c:245)
==28892==    by 0x402E29: read_page (networking.c:348)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892==
==28892== HEAP SUMMARY:
==28892==     in use at exit: 337 bytes in 10 blocks
==28892==   total heap usage: 19 allocs, 9 frees, 3,307 bytes allocated
==28892==
==28892== LEAK SUMMARY:
==28892==    definitely lost: 337 bytes in 10 blocks
==28892==    indirectly lost: 0 bytes in 0 blocks
==28892==      possibly lost: 0 bytes in 0 blocks
==28892==    still reachable: 0 bytes in 0 blocks
==28892==         suppressed: 0 bytes in 0 blocks
==28892== Rerun with --leak-check=full to see details of leaked memory
==28892==
==28892== For counts of detected and suppressed errors, rerun with: -v
==28892== Use --track-origins=yes to see where uninitialised values come from
==28892== ERROR SUMMARY: 348 errors from 17 contexts (suppressed: 4 from 4)
==28881==
==28881== HEAP SUMMARY:
==28881==     in use at exit: 0 bytes in 0 blocks
==28881==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==28881==
==28881== All heap blocks were freed -- no leaks are possible
==28881==
==28881== For counts of detected and suppressed errors, rerun with: -v
==28881== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

217 int get_headers(char* time, char* last_modified, char* server, char* content_type, size_t msglen, char* header, int flag)
218 {
219         char* header1 = NULL;
220         char* header2 = NULL;
221         char* header3 = NULL;
222         char* header4 = NULL;
223         char* header5 = NULL;
224
225         if ((header1 = (char*)malloc(strlen("Date: ")+strlen(time)+2) ) ==NULL)
226         {
227                 fprintf(stderr, "%s: No more memory\n", getprogname());
228                 exit(EXIT_FAILURE);
229         }
230
231
232         strcpy(header1, "Date: ");
233         strcat(header1, time);
234         strcat(header1, "\n");
235
236
237         if ((header2 = (char*)malloc(strlen("Last-Modified: ")+strlen(last_modified)+5) ) ==NULL)
238         {
239                 fprintf(stderr, "%s: No more memory\n", getprogname());
240                 exit(EXIT_FAILURE);
241         }
242
243
244         strcpy(header2, "Last-Modified: ");
245         strcat(header2, last_modified);
246         strcat(header2, "\n");
247
248
249         if ((header3 = (char*)malloc(strlen("Server: ")+strlen(server)+5) ) ==NULL)
250         {
251                 fprintf(stderr, "%s: No more memory\n", getprogname());
252                 exit(EXIT_FAILURE);
253         }
254
255
256         strcpy(header3, "Server: ");
257         strcat(header3, server);
258         strcat(header3, "\n");
259
260
261         if ((header4 = (char*)malloc(strlen("Content-Type: ")+strlen(content_type)+5) ) ==NULL)
262         {
263                 fprintf(stderr, "%s: No more memory\n", getprogname());
264                 exit(EXIT_FAILURE);
265         }
266
267
268         strcpy(header4, "Content-Type: ");
269         strcat(header4, content_type);
270         strcat(header4, "\n");
271
272
273         int content_length = strlen(header1)+strlen(header2)+strlen(header3)+strlen(header4)+strlen("Content-Length: ")+msglen+5;
274         char temp[10] = {' '};
275         snprintf(temp, sizeof(msglen),"%d", content_length);
276
277         if ((header5 = (char*)malloc(strlen("Content-Length: ")+strlen(temp)+5) ) ==NULL)
278         {
279                 fprintf(stderr, "%s: No more memory\n", getprogname());
280                 exit(EXIT_FAILURE);
281         }
282
283
284         strcpy(header5, "Content-Length: ");
285         strncat(header5, temp, strlen(temp));
286         strcat(header5, "\n\n");
287
288
289         if(flag == 1)
290         {
291                 strcpy(header, header1);
292                 strcat(header, header2);
293                 strcat(header, header3);
294                 strcat(header, header4);
295                 strcat(header, header5);
296         }
297
298         return content_length;
299         free(header1);
300         free(header2);
301         free(header3);
302         free(header4);
303         free(header5);
304 }

If flag is 0, then you never initialize any of the data in the header1..4 strings, so when you try to get their lengths with strlen , you read in uninitialized garbage. 如果flag为0,则您永远不会初始化header1..4字符串中的任何数据,因此当您尝试使用strlen获得它们的长度时,会读取未初始化的垃圾。 You should make sure to always initialize the header values to empty strings regardless of the flag setting. 无论flag设置如何,都应确保始终将标头值初始化为空字符串。

Also, there's no need to strcat(..., "\\0") onto the string -- strcpy and strcat always null-terminate the strings (in fact, "\\0" is indistinguishable from the empty string "" , since both of their first bytes are the NUL byte). 另外,也不需要将strcat(..., "\\0")放在字符串上strcpystrcat始终对字符串进行null终止(实际上, "\\0"与空字符串""是无法区分的,因为两者他们的第一个字节中的第一个是NUL字节)。 And beware of Shlemiel the Painter algorithms when concatenating a bunch of strings together. 当将一串字符串连接在一起时,请谨防Shlemiel Painter算法

1) You malloc'd 5 pieces of memory and did not free them in your function. 1)您分配了5个内存,但没有在函数中释放它们。 These should be freed before you return or exit. 这些应该在您返回或退出之前释放。 Notice how valgrind is saying you have 326 bytes that were definitely lost . 请注意valgrind怎么说,您definitely lost有326个字节definitely lost

2) If flag is false, your header* variables never get set to anything, which is why valgrind is giving you a bunch of errors on line 280. Subsequently, there's nothing good for it to copy later around line 301, so you get more errors. 2)如果flag为false,则您的header*变量永远都不会设置为任何值,这就是为什么valgrind在第280行给您一些错误的原因。随后,在301行附近复制它没有任何好处,因此您会得到更多错误。

Since you are interested in writing 'neat + cool' code, I am going to attempt to nudge you in the right direction. 由于您对编写“简洁+出色”的代码感兴趣,因此,我将尝试向正确的方向轻推。 The best way to combat future errors is to keep it simple. 应对未来错误的最佳方法就是保持简单。

What is simple? 有什么简单的? Doing it in as few lines as possible, but still keeping it readable and easy to understand. 尽可能少地编写代码,但仍保持可读性和易懂性。 Instead of 87 lines (304-217) of code, you can do it in 30 lines. 您可以用30行来代替87行(304-217)的代码。

Also, it is a good mindset to lookout for places where the code could go into 'undefined' behavior. 同样,寻找代码可能进入“未定义”行为的地方也是一个好主意。 It would be good practice to include the size of the header in get_header(). 最好在get_header()中包含标头的大小。 If it is not available in get_header(), then there is no way to prevent potential buffer overflow/memory corruption. 如果在get_header()中不可用,则无法防止缓冲区溢出/内存损坏。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
get_header(char *date, char *last_m, char *server, char *c_type,
        int c_len, char *header, int flag, int h_len);

int
main()
{
        char header[500];
        int n;

        n = get_header(
                "Fri, 09 Nov 2012 09:22:06 GMT", /* Date            */
                "Fri, 09 Nov 2012 09:10:32 GMT", /* Last modified   */
                "MySuperDuperServer/V 1.0.0.0",  /* Server name     */
                "Text/html",                     /* Content type    */
                1234,                            /* Content length  */
                header,                          /* Destination buf */
                1,             /* 1 = write into header, 0 = Do not */
                sizeof(header)                   /* header buf size */
        );             

        printf("%s\n", header);

        exit(0);
}

/* Header lines should end with CR LF */

#define DATE   "Date: %s\r\n"
#define LAST_M "Last-Modified: %s\r\n"
#define SERVER "Server : %s\r\n"
#define C_TYPE "Content-Type: %s\r\n"
#define C_LEN  "Content-Length: %d\r\n\r\n"

#define HEADER DATE LAST_M SERVER C_TYPE C_LEN

int
get_header(char *date, char *last_m, char *server, char *c_type,
        int c_len, char *header, int flag, int h_len)
{
        char *d;
        int r;

        if (flag == 1) {
                d = header;
        }
        else if ((d = (char *)malloc(h_len)) == 0) {
                printf("out of memory\n");
                exit(1); /* exit(EXIT_FAILURE); */
        }

        r = snprintf(d, h_len, HEADER, date, last_m, server, c_type, c_len);

        if (flag == 0) {
                free(d);
        }

        return(r);
}

I hope you find this helpful. 我希望你觉得这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM