【发布时间】:2016-02-20 04:41:00
【问题描述】:
我正在尝试了解 hello world 程序是如何工作的:
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello World!");
return 0;
}
除了printf 部分外,大部分内容都很简单。我不知道它是如何工作的。为了理解它,我寻找了glibc cross reference并找到了this page。
然后我搜索了printf,它返回了很多results。
现在我的程序正在使用这些printfs 中的哪一个?如何确定?
另外,例如,当打开该页面中的first result 时,printf 函数中的函数将我引导至__printf_chk,其中__printf_chk 中的函数将我引导至__nldbl___vfprintf_chk,其中@ 中的函数987654337@ 将我引向__vfprintf_chk,__vfprintf_chk 中的函数又将我引向__nldbl___vfprintf_chk,它创建了一个无限递归。怎么回事?
简而言之,我应该如何跟踪给定函数/源代码的来源?
【问题讨论】:
-
"现在我的程序正在使用这些 printfs 中的哪一个?如何确定它?"您应该弄清楚该库是如何构建的。这主要取决于如何调用编译器,这在 Makefiles 中定义。这可能同样难以理解。 glibc 不好玩吗? (剧透:glibc 不好玩。)
-
另一个剧透:你最终会在 vfprintf in stdio-common/vfprintf.c 的定义中结束,但要了解它与
__printf之类的函数之间的关系,你将不得不经历一大堆预处理器宏和 GCC 特定的属性声明。 -
@Rhymoid 是所有这些创建/保留可移植性的原因吗?
-
我不能肯定,但这是我的猜测:有一个通用实现绝对可移植,然后针对特定平台的优化进行了一些调整(那些
__nldbl函数似乎与具有long double的系统有关)。为了保持这个解决方案可维护,有一些宏和包装函数层。随着时间的推移,这一层不断增长,并变成了维护负担。 (遗憾的是,这种情况在软件工程中很常见。) -
与 glibc here 相比,知名的替代品包括 musl、uClibc 和 Dietlibc。