简体   繁体   English

没有符号的调试?

[英]Debugging without symbols?

I have the simple.c file that is supposed to fail(I know where it fails, I put the bug in there intentionally):我有应该失败的 simple.c 文件(我知道它失败的地方,我故意将错误放在那里):

#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;
}

Part 1) I save it as "hello.c" and compile without debugging flags by gcc hello.c -o hello .第 1 部分)我将其保存为“hello.c”,并通过gcc hello.c -o hello在不带调试标志的情况下进行编译。

Then, I wish to go line by line through the main function.然后,我希望 go 一行一行地通过主 function。 I try to use gdb as follows:我尝试使用 gdb 如下:

  1. Run gdb./hello运行gdb./hello

  2. Set breakpoint by break main通过break main设置断点

  3. Run run 123运行run 123

  4. s -> fails s -> 失败

Here is the outcome:结果如下:

(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.

Why does this happen?为什么会这样? Why does it fail like this by trying to find a file fprintf?为什么通过尝试查找文件 fprintf 会失败? Thought the preprocessed headers should deal with the required implementation code.认为预处理的标头应该处理所需的实现代码。

Part 2) When I however compile with the -g , it works for some reason.第 2 部分)当我使用-g进行编译时,它出于某种原因工作。 But running the program in gdb does not yield a segmentation fault as expected:/ Why?但是在 gdb 中运行程序不会产生预期的分段错误:/ 为什么?

Again, see:再次,请参阅:

$ ./hello 123
Segmentation fault (core dumped)

but

(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]

Part 1)第1部分)

s -> fails

Without debugging information, gdb is unable to map instructions to source code - file paths and line numbers.在没有调试信息的情况下, gdb无法将 map 指令转为源代码——文件路径和行号。 The s / step command tells gdb to execute instructions that correspond to the current statement in the source language. s / step命令告诉gdb执行与源语言中的当前语句相对应的指令。 gdb has no way of telling what that is, so it continues till wherever in code the source position ("SPOS") information is available. gdb无法告诉它是什么,所以它一直持续到代码中的任何地方,源 position(“SPOS”)信息可用。 That happens to be in libc where fprintf is defined.这恰好在定义 fprintf 的 libc 中。 However the source code for fprintf is not available in your environment, hence that message.但是 fprintf 的源代码在您的环境中不可用,因此该消息。

You could step through the individual instructions using the si / stepi command, this does not need debugging information to be present.您可以使用si / stepi命令逐步执行各个指令,这不需要存在调试信息。

You did not show what happens if you continue execution from that point, I suspect it would eventually hit the segmentation fault.您没有显示如果从该点继续执行会发生什么,我怀疑它最终会遇到分段错误。

Why does this happen?为什么会这样? Why does it fail like this by trying to find a file fprintf?为什么通过尝试查找文件 fprintf 会失败? Thought the preprocessed headers should deal with the required implementation code.认为预处理的标头应该处理所需的实现代码。

That is not what headers are.那不是标题。 They don't contain source code.它们不包含源代码。

Part 2) When I however compile with the -g, it works for some reason.第 2 部分)当我使用 -g 编译时,它出于某种原因工作。 But running the program in gdb does not yield a segmentation fault as expected:/ Why?但是在 gdb 中运行程序不会产生预期的分段错误:/ 为什么?

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 ). gdb或任何其他调试器将安排将可执行文本段映射为私有而不是像通常的运行情况那样共享(使用MAP_PRIVATE而不是MAP_SHAREDmmap )。 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.您输入的“hello”是一个常量字符串文字,存储在可执行文件的只读文本段中。 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.然而,在调试器内部,文本段被映射为私有的,因此您可以对其进行写入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM