“冷”的源代码在哪里位于GLIBC中的功能?

发布于 2025-01-29 05:28:33 字数 4112 浏览 1 评论 0原文

我在C中有一个Hello World程序:

#include <stdio.h>

int main() {
    printf("Hello world!\n");
    return 0;
}

编译GCC -Static Hello.c -o Hello

in readfelf -a- wide Hello我找到了一些功能,该功能带有

__assert_fail_base.cold
_nl_load_domain.cold
_IO_new_fclose.cold
_IO_fflush.cold
_IO_puts.cold
_IO_wfile_underflow.cold
_IO_new_file_underflow.cold
_IO_fputs.cold
_IO_fwrite.cold
_IO_getdelim.cold
__printf_fp_l.cold
__printf_fphex.cold
read_encoded_value_with_base.cold
base_of_encoded_value.cold
execute_cfa_program.cold
uw_frame_state_for.cold
uw_install_context_1.cold
execute_stack_op.cold
uw_update_context_1.cold
uw_init_context_1.cold
uw_update_context.cold
_Unwind_RaiseException_Phase2.cold
_Unwind_GetGR.cold
_Unwind_SetGR.cold
_Unwind_Resume.cold
_Unwind_Resume_or_Rethrow.cold
size_of_encoded_value.cold
base_from_object.cold
base_from_cb_data.cold
read_encoded_value_with_base.cold
_Unwind_IteratePhdrCallback.cold
search_object.cold
base_of_encoded_value.cold
read_encoded_value_with_base.cold

在这里

功能上的冷属性用于通知编译器,不太可能执行该功能。该功能针对尺寸而不是速度进行了优化,并且在许多目标上都将其放置在文本部分的特殊小节中,以便所有冷功能都靠近在一起,从而改善了程序的非冷淡部分的代码位置。导致代码中冷函数调用的路径被分支预测机制标记为不可能。因此,这对于标记用于处理不太可能条件的功能(例如Perror)很有用,因为冷的功能可改善在极少数情况下调用标记功能的热功能的优化。

当配置文件反馈可用时,通过-fprofile -use,将自动检测到冷功能,并忽略此属性。

According that I download glibc and switch to commit 160f6c36a374841ee6e2bf2ee0ba05b70634978e指向我的版本git rev list -n 1 $(git tag | grep 2.31-0ubuntu9.7),但是在所有这些操作之后,我找不到上面标记的任何功能强>冷侵略。

我知道GLIBC生成了一些Syscall,但是在glibc/sysdeps/unix/syscalls.lists.lists.list中,我找不到任何有趣的功能。

我还从libc.a中提取函数:

cd /usr/lib/x86_64-linux-gnu/
readelf -a --wide libc.a | egrep '\.cold' | awk '{print $NF}' > libc.a.cold

并将它们与readelf -a- wide Hello |将它们进行了比较。 egrep'\ .cold'| awk'{print $ nf}'&gt; hello.readelf

grep -f libc.a.cold hello.readelf

这些是匹配的函数:

__assert_fail_base.cold
_nl_load_domain.cold
_IO_new_fclose.cold
_IO_fflush.cold
_IO_puts.cold
_IO_wfile_underflow.cold
_IO_new_file_underflow.cold
_IO_fputs.cold
_IO_fwrite.cold
_IO_getdelim.cold
__printf_fp_l.cold
__printf_fphex.cold

并且使用grep -f libc.a.cold hello.readelf -v我找到了无与伦比的功能:

read_encoded_value_with_base.cold
base_of_encoded_value.cold
execute_cfa_program.cold
uw_frame_state_for.cold
uw_install_context_1.cold
execute_stack_op.cold
uw_update_context_1.cold
uw_init_context_1.cold
uw_update_context.cold
_Unwind_RaiseException_Phase2.cold
_Unwind_GetGR.cold
_Unwind_SetGR.cold
_Unwind_Resume.cold
_Unwind_Resume_or_Rethrow.cold
size_of_encoded_value.cold
base_from_object.cold
base_from_cb_data.cold
read_encoded_value_with_base.cold
_Unwind_IteratePhdrCallback.cold
search_object.cold
base_of_encoded_value.cold
read_encoded_value_with_base.cold

问题:

  1. 有人可以帮助我找出我可以在哪里找到冷>功能的源代码吗?
  2. libc.aHello二进制的源代码在哪里,位于哪个库中?

版本:

  • glibc:ldd(ubuntu glibc 2.31-0ubuntu9.7)2.31

  • gcc:gcc(ubuntu 9.4.0-1ubuntu1〜20.04.144.1)9.4.4.0

  • linux发行版:

      distrib_id = ubuntu
    Distrion_Release = 20.04
    distrib_codeName =焦点
    distrip_description =“ ubuntu 20.04.4 lts”
     
  • 内核:5.13.0-41生成

