【问题标题】:How to know which 'sin' function does my program invoke when running?如何知道我的程序在运行时调用了哪个“sin”函数?
【发布时间】:2015-06-24 13:45:56
【问题描述】:

我正在使用不同版本的 libm.a。我正在使用的一个是 fdlibm 的 libm.a(来自 Sun)。

问题是我感觉我的程序没有调用fdlibm的libm.a中的函数,而是调用了系统glibc的libm.a中的函数。

#include "fdlibm.h"
int main(){
  double x = sin(3);
}

程序是编译的C++程序(因为它必须与其他c++程序链接):

g++ prog.cpp libm.a

其中 libm.a 是 fdlibm 的。 (来自孙,http://www.netlib.org/fdlibm/readme

问题 1

我怎么知道sin 在运行时实际调用了什么?我听说过各种工具,例如 objdump、gdb... 哪一种可以用于我的案例以及如何使用?

问题 2

如何强制使用 fdlibm 的 libm.a?

谢谢。

【问题讨论】:

  • 你在问当你调用未定义的行为时会发生什么。重新定义标准库函数(例如,sin)是未定义的行为。
  • @David 感谢您的帮助。顺便说一句,你的意思是什么?
  • @David Hammen,您能否提供参考证明您对 UB 的陈述?
  • 作为OP问题的后续,为什么在这种情况下编译器不会警告多个函数定义?
  • @Carlton - 这不是错误。 sin 是一个 libc 函数,您可以提供自己的函数。这就是为什么命令行中库的顺序很重要的原因

标签: c++ static-linking


【解决方案1】:

问题1.听说过objdump、gdb等各种工具。

与 gdb 一样。 创建文件 trace_sin.gdb

$ cat trace_sin.gdb
set confirm off
b sin
commands
bt
c
end
r
quit

然后运行你的程序:

$ gdb -q -x trace_sin.gdb   ./a.out Reading symbols from ./a.out...(no
debugging symbols found)...done. Breakpoint 1 at 0x400498

Breakpoint 1, 0x000000314941c760 in sin () from /lib64/libm.so.6
#0  0x000000314941c760 in sin () from /lib64/libm.so.6
#1  0x0000000000400629 in main ()

正如你在我的例子中看到的 sin 来自 libm

问题 2. 如何强制使用 fdlibm 的 libm.a?

只需确保来自 fdlibm 的 sin 位于 libm 的 sin 之前

【讨论】:

  • 确实很有帮助。谢谢。
【解决方案2】:

我厌倦了链接/延迟加载 .so 版本的库,在某处我发现您可以通过指定库的路径来实现到特定库的链接。

也许这可以帮助您应对挑战。

示例 - 我可以更改此命令(并链接到 SDL2 .so)

$(CC) $(CC_FLAGS)  $<  -o $@  -L../../bag  -lbag_i686 -lSDL2

并达到同样的效果

$(CC) $(CC_FLAGS)  $<  -o $@  -L../../bag  -lbag_i686 /usr/local/lib/libSDL2.so

明确标识要使用的库。


在 ubuntu 上,我可以使用“定位”来查找文件的完整路径。事实证明,SDL2 (.so) 位于 /usr/local/lib 和 /usr/lib/x86_64-linux-gnu 中。我想 x86_64 更适合我的系统,它也链接。

【讨论】:

    【解决方案3】:

    我使用了以下简单的技术来“温和地指定”(非显式)链接所需的库。这种技术可能适合您。

    我已经创建了几个我必须使用的库,它们都在一个特定的路径中:“/home//cvs-tools/lib1”。 )

    当需要使用我需要的 1 个 boost 库时,我只是将最新的 libboost_chrono.a 复制到“/home//cvs-tools/lib1”中。没有.so妨碍。

    并触摸了我的 make 文件,因此当我更新 boost 时,而不是试图记住所有含义,我只是将 chrono.a 的副本添加到我的 make 文件到我的 lib1 中,然后我的正常构建然后更新了 lib1 的副本。

    所以,“稍微具体”是指 a) 我的 make 文件将 b) 特定的 COTS 库(boost)复制到 c) 我的 lib1 目录中,因此被同一个 -L 拾取。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-21
      • 2016-01-20
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 2018-07-23
      相关资源
      最近更新 更多