【问题标题】:getaddrinfo, Segmentation Faultgetaddrinfo,分段错误
【发布时间】:2019-02-12 08:29:47
【问题描述】:

我收到以下代码的分段错误。

我需要程序做的是,当输入一个无效/未知的名称或服务作为参数时,它只显示该特定服务的错误,并继续处理提供的其余服务。

现在,如果我在服务行中的任何位置包含无效服务(例如 ./dnslookup www.nhawurha.com www.google.com 或 www.google.com www.nhawurha.com),该程序就可以工作

但如果仅将无效服务用作唯一参数(例如 ./dnslookup www.nhawurha.com),则会在打印错误后给我一个分段错误

任何形式的帮助都将不胜感激,谢谢!

#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>

#define BUFLEN 1500    

int main(int argc, char *argv[]) {
struct addrinfo hints, *ai, *result;    
char ipaddrv4[BUFLEN];
char ipaddrv6[BUFLEN];
int error;

if (argc < 2) {
    fprintf(stderr, "Missing <hostname> after %s \n", argv[0]);
    return 0;
}

for (int j = 1; j < argc; j++) {

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;    /* IPv4, IPv6, or anything */
    hints.ai_socktype = SOCK_DGRAM; /* Dummy socket type */

    error = getaddrinfo(argv[j], NULL, &hints, &result);
    if (error) {
        fprintf(stderr, "ERROR (%s: %s)\n", argv[j], gai_strerror(error));
        continue;
    }

    for (ai = result; ai != NULL; ai = ai->ai_next) {
        if (ai->ai_family == AF_INET) {
            struct sockaddr_in *ipv4 = (struct sockaddr_in *) ai->ai_addr;
            void *addr = &(ipv4->sin_addr);
            inet_ntop(AF_INET, addr, ipaddrv4, BUFLEN);
            printf("%s IPv4 %s\n", argv[j], ipaddrv4);
        }

        else if (ai->ai_family == AF_INET6) {
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) ai->ai_addr;
            void *addr = &(ipv6->sin6_addr);
            inet_ntop(AF_INET6, addr, ipaddrv6, BUFLEN);
            printf("%s IPv6 %s\n", argv[j], ipaddrv6);
        }

        else {
            continue;
        }
    }       
}

freeaddrinfo(result);
return 0;

}

【问题讨论】:

  • 你究竟是从哪里得到错误的?错误信息是什么?你都尝试过什么?
  • @Skandix,对不起,我忘了提供这些信息!我在这里收到错误:error = getaddrinfo(argv[j], NULL, &amp;hints, &amp;result); if (error) { fprintf(stderr, "ERROR (%s: %s)\n", argv[j], gai_strerror(error)); continue; } 错误消息是:“分段错误(核心转储)”。将“继续”更改为“返回 0”会阻止出现分段错误错误,但在提供无效服务后程序不会处理任何其他参数。

标签: getaddrinfo


【解决方案1】:

查看“结果”参数 - 如果您唯一的查找失败,结果将未初始化,freeaddrinfo 将出现段错误。尝试先将其初始化为 NULL。

如果您有多个查找,则会出现第二个问题 - 内存泄漏,因为您没有在每个结果上调用 freeaddrinfo

所以我认为你的逻辑应该更像:

for each command line arg
   if lookup succeeds
     print result
     free result
   else
     print error

请参阅man pagegetaddrinfo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 2014-10-20
    • 2018-03-03
    • 1970-01-01
    • 2018-05-24
    • 2016-04-20
    相关资源
    最近更新 更多