1

我无法破译我得到的 Valgrind 输出。例如,我有一个错误,说我正在执行大小为 1 的非法写入。所以我在 malloc 中添加了一个,但这并没有改变任何东西。由于我以前从未使用过 Valgrind,所以我认为最好在网上搜索没有回应后寻求帮助。请注意,我不是在寻找答案,所以我没有复制我的代码。我想被推向正确的方向,这样我就可以与未来的错误作斗争。谢谢!

==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 }
4

3 回答 3

3

如果flag为 0,那么您永远不会初始化header1..4字符串中的任何数据,因此当您尝试使用 获取它们的长度时strlen,您会读入未初始化的垃圾。无论设置如何,您都应确保始终将标头值初始化为空字符串flag

此外,不需要strcat(..., "\0")在字符串上 -strcpy并且strcat始终以空值终止字符串(实际上,"\0"与空字符串无法区分"",因为它们的第一个字节都是 NUL 字节)。在将一堆字符串连接在一起时,请注意Shlemiel the Painter 算法。

于 2012-11-07T23:09:01.730 回答
1

1)你 malloc 了 5 块内存,并没有在你的函数中释放它们。这些应该在您返回或退出之前释放。请注意 valgrind 是如何说您有 326 个字节的definitely lost.

2)如果flag是假的,你的header*变量永远不会被设置为任何东西,这就是为什么 valgrind 在第 280 行给你一堆错误。随后,它在第 301 行附近复制没有什么好处,所以你会得到更多的错误。

于 2012-11-07T23:11:57.413 回答
1

由于您对编写“整洁+酷”的代码感兴趣,我将尝试将您推向正确的方向。对抗未来错误的最佳方法是保持简单。

什么是简单的?尽可能少行,但仍保持可读性和易于理解。您可以用 30 行代码代替 87 行 (304-217) 的代码。

此外,寻找代码可能进入“未定义”行为的地方也是一种很好的心态。在 get_header() 中包含标头的大小是一种很好的做法。如果它在 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);
}

我希望你觉得这有帮助。

于 2012-11-10T06:13:47.603 回答