I have a hello world program in C:

#include <stdio.h>

int main() {
    printf("Hello world!\n");
    return 0;
}

Compile it gcc -static hello.c -o hello

In readelf -a --wide hello I found some functions with cold postfix

__assert_fail_base.cold
_nl_load_domain.cold
_IO_new_fclose.cold
_IO_fflush.cold
_IO_puts.cold
_IO_wfile_underflow.cold
_IO_new_file_underflow.cold
_IO_fputs.cold
_IO_fwrite.cold
_IO_getdelim.cold
__printf_fp_l.cold
__printf_fphex.cold
read_encoded_value_with_base.cold
base_of_encoded_value.cold
execute_cfa_program.cold
uw_frame_state_for.cold
uw_install_context_1.cold
execute_stack_op.cold
uw_update_context_1.cold
uw_init_context_1.cold
uw_update_context.cold
_Unwind_RaiseException_Phase2.cold
_Unwind_GetGR.cold
_Unwind_SetGR.cold
_Unwind_Resume.cold
_Unwind_Resume_or_Rethrow.cold
size_of_encoded_value.cold
base_from_object.cold
base_from_cb_data.cold
read_encoded_value_with_base.cold
_Unwind_IteratePhdrCallback.cold
search_object.cold
base_of_encoded_value.cold
read_encoded_value_with_base.cold

From here:

The cold attribute on functions is used to inform the compiler that the function is unlikely to be executed. The function is optimized for size rather than speed and on many targets it is placed into a special subsection of the text section so all cold functions appear close together, improving code locality of non-cold parts of program. The paths leading to calls of cold functions within code are marked as unlikely by the branch prediction mechanism. It is thus useful to mark functions used to handle unlikely conditions, such as perror, as cold to improve optimization of hot functions that do call marked functions in rare occasions.

When profile feedback is available, via -fprofile-use, cold functions are automatically detected and this attribute is ignored.

According that I download glibc and switch to commit 160f6c36a374841ee6e2bf2ee0ba05b70634978e which points to my version git rev-list -n 1 $(git tag | grep 2.31-0ubuntu9.7), but after all of this actions I cannot find any functions from above marked with the cold atribute.

I know that glibc generates some of the syscalls, but I don't find any interesting functions for me in glibc/sysdeps/unix/syscalls.list.

I also extracted cold functions from libc.a:

cd /usr/lib/x86_64-linux-gnu/
readelf -a --wide libc.a | egrep '\.cold' | awk '{print $NF}' > libc.a.cold

and compared them with readelf -a --wide hello | egrep '\.cold' | awk '{print $NF}' > hello.readelf:

grep -f libc.a.cold hello.readelf

These are the matched functions:

__assert_fail_base.cold
_nl_load_domain.cold
_IO_new_fclose.cold
_IO_fflush.cold
_IO_puts.cold
_IO_wfile_underflow.cold
_IO_new_file_underflow.cold
_IO_fputs.cold
_IO_fwrite.cold
_IO_getdelim.cold
__printf_fp_l.cold
__printf_fphex.cold

And with grep -f libc.a.cold hello.readelf -v I found the unmatched functions:

read_encoded_value_with_base.cold
base_of_encoded_value.cold
execute_cfa_program.cold
uw_frame_state_for.cold
uw_install_context_1.cold
execute_stack_op.cold
uw_update_context_1.cold
uw_init_context_1.cold
uw_update_context.cold
_Unwind_RaiseException_Phase2.cold
_Unwind_GetGR.cold
_Unwind_SetGR.cold
_Unwind_Resume.cold
_Unwind_Resume_or_Rethrow.cold
size_of_encoded_value.cold
base_from_object.cold
base_from_cb_data.cold
read_encoded_value_with_base.cold
_Unwind_IteratePhdrCallback.cold
search_object.cold
base_of_encoded_value.cold
read_encoded_value_with_base.cold

Questions:

  1. Can someone please help me to figure out where I can find a source code of cold functions?
  2. Where is the source code of unmatched functions from libc.a and the hello binary located, and from which library are they loaded?

Versions:

  • glibc: ldd (Ubuntu GLIBC 2.31-0ubuntu9.7) 2.31

  • gcc: gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

  • Linux distro:

    DISTRIB_ID=Ubuntu
    DISTRIB_RELEASE=20.04
    DISTRIB_CODENAME=focal
    DISTRIB_DESCRIPTION="Ubuntu 20.04.4 LTS"
    
  • Kernel: 5.13.0-41-generic

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Hello爱情风 2025-02-05 05:28:33

