调试时没有符号? [英] Debugging without symbols?
问题描述
我有一个简单的.c文件,它应该会失败(我知道它会在哪里失败,我有意将错误放在其中):
I have the simple .c file that is supposed to fail(I know where it fails, I put the bug in there intentionally):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s argument\n", argv[0]);
return EXIT_FAILURE;
}
char *hello = "hello";
*hello = 'H';
fprintf(stdout, "%s, %s!\n", hello, argv[1]);
return EXIT_SUCCESS;
}
第1部分),我将其另存为"hello.c",并在没有调试标志的情况下通过gcc hello.c -o hello
进行编译.
Part 1) I save it as "hello.c" and compile without debugging flags by gcc hello.c -o hello
.
然后,我希望逐行浏览主要功能.我尝试如下使用gdb:
Then, I wish to go line by line through the main function. I try to use gdb as follows:
-
运行
gdb ./hello
通过break main
运行run 123
s
->失败
这是结果:
(gdb) info func
All defined functions:
Non-debugging symbols:
0x0000000000000568 _init
0x0000000000000590 fprintf@plt
0x00000000000005a0 __cxa_finalize@plt
0x00000000000005b0 _start
0x00000000000005e0 deregister_tm_clones
0x0000000000000620 register_tm_clones
0x0000000000000670 __do_global_dtors_aux
0x00000000000006b0 frame_dummy
0x00000000000006ba main
0x0000000000000740 __libc_csu_init
0x00000000000007b0 __libc_csu_fini
0x00000000000007b4 _fini
(gdb) break main
Breakpoint 1 at 0x6be
(gdb) r
Starting program: /mnt/c/Users/User/Documents/Debugging/hello
Breakpoint 1, 0x00000000080006be in main ()
(gdb) s
Single stepping until exit from function main,
which has no line number information.
__fprintf (stream=0x7fffff3ec680 <_IO_2_1_stderr_>, format=0x80007c4 "Usage: %s argument\n") at fprintf.c:27
27 fprintf.c: No such file or directory.
为什么会这样?为什么通过尝试找到文件fprintf却失败了?认为预处理的标头应处理所需的实现代码.
Why does this happen? Why does it fail like this by trying to find a file fprintf? Thought the preprocessed headers should deal with the required implementation code.
第2部分)但是,当我使用-g
进行编译时,由于某些原因,它可以工作.但是在gdb中运行该程序不会产生预期的分段错误:/为什么?
Part 2) When I however compile with the -g
, it works for some reason. But running the program in gdb does not yield a segmentation fault as expected :/ Why?
再次,请参阅:
$ ./hello 123
Segmentation fault (core dumped)
但是
(gdb) run 123
Starting program: /mnt/c/Users/NichlasDesktop/Documents/uni/Compsys/Exercises/Debugging/exercise_code/hello 123
Hello, 123!
[Inferior 1 (process 632) exited normally]
推荐答案
第1部分)
s -> fails
没有调试信息,gdb
无法将指令映射到源代码-文件路径和行号. s
/step
命令告诉gdb
执行与源语言中当前语句相对应的指令. gdb
没有办法知道是什么,所以它一直持续到代码中的任何位置,源位置("SPOS")信息都可用.碰巧在定义了fprintf的libc中.但是,fprintf的源代码在您的环境中不可用,因此会显示该消息.
Without debugging information, gdb
is unable to map instructions to source code - file paths and line numbers. The s
/step
command tells gdb
to execute instructions that correspond to the current statement in the source language. gdb
has no way of telling what that is, so it continues till wherever in code the source position ("SPOS") information is available. That happens to be in libc where fprintf is defined. However the source code for fprintf is not available in your environment, hence that message.
您可以使用si
/stepi
命令逐步执行各个指令,这不需要调试信息.
You could step through the individual instructions using the si
/stepi
command, this does not need debugging information to be present.
您没有显示如果从那时起继续执行会发生什么情况,我怀疑它最终会遇到细分错误.
You did not show what happens if you continue execution from that point, I suspect it would eventually hit the segmentation fault.
为什么会这样?为什么通过尝试找到文件fprintf却失败了?认为预处理的标头应处理所需的实现代码.
Why does this happen? Why does it fail like this by trying to find a file fprintf? Thought the preprocessed headers should deal with the required implementation code.
那不是标题.它们不包含源代码.
That is not what headers are. They don't contain source code.
第2部分)但是,当我使用-g进行编译时,由于某些原因,它可以工作.但是在gdb中运行该程序不会产生预期的分段错误:/为什么?
Part 2) When I however compile with the -g, it works for some reason. But running the program in gdb does not yield a segmentation fault as expected :/ Why?
gdb
或任何其他调试器将安排将可执行文本段映射为私有映射,而不是像通常的运行情况(mmap
和MAP_PRIVATE
而非MAP_SHARED
)共享.这是因为调试器需要文本段可写,以便可以覆盖指令以插入断点等.
gdb
or any other debugger would arrange for the executable text segment to be mapped private instead of shared as in the usual run case (mmap
with MAP_PRIVATE
instead of MAP_SHARED
). This is because the debugger needs the text segment to be writable so that instructions can be overwritten to insert breakpoints etc.
你好"您放入一个常量字符串文字,该文字存储在可执行文件的只读文本段中.这就是为什么在正常运行期间对其进行写入会导致分段错误的原因-文本段被映射为共享.但是,在调试器内部,该文本段被映射为私有,因此您可以对其进行写入.
The "hello" you put in there is a constant string literal that is stored in the read-only text segment of the executable. This is why writing to it causes a segmentation fault during the normal run - the text segment is mapped shared. Inside the debugger however the text segment is mapped private, so you are able to write to it.
这篇关于调试时没有符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!