memcpy导致的gethostbyname分段错误

r8uurelv  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(185)

我有一个程序,它通过gethostbyname获取txt中的域列表的IP,一个巨大的列表,如数百万个域,并将它们放在struct sockaddr_in中,我使用多线程来使过程更快,在工作4或5分钟后检查所有这些域,我在memcpy代码中得到了准确的分段错误
它是一个linux代码。
所有线程的主例程示例:

#include <netdb.h>
#include <arpa/inet.h>

void* startcheckingdomains(){
    while(1){
        char* domain = "www.google.com";
        struct hostent* hp = gethostbyname(domain);
        struct sockaddr_in sockaddr;

        if(hp == NULL){
            herror("hp");
        }else{
            memcpy(&sockaddr.sin_addr,hp->h_addr,hp->h_length);
        }
    }
}

这是gdb产生的错误:

Thread 535 "main" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffe8f606700 (LWP 27402)]
__memmove_avx_unaligned_erms ()
hs1ihplo

hs1ihplo1#

函数gethostbynamemanual page声明如下:
函数gethostbyname()和gethostbyaddr()可以返回指向静态数据的指针,这些指针可能会被以后的调用覆盖。
这意味着,如果有多个线程同时调用该函数,它们可能会覆盖彼此的数据。
该手册还指出:
Glibc2也有可重入的版本[...] gethostbyname_r()[...]。调用者提供一个宿主结构ret,它将在成功时被填充,以及一个大小为buflen的临时工作缓冲区buf。
因此,如果您使用的是glibc,则在使用函数gethostbyname_r而不是gethostbyname时,问题可能会消失。
或者,您可能希望使用函数getaddrinfo,它也是可重入的。

相关问题