功能不一定必须使用__属性__(((冷)),以使GCC意识到它们是“冷”。当启用适当的优化时,海湾合作委员会可以并且将自己做到这一点。

特别是引用GCC的优化文档:

-freorder-blocks and-partition

除了重新排序编译函数中的基本块外,
为了减少带有分支机构的数量,隔板冷热
基本块进入汇编的单独部分和.o文件,
提高分页和缓存位置性能。

在存在的情况下,此优化自动关闭
异常处理或放松表(使用setJump/longjump在目标上
或针对特定方案),用于Linkonce部分,用于具有
用户定义的部分属性以及任何不
命名部分的支持。当使用-fsplit-stack时,此选项不是
默认启用(避免链接器错误),但可以启用
明确(如果使用工作链接器)。

启用了x86 at Levels -O2-O3-os

如您所见,默认情况下,在-O2-O3-OS上启用了此优化。

一个简单的示例,说明这种自动优化可以应用将是以下情况:

void parent_function(int x) {
    if (__builtin_expect(x == 1337, 1)) {
        some_function(123);
    } else {
        some_function(456);
    }

    // ...
}

gcc可以拆分some_function(甚至parent> parent_function)进入some_functionsome_function.cold,简化了函数的内部逻辑。因此,就您而言,您在编译二进制中看到的这些.cold 不是实际上在源代码中实际定义的,而是由GCC自动产生的。

Functions do not necessarily have to be marked as cold using __attribute__((cold)) in order for GCC to realize that they are "cold". GCC can and will do this by itself when the appropriate optimizations are enabled.

In particular, quoting from GCC's optimizations doc:

-freorder-blocks-and-partition

In addition to reordering basic blocks in the compiled function, in
order to reduce number of taken branches, partitions hot and cold
basic blocks into separate sections of the assembly and .o files, to
improve paging and cache locality performance.

This optimization is automatically turned off in the presence of
exception handling or unwind tables (on targets using setjump/longjump
or target specific scheme), for linkonce sections, for functions with
a user-defined section attribute and on any architecture that does not
support named sections. When -fsplit-stack is used this option is not
enabled by default (to avoid linker errors), but may be enabled
explicitly (if using a working linker).

Enabled for x86 at levels -O2, -O3, -Os.

As you can see, this optimization is enabled by default at -O2, -O3 and -Os.

A simple example of when such an automatic optimization could be applied would be a situation like the following:

void parent_function(int x) {
    if (__builtin_expect(x == 1337, 1)) {
        some_function(123);
    } else {
        some_function(456);
    }

    // ...
}

GCC can split some_function (or even parent_function) into some_function and some_function.cold, simplifying the internal logic of the functions. So in your case, those .cold functions you see in the compiled binary are not actually defined in the source code as such, but rather produced by GCC automatically.

筱果果 2025-02-05 05:28:33

我可以在哪里找到冷功能的源代码?

在GLIBC源代码中。

我找不到上面的任何功能。

。对_silver_searcher感兴趣,以更快地grep

$ git clone git://git.launchpad.net/ubuntu/+source/glibc
Cloning into 'glibc'...
...
$ cd glibc/
$ grep -R --include '*.c' __assert_fail_base
assert/assert.c:__assert_fail_base (const char *fmt, const char *assertion, const char *file,
assert/assert.c:  __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"),
assert/assert-perr.c:  __assert_fail_base (_("%s%s%s:%u: %s%sUnexpected error: %s.\n%n"),

因此,__ assert_fail_baseassert/assert.c中定义。您可以重复每个功能的过程。

但是,仅在Google中键入函数或在Github上找到该项目并在此处搜索要简单得多。还有 https://code.woboq.org/ ,这使任务变得琐碎。

libc.a和hello binary的无与伦比函数的源代码以及它们加载哪个库?

看起来像 libgcc untind utind 可能在 gcc libstdc ++ 中。

where I can find a source code of cold functions?

In glibc source code.

I cannot find any functions from above marked with cold atribute

That is very odd, simple grep -R is enough, but you might be interested in code indexing - clangd, GLOBAL tags, ctags, etc. You can interest yourself in the_silver_searcher for faster grep.

$ git clone git://git.launchpad.net/ubuntu/+source/glibc
Cloning into 'glibc'...
...
$ cd glibc/
$ grep -R --include '*.c' __assert_fail_base
assert/assert.c:__assert_fail_base (const char *fmt, const char *assertion, const char *file,
assert/assert.c:  __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n%n"),
assert/assert-perr.c:  __assert_fail_base (_("%s%s%s:%u: %s%sUnexpected error: %s.\n%n"),

So __assert_fail_base is defined in assert/assert.c. You can repeat the process for every function.

But it's much simpler to just type the function in google or find the project on github and search there. And there is also https://code.woboq.org/ , which makes the task just trivial.

Where is located source code of unmatched functions from libc.a and hello binary and from which library they loads?

That looks like inside libgcc and the Unwind most probably in gcc libstdc++.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文