Per Employed Russian's answer, I rebuilt using -fno-builtin via:#!/bin/bashexec 2>&1set -xcxx_args='-fno-builtin'rm -rf "/tmp/testdir"mkdir -p "/tmp/testdir"cd "/tmp/testdir"cat > main.cpp <<'EOF'#include <stdio.h>#include <math.h> // double floor(double x);int main(int argc, char *argv[], char *const envp[]){ printf("From inside C++: floor(2.12) %g\n", floor(2.12)); return 0;} // end mainEOF/usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type $cxx_args main.cpp -c -o main.o/usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type $cxx_args main.o -L. -L/usr/lib64 -lstdc++ -o main.exe(./main.exe; exit 0)cat > /tmp/gdb.commands <<EOF# https://stackoverflow.com/a/60909020/257924set trace-commands onb mainrinfo sharedp floor(2.12)EOFgdb -batch -x /tmp/gdb.commands main.exeexit 0是:+ cxx_args=-fno-builtin+ rm -rf /tmp/testdir+ mkdir -p /tmp/testdir+ cd /tmp/testdir+ cat+ /usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type -fno-builtin main.cpp -c -o main.o+ /usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type -fno-builtin main.o -L. -L/usr/lib64 -lstdc++ -o main.exe+ ./main.exeFrom inside C++: floor(2.12) 2+ exit 0+ cat+ gdb -batch -x /tmp/gdb.commands main.exe+b mainBreakpoint 1 at 0x1169: file main.cpp, line 5.+rBreakpoint 1, main (argc=0, argv=0x7fffffffdbc0, envp=0x555555555080 <_start>) at main.cpp:55 {+info sharedFrom To Syms Read Shared Object Library0x00007ffff7fd1100 0x00007ffff7ff23f4 Yes /lib64/ld-linux-x86-64.so.20x00007ffff7e553c0 0x00007ffff7efbe78 Yes /lib/x86_64-linux-gnu/libm.so.60x00007ffff7c7a670 0x00007ffff7def74f Yes /lib/x86_64-linux-gnu/libc.so.6+p floor(2.12)$1 = 2+ exit 0推荐答案我复制了此内容.问题有两个:I reproduced this. The problem is two-fold:编译器可以评估 floor(2.12),而无需调用 libm.so.6 和编译器配置为将-按需参数传递给链接器.The compiler can evaluate floor(2.12) without calling into libm.so.6, andThe compiler is configured to pass --as-needed argument to the linker.问题1)导致不需要 libm.so.6 . main 的反汇编显示:The issue 1) results in libm.so.6 not being needed. Disassembly of main shows:=> 0x0000555555555148 <+19>: mov 0xee1(%rip),%rax # 0x555555556030 0x000055555555514f <+26>: movq %rax,%xmm0 0x0000555555555154 <+31>: lea 0xead(%rip),%rdi # 0x555555556008 0x000055555555515b <+38>: mov $0x1,%eax 0x0000555555555160 <+43>: callq 0x555555555030 <printf@plt>(gdb) p *(double*)0x555555556030$1 = 2并且 info shared 显示GDB没有加载 libm.so.6 (因为它不是必需的),因此从未加载过它的调试信息.要么.And info shared shows that GDB didn't load libm.so.6 (as it isn't needed), so the debug info for it was never loaded either.稍微改变一下来源:1 #include <stdio.h>2 #include <math.h> // double floor(double x);34 int main(int argc, char *argv[], char *const envp[])5 {6 double d = 2.12;7 printf("From inside C++: floor(2.12) %g\n", floor(d));8 return 0;9 } // end main结果:(gdb) startTemporary breakpoint 1 at 0x1158: file main.cpp, line 6.Starting program: /tmp/testdir/a.outTemporary breakpoint 1, main (argc=1, argv=0x7fffffffdca8, envp=0x7fffffffdcb8) at main.cpp:66 double d = 2.12;(gdb) n7 printf("From inside C++: floor(2.12) %g\n", floor(d));(gdb) p floor$1 = {<text gnu-indirect-function variable, no debug info>} 0x7ffff7e8e820 <__floor_ifunc>(gdb) p floor(d)$2 = 2 P.S.除了修改源代码,您还可以禁止编译器使用 -fno-builtin 或 -fno-builtin-floor 来了解 floor 是什么.P.S. Instead of modifying source, you could also prohibit the compiler from knowing what floor is with -fno-builtin or -fno-builtin-floor. 这篇关于如何使gdb允许我将"floor"称为"floor"即使安装了调试信息文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 1403页,肝出来的..
09-07 03:13