即使安装了调试信息文件,如何让 gdb 允许我调用 "floor"?
How to make gdb allow me to call "floor" even when debug info files are installed?
作为对 的回应,我确认我确实有调试包,这些包应该提供足以从 gdb 命令行调用 floor
等函数的调试信息,但有些东西仍然表现得很奇怪在 gdb 中。
我是 运行 这个版本的 gdb 来自:
gdb --version
是:
GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Linux 机器操作系统信息来自:
lsb_release -r -i
是:
Distributor ID: Ubuntu
Release: 19.10
我希望 gdb 使用的调试包,以便通过以下方式找到 floor
符号:
dpkg --listfiles libc6-dbg | grep libm
是:
/usr/lib/debug/lib/x86_64-linux-gnu/libm-2.30.so
/usr/lib/debug/lib/x86_64-linux-gnu/libmemusage.so
/usr/lib/debug/lib/x86_64-linux-gnu/libmvec-2.30.so
编译,运行,然后 运行 gdb via:
#!/bin/bash
exec 2>&1
set -x
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 main
EOF
/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
#
set trace-commands on
b main
r
info shared
p floor(2.12)
EOF
gdb -batch -x /tmp/gdb.commands main.exe
exit 0
是:
+ 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 main.cpp -c -o main.o
+ /usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type main.o -L. -L/usr/lib64 -lstdc++ -o main.exe
+ ./main.exe
From inside C++: floor(2.12) 2
+ exit 0
+ cat
+ gdb -batch -x /tmp/gdb.commands main.exe
+b main
Breakpoint 1 at 0x1149: file main.cpp, line 5.
+r
Breakpoint 1, main (argc=0, argv=0x7fffffffdbc0, envp=0x555555555060 <_start>) at main.cpp:5
5 {
+info shared
From To Syms Read Shared Object Library
0x00007ffff7fd1100 0x00007ffff7ff23f4 Yes /lib64/ld-linux-x86-64.so.2
0x00007ffff7dc9670 0x00007ffff7f3e74f Yes /lib/x86_64-linux-gnu/libc.so.6
+p floor(2.12)
/tmp/gdb.commands:6: Error in sourced command file:
No symbol "floor" in current context.
+ exit 0
即使我确实安装了如上所示的调试信息,为什么 gdb 无法允许我调用程序本身能够调用的函数?
我该如何解决?
更新 1
根据 中 Employed Russian 的帮助,我在 gdb 命令中使用了 set trace-command on
。
更新 2
根据 ,插入 info shared
到 gdb 命令中。
更新 3
根据 ,我使用 -fno-builtin
通过以下方式重建:
#!/bin/bash
exec 2>&1
set -x
cxx_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 main
EOF
/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
#
set trace-commands on
b main
r
info shared
p floor(2.12)
EOF
gdb -batch -x /tmp/gdb.commands main.exe
exit 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.exe
From inside C++: floor(2.12) 2
+ exit 0
+ cat
+ gdb -batch -x /tmp/gdb.commands main.exe
+b main
Breakpoint 1 at 0x1169: file main.cpp, line 5.
+r
Breakpoint 1, main (argc=0, argv=0x7fffffffdbc0, envp=0x555555555080 <_start>) at main.cpp:5
5 {
+info shared
From To Syms Read Shared Object Library
0x00007ffff7fd1100 0x00007ffff7ff23f4 Yes /lib64/ld-linux-x86-64.so.2
0x00007ffff7e553c0 0x00007ffff7efbe78 Yes /lib/x86_64-linux-gnu/libm.so.6
0x00007ffff7c7a670 0x00007ffff7def74f Yes /lib/x86_64-linux-gnu/libc.so.6
+p floor(2.12)
= 2
+ exit 0
我转载了这个。问题有两个:
- 编译器可以在不调用
libm.so.6
和 的情况下评估 floor(2.12)
- 编译器配置为将
--as-needed
参数传递给链接器。
问题 1) 导致 libm.so.6
不需要。 main
的反汇编显示:
=> 0x0000555555555148 <+19>: mov 0xee1(%rip),%rax # 0x555555556030
0x000055555555514f <+26>: movq %rax,%xmm0
0x0000555555555154 <+31>: lea 0xead(%rip),%rdi # 0x555555556008
0x000055555555515b <+38>: mov [=10=]x1,%eax
0x0000555555555160 <+43>: callq 0x555555555030 <printf@plt>
(gdb) p *(double*)0x555555556030
= 2
并且 info shared
显示 GDB 没有加载 libm.so.6
(因为它不需要),所以它的调试信息也从未加载。
稍微更改一下来源:
1 #include <stdio.h>
2 #include <math.h> // double floor(double x);
3
4 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) start
Temporary breakpoint 1 at 0x1158: file main.cpp, line 6.
Starting program: /tmp/testdir/a.out
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdca8, envp=0x7fffffffdcb8) at main.cpp:6
6 double d = 2.12;
(gdb) n
7 printf("From inside C++: floor(2.12) %g\n", floor(d));
(gdb) p floor
= {<text gnu-indirect-function variable, no debug info>} 0x7ffff7e8e820 <__floor_ifunc>
(gdb) p floor(d)
= 2
P.S。除了修改源代码,您还可以禁止编译器知道 floor
与 -fno-builtin
或 -fno-builtin-floor
.
的含义
作为对 floor
等函数的调试信息,但有些东西仍然表现得很奇怪在 gdb 中。
我是 运行 这个版本的 gdb 来自:
gdb --version
是:
GNU gdb (Ubuntu 8.3-0ubuntu1) 8.3
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Linux 机器操作系统信息来自:
lsb_release -r -i
是:
Distributor ID: Ubuntu
Release: 19.10
我希望 gdb 使用的调试包,以便通过以下方式找到 floor
符号:
dpkg --listfiles libc6-dbg | grep libm
是:
/usr/lib/debug/lib/x86_64-linux-gnu/libm-2.30.so
/usr/lib/debug/lib/x86_64-linux-gnu/libmemusage.so
/usr/lib/debug/lib/x86_64-linux-gnu/libmvec-2.30.so
编译,运行,然后 运行 gdb via:
#!/bin/bash
exec 2>&1
set -x
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 main
EOF
/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
#
set trace-commands on
b main
r
info shared
p floor(2.12)
EOF
gdb -batch -x /tmp/gdb.commands main.exe
exit 0
是:
+ 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 main.cpp -c -o main.o
+ /usr/bin/c++ -MD -DDEBUG -g -fPIC -Wall -Werror -Wsynth -Wno-comment -Wreturn-type main.o -L. -L/usr/lib64 -lstdc++ -o main.exe
+ ./main.exe
From inside C++: floor(2.12) 2
+ exit 0
+ cat
+ gdb -batch -x /tmp/gdb.commands main.exe
+b main
Breakpoint 1 at 0x1149: file main.cpp, line 5.
+r
Breakpoint 1, main (argc=0, argv=0x7fffffffdbc0, envp=0x555555555060 <_start>) at main.cpp:5
5 {
+info shared
From To Syms Read Shared Object Library
0x00007ffff7fd1100 0x00007ffff7ff23f4 Yes /lib64/ld-linux-x86-64.so.2
0x00007ffff7dc9670 0x00007ffff7f3e74f Yes /lib/x86_64-linux-gnu/libc.so.6
+p floor(2.12)
/tmp/gdb.commands:6: Error in sourced command file:
No symbol "floor" in current context.
+ exit 0
即使我确实安装了如上所示的调试信息,为什么 gdb 无法允许我调用程序本身能够调用的函数?
我该如何解决?
更新 1
根据 set trace-command on
。
更新 2
根据 info shared
到 gdb 命令中。
更新 3
根据 -fno-builtin
通过以下方式重建:
#!/bin/bash
exec 2>&1
set -x
cxx_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 main
EOF
/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
#
set trace-commands on
b main
r
info shared
p floor(2.12)
EOF
gdb -batch -x /tmp/gdb.commands main.exe
exit 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.exe
From inside C++: floor(2.12) 2
+ exit 0
+ cat
+ gdb -batch -x /tmp/gdb.commands main.exe
+b main
Breakpoint 1 at 0x1169: file main.cpp, line 5.
+r
Breakpoint 1, main (argc=0, argv=0x7fffffffdbc0, envp=0x555555555080 <_start>) at main.cpp:5
5 {
+info shared
From To Syms Read Shared Object Library
0x00007ffff7fd1100 0x00007ffff7ff23f4 Yes /lib64/ld-linux-x86-64.so.2
0x00007ffff7e553c0 0x00007ffff7efbe78 Yes /lib/x86_64-linux-gnu/libm.so.6
0x00007ffff7c7a670 0x00007ffff7def74f Yes /lib/x86_64-linux-gnu/libc.so.6
+p floor(2.12)
= 2
+ exit 0
我转载了这个。问题有两个:
- 编译器可以在不调用
libm.so.6
和 的情况下评估 - 编译器配置为将
--as-needed
参数传递给链接器。
floor(2.12)
问题 1) 导致 libm.so.6
不需要。 main
的反汇编显示:
=> 0x0000555555555148 <+19>: mov 0xee1(%rip),%rax # 0x555555556030
0x000055555555514f <+26>: movq %rax,%xmm0
0x0000555555555154 <+31>: lea 0xead(%rip),%rdi # 0x555555556008
0x000055555555515b <+38>: mov [=10=]x1,%eax
0x0000555555555160 <+43>: callq 0x555555555030 <printf@plt>
(gdb) p *(double*)0x555555556030
= 2
并且 info shared
显示 GDB 没有加载 libm.so.6
(因为它不需要),所以它的调试信息也从未加载。
稍微更改一下来源:
1 #include <stdio.h>
2 #include <math.h> // double floor(double x);
3
4 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) start
Temporary breakpoint 1 at 0x1158: file main.cpp, line 6.
Starting program: /tmp/testdir/a.out
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdca8, envp=0x7fffffffdcb8) at main.cpp:6
6 double d = 2.12;
(gdb) n
7 printf("From inside C++: floor(2.12) %g\n", floor(d));
(gdb) p floor
= {<text gnu-indirect-function variable, no debug info>} 0x7ffff7e8e820 <__floor_ifunc>
(gdb) p floor(d)
= 2
P.S。除了修改源代码,您还可以禁止编译器知道 floor
与 -fno-builtin
或 -fno-builtin-floor
.