调试时没有符号? [英] Debugging without symbols?

查看:116
本文介绍了调试时没有符号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的.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:

  1. 运行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或任何其他调试器将安排将可执行文本段映射为私有映射,而不是像通常的运行情况(mmapMAP_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