所以我是Linux新手,刚刚在VM上运行Ubuntu 16.04.2。我已经在终端上安装了gcc / g ++,但是当我在GDB中运行我的程序时,只要我进入strcmp函数,就会弹出很多行。
strcmp_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:24
24 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S: No such file or directory.
当我走得更远的时候:
strlen () at ../sysdeps/x86_64/strlen.S:66
66 ../sysdeps/x86_64/strlen.S: No such file or directory.
所以我猜它只是不识别我的C库.. 我意识到我可以在几次尝试之后逐步完成这个过程,但是我的所有c函数都出现了,当我在学校服务器上使用GDB时,我不会遇到这个问题。任何帮助将不胜感激。
答案 0 :(得分:1)
我进入strcmp函数,弹出很多行。
执行s
(单步)或si
(步骤单指令)时,您看到的字符串和内存函数如strcmp
,memcpy
,{{ 1}},memcmp
等是正确的,GDB确实识别你的C库(从VM中的iso启动的Ubuntu 16.04.2 amd64已经为你的libc-C库预安装了libc6-dbg调试包。) / p>
strlen
我们在这里看到的是,GDB能够找到strcmp和strlen函数的调试信息来获取行号,但标准C库的这些函数不是C函数!它们是汇编程序函数(一个用SSE2优化),我们可以从它们的源引用的strcmp_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:24
24 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S: No such file or directory.
strlen () at ../sysdeps/x86_64/strlen.S:66
66 ../sysdeps/x86_64/strlen.S: No such file or directory.
后缀中看到它。输入后,您可以尝试执行多个.S
或s
,以查看递增的源文件行。
它只是不识别
GDB完成了它可以做的所有事情:它找到了系统C库的调试信息(这不是最容易的,因为调试信息被分隔到si
中某个地方的其他文件与其他名称),并找到哪个指令来从哪一行来源。它不能做的是打开源文件,因为它不是预安装的ubuntu映像的一部分,不是任何ubuntu(debian)二进制包的一部分。
如果你想查看这个系统库函数,你能做什么:
1)使用GDB命令/usr/lib/debug/lib/x86_64-linux-gnu/
检查功能的反汇编(默认情况下,它将打印当前功能)。它将非常接近这个函数实现的源代码,因为它最初是用汇编语言编写的,你输的是宏的注释和结构:
转换函数strlen的汇编代码:
disassemble
2)或者您可以通过&#34;显示&#34;执行指令。像 0x000address70 <+0>: pxor %xmm0, %xmm0
=> 0x000address74 <+0>: pxor %xmm1, %xmm1
0x000address78 <+0>: pxor %xmm2, %xmm2
0x000address7c <+0>: pxor %xmm3, %xmm3
...
或display/i $pc
这样的命令(在当前PC上打印一条指令,只是EIP或RIP的名称;或打印两条指令:当前和下一条)
3)或者您可以创建gdb所需的路径并将原始源复制到它:disp/2i $pc
并将此版本的库保存到此目录汇编程序源。 strlen.S有glibc-2.23版本(作者GIT的github镜像):https://github.com/bminor/glibc/blob/glibc-2.23/sysdeps/x86_64/strlen.S#L66
4)或者您可以使用mkdir -p ../sysdeps/x86_64/
下载带有apt source libc
的libc的ubuntu源代码(在~/src
之后的mkdir ~/src
之类的某个稳定路径中)并将gdb指向此目录(添加一些实际的子目录会计到使用../
)
directory ~/src/glibc-2.23/sysdeps
相对部分
这适用于我所有的c函数
不,对于你的c函数,你有其他类型的输出(不是... something.S: No such file or directory
)。您应该在构建程序时通过向-g
(或其他编译器)添加gcc
参数来启用调试符号。