您尚未登录。

#1 2019-05-05 15:38:46

lujun9972
会员
注册时间: 2016-10-21
帖子: 73

(已解决)调用res_ninit函数时出现段错误

代码:

#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>

int main()
{
  res_state res;
  res_ninit(res);
  /* printf("found %d nameservers", res->nscount); */
  /* int class = ns_c_in; */
  /* int type = QUERY; */
  /* char answer[256]=""; */
  /* res_nquery(res, "www.baidu.com", class, type, answer, sizeof(answer)); */
  res_nclose(res);
  /* printf("answer=%s", answer); */
}

编译:

gcc  resolve.c -lm -lpthread -lresolv -o resolve

执行结果:

./resolve 
段错误 (核心已转储)

glibc的版本

lujun9972:tmp/ $ /lib/libc.so.6 
GNU C Library (GNU libc) stable release version 2.29.
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 8.2.1 20181127.
libc ABIs: UNIQUE IFUNC ABSOLUTE
For bug reporting instructions, please see:
<https://bugs.archlinux.org/>.

操作系统版本:

lujun9972:tmp/ $ uname -a
Linux T520 5.0.9-arch1-1-ARCH #1 SMP PREEMPT Sat Apr 20 15:00:46 UTC 2019 x86_64 GNU/Linux

最近编辑记录 lujun9972 (2019-05-05 21:22:10)

离线

#2 2019-05-05 17:44:39

依云
会员
所在地: a.k.a. 百合仙子
注册时间: 2011-08-21
帖子: 8,384
个人网站

Re: (已解决)调用res_ninit函数时出现段错误

突然发现我是不是学了假的 C 啊……指针不像指针,分配空间用 calloc……

#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <stdlib.h>

int main() {
  res_state res = calloc(1, sizeof(*res));
  res_ninit(res);
  printf("found %d nameservers\n", res->nscount);
  int class = C_IN;
  int type = T_A;
  unsigned char answer[512];
  int n = res_nquery(res, "www.baidu.com", class, type, answer, sizeof(answer));
  res_nclose(res);
  printf("answer={ ");
  for(int i=0; i<n; i++){
    printf("%02x ", answer[i]);
  }
  printf("}\n");
}

26fbcc061291155aecc2840ce8381cb5486b5a.png

离线

#3 2019-05-05 19:01:14

lujun9972
会员
注册时间: 2016-10-21
帖子: 73

Re: (已解决)调用res_ninit函数时出现段错误

哦哦,对不起,没怎么写C语言,忘了分配内存了。这里用calloc而不是malloc分配内存有什么特殊的原因吗?

另外再问一下,res_nquery里的class和type的可选值在那里定义啊?我只能在 man solver 中看到op type可以是 QUERY,IQUERY和NS_NOTIFY_OP,没看到T_A和C_IN在哪里定义的?

而且answer的值居然是二进制的,无法直接解读...请问有C函数可以转换吗?

最近编辑记录 lujun9972 (2019-05-05 19:18:54)

离线

#4 2019-05-05 20:20:31

依云
会员
所在地: a.k.a. 百合仙子
注册时间: 2011-08-21
帖子: 8,384
个人网站

Re: (已解决)调用res_ninit函数时出现段错误

callac 是在栈上分配的。本来我是要直接 struct __res_state 的,但你看下划线开头的,很显然不是给你正常用的。
QUERY 和 IQUERY 那些是 res_nmkquery 用的。它叫 op 不是 type。type 就是 DNS 记录的类型,有 A、AAAA、CNAME、TXT、MX、SRV 等等。class 那个好像我只见过 IN。
至于这些 C 宏是哪里定义的,我也不知道啊。我去翻这个 resolv 的源码的时候,看到它带了一堆测试,我就随便找了几个看了看。

那个 answer 当然是二进制的。返回你字符串你要用的时候不还得再转回去么。不过我没想到它返回的是整个 DNS 消息。如果你是要解析得到 IP 地址的话,用 getaddrinfo 啊。

离线

#5 2019-05-05 20:23:41

依云
会员
所在地: a.k.a. 百合仙子
注册时间: 2011-08-21
帖子: 8,384
个人网站

Re: (已解决)调用res_ninit函数时出现段错误

总之很多 C 库是越用越讨厌。太别扭了,好多还要研究半天它到底该怎么用。所以自从 Rust 稳定之后我就尽量不写 C 了。

离线

#6 2019-05-05 21:21:43

lujun9972
会员
注册时间: 2016-10-21
帖子: 73

Re: (已解决)调用res_ninit函数时出现段错误

明白了,谢谢

离线

页脚