【问题标题】:gdb not giving the complete description of the errorgdb 没有给出错误的完整描述
【发布时间】:2014-03-04 11:04:49
【问题描述】:

我刚刚转移到 ubuntu 并新使用 gdb 和 g++ 。如果我的问题很愚蠢,请原谅我。

这是来自 Richard Stevens Advanced Linux Programming 。在文件夹名称互惠中创建了三个文件 main.c:

#include <stdio.h>
#include "reciprocal.hpp"
int main (int argc, char **argv)
{
  int i;
  i = atoi (argv[1]);
  printf ("The reciprocal of %d is %g\n", i, reciprocal (i));
  return 0;
}

reciprocal.cpp:

#include <cassert>
#include "reciprocal.hpp"
double reciprocal (int i) {
  // I should be non-zero.
  assert (i != 0);
  return 1.0/i;
}

reciprocal.hpp:

#ifdef __cplusplus
extern "C" {
#endif
extern double reciprocal (int i);

#ifdef __cplusplus
}
#endif

编译后,我运行了命令(gdb) reciprocal(gdb) run。我期待着书中的东西

Starting program: reciprocal
Program received signal SIGSEGV, Segmentation fault.
__strtol_internal (nptr=0x0, endptr=0x0, base=10, group=0)
at strtol.c:287
287 strtol.c: No such file or directory.
(gdb)

但我得到了:

Starting program: /home/trafalgar/Desktop/reciprocal/reciprocal
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000

Program received signal SIGSEGV , Segmentation fault.
0x00007ffff7a56ad4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6

可能会发生什么不同。这是版本问题还是其他问题?

这是 Makefile

reciprocal: main.o reciprocal.o
           g++ $(CFLAGS) -o reciprocal main.o reciprocal.o
main.o: main.c reciprocal.hpp
           gcc $(CFLAGS) -c main.c
reciprocal.o: reciprocal.cpp reciprocal.hpp
           g++ $(CFLAGS) -c reciprocal.cpp
clean:
      rm -f *.o reciprocal

【问题讨论】:

  • 我认为设置详细程度会有所帮助,但它仍然提供与以前相同的输出
  • 调试器正在工作(在带有调试信息的二进制文件上)。您的代码不起作用。
  • 使用rm -v *.o recpirocal 进行清理。重新编译所有源代码。向我们展示您的编译命令。再次启动调试器。

标签: linux gdb g++


【解决方案1】:

你是如何编译程序的? use g++ -g programname.c

另外,当你这样做时 gdb reciprocal

注意是否有类似的消息 loaded symbols from ... 或者 couldnot find symbols

如果你得到类似于第二条代码语句的输出,那么问题是你没有使用 -g 符号。

【讨论】:

  • 我使用了 -g 符号,但仍然是一样的,任何其他建议
  • 能否请您在从执行程序的位置开始编写 gdb 倒数时粘贴确切的输出?
  • 符号未生成,因此未加载。我们将需要您的编译声明。
  • 我用了一个 Makefile ,然后make CFLAGS=-g
  • 请看一下make文件
【解决方案2】:

您应该使用所有警告和调试信息进行编译,即

 gcc -Wall -g -c main.c
 g++ -Wall -g -c reciprocal.cpp

然后链接

 g++ -g main.o reciprocal.o -o reciprocal

所以添加

CFLAGS= -Wall -g

在您的Makefile 中。另见this

然后运行调试器

 gdb reciprocal

然后使用set args 12 命令将程序参数设置为(gdb) 提示符 最后在出现(gdb) 提示时使用run 启动调试程序

当然,如果你没有任何程序参数,argc 是 1,argv[1]NULL,你不应该将它们传递给 atoi(3)

调试器运行良好。 错误在您的代码中。您应该正确处理argc 为1 且argv[1]NULL 的情况。

如果您在 C 库函数中遇到 segmentation fault,请使用 btbacktrace gdb 命令了解您是如何到达那里的。

【讨论】:

    【解决方案3】:

    一切正常,有预期的输出。

    比较:

    1. Starting program: reciprocal
    2. Program received signal SIGSEGV, Segmentation fault.
    3. __strtol_internal (nptr=0x0, endptr=0x0, base=10, group=0)
    4. at strtol.c:287
    5. 287 strtol.c: No such file or directory.
    
    A. Starting program: /home/trafalgar/Desktop/reciprocal/reciprocal
    B. warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
    C. Program received signal SIGSEGV , Segmentation fault.
    D. 0x00007ffff7a56ad4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
    

    第 1-5 行是您的预期输出(来自 Stevens 先生的文字),第 A-D 行是您的实际输出。

    第 1 行和 A 行本质上是相同的,它们都指定了可执行文件的文件名,(1) 是相对路径,(A) 具有完整路径。不用担心。

    B 行...这是正常的,这是 gdb 告诉您没有为您的库函数(不是您的代码,系统上的动态链接库)安装调试信息。

    C 行...同(2),很简单。

    D行...好吧,由于我们没有库函数的调试信息,它只能尽可能指出错误的位置:libc.so.6(标准库函数,其中strtol就是这样)

    本质上,D 行与 3-5 行类似。如果没有安装/可用的调试信息,您将不会获得比这更多的信息。

    但一切都按预期工作。你很好。

    有关如何安装调试符号的帮助,请参阅此处:how-to-use-debug-libraries-on-ubuntu

    不要害怕!你做得很好。 (从技术上讲,错误出现在 main.cpp 的第 6 行,因为 argv[1] 几乎没有定义,因为您没有提供参数,这可能会令人困惑,因为 atoi() 通常在幕后被 strtol() 替换。 )

    试试:

    gdb --args ./reciprocal 15
    

    或类似于带参数的测试。

    【讨论】:

      猜你喜欢
      • 2021-01-30
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 1970-01-01
      相关资源
      最近更新 更多