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