![为什么 ltrace 不显示对 glibc __nss_configure_lookup() 的调用](https://linux22.com/image/179738/%E4%B8%BA%E4%BB%80%E4%B9%88%20ltrace%20%E4%B8%8D%E6%98%BE%E7%A4%BA%E5%AF%B9%20glibc%20__nss_configure_lookup()%20%E7%9A%84%E8%B0%83%E7%94%A8.png)
我试图了解ltrace
命令是如何工作的。
所以我一直在闲逛/etc/nsswitch.conf
。我在那里有一个“hosts:resolve”行 - 它告诉glibc动态加载nss-resolve
进行主机名查找时的插件模块。我希望看到插件被加载ltrace
:
$ ltrace getent hosts google.com
mtrace() = <void>
setlocale(LC_ALL, "") = "en_GB.UTF-8"
textdomain("libc") = "libc"
argp_parse(0x55e7c8bf5140, 3, 0x7fffd79d00c8, 0) = 0
strcmp("hosts", "hosts") = 0
inet_pton(10, 0x7fffd79d11fb, 0x7fffd79cff60, 0) = 0
inet_pton(2, 0x7fffd79d11fb, 0x7fffd79cff60, 38) = 0
gethostbyname2(0x7fffd79d11fb, 10, 0, 55) = 0x7fbb0311b340
inet_ntop(10, 0x55e7c8f3ba38, 0x7fffd79cfef0, 46) = 0x7fffd79cfef0
printf("%-15s %s", "2a00:1450:4009:", "google.com") = 35
__overflow(0x7fbb03118760, 10, 0x7fffd79cf990, 02a00:1450:4009:816::200e google.com) = 10
+++ exited (status 0) +++
输出中没有任何内容ltrace
看起来像是正在加载插件,尽管我可以确认/lib/x86_64-linux-gnu/libnss_resolve.so.2
确实使用strace
.
例如,我 99% 确定加载过程涉及一个电话到__nss_configure_lookup()
来自 glibc/nss/nsswitch.c但输出中没有这样的调用 - 为什么?有没有办法看到使用或其他工具__nss_configure_lookup()
被调用?ltrace
答案1
$ ltrace getent hosts google.com
例如,我 99% 确定加载过程涉及从 glibc/nss/nsswitch.c 调用 __nss_configure_lookup()
为什么会这样呢?您没有使用-s
标志 [1]:
% ltrace getent -s hosts:dns hosts google.com
...
__nss_configure_lookup(0x563d2eecc194, 0x7ffcff9ec80f, 5, 9) = 0
...
ltrace 的输出中没有任何内容看起来像是正在加载插件,
ltrace
无法跟踪库内部的任何调用。使用像这样的调试器,gdb
您可以在任意位置设置断点和观察点。
[1] 引用您链接到的来源:
879 static error_t
880 parse_option (int key, char *arg, struct argp_state *state)
881 {
882 char *endp;
883 switch (key)
884 {
885 case 's':
886 endp = strchr (arg, ':');
887 if (endp == NULL)
888 /* No specific database, change them all. */
889 for (int i = 0; databases[i].name != NULL; ++i)
890 __nss_configure_lookup (databases[i].name, arg);
891 else
892 {
893 int i;
894 for (i = 0; databases[i].name != NULL; ++i)
895 if (strncmp (databases[i].name, arg, endp - arg) == 0)
896 {
897 __nss_configure_lookup (databases[i].name, endp + 1);
898 break;
899 }
900 if (databases[i].name == NULL)
901 error (EXIT_FAILURE, 0, gettext ("Unknown database name"));
902 }
903 break;