使用 godbolt 进入标准库调用

2024-01-15

我想知道各个编译器是如何实现的std::random_device,所以我把它放进去godbolt https://godbolt.org/z/24H4SZ.

不幸的是,它唯一说的是

std::random_device::operator()():
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        mov     rdi, rax
        call    std::random_device::_M_getval()
        leave
        ret

这不是很有帮助。我怎样才能步入_M_getval()打电话并检查那里的集会吗?


你不能“单步进入”函数; Godbolt 不是调试器,它是反汇编器(在“二进制”模式下,否则是编译器 asm-text 输出过滤器/查看器)。你的程序没有run,它就被编译了。 (除非您选择“二进制”输出选项,否则它仅编译为 asm,而不是机器代码,并且实际上并不链接。)

但无论术语如何,您都无法让 Godbolt 向您展示它碰巧安装的任何版本的库的反汇编。

单步执行桌面上的程序。(编译为gcc -O3 -fno-plt以避免必须逐步执行 PLT 惰性动态链接。)

(我这样做了,Arch Linux 上的 libstdc++ 6.2.1 运行cpuid在构造函数中std::random_device. If rdrand可用,它在调用时使用它_M_getval()。仅通过反汇编来弄清楚这一点是很棘手的。有多个级别的函数调用和分支,如果没有符号,就很难弄清楚什么是什么。我的 Skylake 有rdseed可用,但没有使用它。是的,正如您所评论的,那将是一个更好的选择。)


不同的编译器可以从同一源生成不同版本的库函数,这就是编译器资源管理器存在的要点。不,它没有由下拉列表中的每个编译器编译的单独版本的 libstdc++。

无法保证您看到的库代码与您桌面上的代码或其他任何内容相匹配。

不过,它实际上确实安装了 x86-64 Linux 库,因此理论上 Godbolt 可以为您提供查找和反汇编某些库函数的选项,但该功能目前还不存在。并且仅适用于“二进制”选项可用的目标;我认为对于大多数交叉编译目标来说,它只有标头而不是库。或者可能还有其他原因导致它无法针对非 x86 ISA 进行链接和反汇编。


Using -static二进制模式显示了一些东西,但不是我们想要的。

I tried https://godbolt.org/z/Ya3wez编译用-static -fno-plt -fno-exceptions -fno-rtti -nostartfiles -O3 -march=skylake(因此 rdrand 和 rdseed 可以使用,以防它们被内联;但它们没有)。-fno-plt是多余的-static,但是很有用without消除那些混乱。

-static导致库代码实际上最终出现在 Godbolt 反汇编的链接二进制文件中. 但输出限制为500行,并且定义std::random_device::_M_getval()碰巧不在文件开头附近。

-nostartfiles避免使二进制文件混乱_startCRT 启动文件等。不过,我认为 Godbolt 已经将这些从反汇编中过滤掉了,因为你在正常的二进制输出中看不到它们(没有-static)。您不会运行该程序,因此链接器找不到_start符号,并且默认将 ELF 入口点放在开头.text部分。

尽管编译时使用-fno-exceptions -fno-rtti(因此不包含函数的展开处理程序),libstdc++ 函数是在启用异常处理的情况下编译的。因此,链接它们会带来大量异常代码。静态可执行文件从函数的定义开始,例如std::__throw_bad_exception(): and std::__throw_bad_alloc():

顺便说一句,没有-fno-exceptions,还有一个get_random_seed() [clone .cold]:定义,我认为这是一个展开处理程序。它是not您的实际功能的定义。静态二进制文件的开头附近是operator new(unsigned long) [clone .cold]:我再次认为这是 libstdc++ 的异常处理程序代码。

我觉得.text.cold or .init不幸的是,各个部分首先被链接,因此在前 500 行中不会显示任何有趣的函数。


即使这有效,它也只是二进制模式反汇编,而不是编译器 asm

即使使用调试符号,我们也不知道正在访问哪个结构成员,只知道寄存器的数字偏移量,因为 objdump 不会填充这些偏移量。

由于有很多分支,很难遵循复杂的逻辑可能性。运行时单步执行会自动遵循actual执行路径。


Related:

  • 如何从 GCC/clang 汇编输出中消除“噪音”? https://stackoverflow.com/questions/38552116/how-to-remove-noise-from-gcc-clang-assembly-output关于使用 Matt Godbolt Compiler Explorer 来做它有用的事情。

  • Matt Godbolt CppCon 2017 演讲“我的编译器最近为我做了什么?打开编译器的盖子 https://youtu.be/bSkpMdDe4g4” 是一个很好的指南,并指出您可以克隆编译器资源管理器存储库并使用您自己选择的编译器在本地进行设置。你甚至可以破解它以允许更大的输出,但这对于this问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 godbolt 进入标准库调用 的相关文章

  • 推导指南中的引用和值之间的差异

    考虑类型A template
  • 将内置类型转换为向量

    我的 TcpClient 类接受vector
  • 在 Unity 进程和另一个 C# 进程之间进行本地 IPC 的最快方法 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我希望每秒大约 30 次从 C 应用程序向我的 Unity 应用程序传送大量数据 由于 Unity 不支持映射内存和管道 我考虑了 t
  • 如何从 .resx 文件条目获取注释

    资源文件中的字符串有名称 值和注释 The ResXResourceReader类让我可以访问名称和值 有办法看评论吗 你应该能够得到Comment via ResXDataNode class http msdn microsoft co
  • 将 System.Windows.Input.KeyEventArgs 键转换为 char

    我需要将事件参数作为char 但是当我尝试转换 Key 枚举时 我得到的字母和符号与传入的字母和符号完全不同 如何正确地将密钥转换为字符 这是我尝试过的 ObserveKeyStroke this new ObervableKeyStrok
  • 存储来自其他程序的事件

    我想将其他应用程序的事件存储在我自己的应用程序中 事件示例 打开 最小化 Word 或打开文件时 这样的事可能吗 运行程序 http msdn microsoft com en us library ms813609 aspx and 打开
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何将自定义 JSON 文件添加到 IConfiguration 中?

    我正在使用 asp net Autofac 我正在尝试加载自定义 JSON 配置文件 并基于该文件创建 实例化 IConfiguration 实例 或者至少将我的文件包含到默认情况下构建的 IConfiguration asp net 中
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • .NET中的LinkedList是循环链表吗?

    我需要一个循环链表 所以我想知道是否LinkedList是循环链表吗 每当您想要移动列表中的 下一个 块时 以循环方式使用它的快速解决方案 current current Next current List First 电流在哪里Linke
  • (de)从 CSV 序列化为对象(或者最好是类型对象的列表)

    我是一名 C 程序员 试图学习 C 似乎有一些内置的对象序列化 但我在这里有点不知所措 我被要求将测试数据从 CSV 文件加载到对象集合中 CSV 比 xml 更受青睐 因为它更简单且更易于人类阅读 我们正在创建测试数据来运行单元测试 该集
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 使用 GROUP 和 SUM 的 LINQ 查询

    请帮助我了解如何使用带有 GROUP 和 SUM 的 LINQ 进行查询 Query the database IEnumerable
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub

随机推荐