来自getaddrinfo()的4个错误的无效读取

时间:2014-08-09 19:18:00

标签: c valgrind getaddrinfo

在我的程序上运行Valgrind会生成4号错误的无效读取。我正试图找到它,但似乎无法找到它。

#define _GNU_SOURCE
#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/socket.h>

void download_file (void){
    int ret;
    char *service = "http";
    char *site = "www.sony.com";
    char *page = "/";
    char *msg;
    struct addrinfo *res;
    struct addrinfo hints;
    const char * format = "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0\r\n\r\n";
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    asprintf(&msg, format, page, site);

    if((ret = getaddrinfo(site, service, &hints, &res)) != 0){
        fprintf(stderr, "download_file: getaddrinfo error: %s\n", gai_strerror(ret));
        freeaddrinfo(res);
        free(msg);
        return;
    }
    freeaddrinfo(res);
    free(msg);
    return;
}
int main (void){
    download_file();
    exit(0);
}

以下是Valgrind的输出:

==3215== Memcheck, a memory error detector
==3215== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==3215== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==3215== Command: ./a.out
==3215== 
==3215== Invalid read of size 4
==3215==    at 0x401718C: strlen (strlen.S:53)
==3215==    by 0x4012F1F: _dl_open (dl-open.c:672)
==3215==    by 0x495982F: do_dlopen (dl-libc.c:86)
==3215==    by 0x400F0BF: _dl_catch_error (dl-error.c:178)
==3215==    by 0x4959917: dlerror_run (dl-libc.c:47)
==3215==    by 0x495997F: __libc_dlopen_mode (dl-libc.c:160)
==3215==    by 0x4935447: __nss_lookup_function (nsswitch.c:434)
==3215==    by 0x493569B: __nss_lookup (nsswitch.c:229)
==3215==    by 0x493DB93: getservbyname_r@@GLIBC_2.4 (getXXbyYY_r.c:203)
==3215==    by 0x48FDBA3: gaih_inet_serv (getaddrinfo.c:164)
==3215==    by 0x48FE917: gaih_inet (getaddrinfo.c:332)
==3215==    by 0x490145F: getaddrinfo (getaddrinfo.c:2438)
==3215==  Address 0x4988e64 is 44 bytes inside a block of size 46 alloc'd
==3215==    at 0x4835978: malloc (vg_replace_malloc.c:263)
==3215==    by 0x400EE03: _dl_signal_error (dl-error.c:90)
==3215==    by 0x400903F: _dl_map_object (dl-load.c:2556)
==3215==    by 0x4013157: dl_open_worker (dl-open.c:226)
==3215==    by 0x400F0BF: _dl_catch_error (dl-error.c:178)
==3215==    by 0x4012C9B: _dl_open (dl-open.c:633)
==3215==    by 0x495982F: do_dlopen (dl-libc.c:86)
==3215==    by 0x400F0BF: _dl_catch_error (dl-error.c:178)
==3215==    by 0x4959917: dlerror_run (dl-libc.c:47)
==3215==    by 0x495997F: __libc_dlopen_mode (dl-libc.c:160)
==3215==    by 0x4935447: __nss_lookup_function (nsswitch.c:434)
==3215==    by 0x493569B: __nss_lookup (nsswitch.c:229)
==3215== 
==3215== 
==3215== HEAP SUMMARY:
==3215==     in use at exit: 0 bytes in 0 blocks
==3215==   total heap usage: 67 allocs, 67 frees, 6,461 bytes allocated
==3215== 
==3215== All heap blocks were freed -- no leaks are possible
==3215== 
==3215== For counts of detected and suppressed errors, rerun with: -v
==3215== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 25 from 11)

有人可以帮我理解为什么会出现这种错误吗?或者如何纠正它?在我的搜索中,我只发现与gethostbyaddr()相关的错误。

看起来无效的读取错误来自getaddrinfo(),但是我无法在我的系统上找到文件getaddrinfo.c来尝试纠正它。

2 个答案:

答案 0 :(得分:1)

这类似于此处讨论的问题:http://git.661346.n2.nabble.com/PATCH-valgrind-ignore-SSE-based-strlen-invalid-reads-td6175816.html

优化的strlen()在搜索null终止符char时经常读取完整的单词。这可以通过安全的方式实现,即使它在技术上违反了分配边界。

可能需要更新版本的valgrind(3.9.0是最新版本),或者需要为您正在使用的运行时配置或修补valgrind。您可能希望为此配置抑制:http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress

答案 1 :(得分:0)

看起来像GNU libc的问题。看看valgrind输出,我猜你使用的是GNU libc的旧版本?

Valgrind输出中显示的文件名和行号不会(始终)对应于文件系统上的实际文件。 Valgrind从编译器将调试信息部分中的文件名和行号放入可执行二进制文件中。