【问题标题】:Is there a way to check where did the segmentation fault happened using gdb?有没有办法使用 gdb 检查分段错误发生在哪里?
【发布时间】:2020-04-28 15:50:38
【问题描述】:

当我运行我的对象测试文件时,我遇到了分段错误,所以我使用 gdb 来查找错误在哪里。但是,当我执行 gdb(我的目标文件)时,我使用 next 逐步浏览了该文件,但其中没有任何错误。我有点困惑,有没有一种好方法可以找到分段错误发生在哪里?先感谢您。

这是我在 gdb 中所做的:

(gdb) n
44        if (argc > 1) {
(gdb) n
45          tctest_testname_to_execute = argv[1];
(gdb) n
48        TEST(testGetWidth);
(gdb) n
49        TEST(testGetHeight);
(gdb) n
50        TEST(testGetTile);
(gdb) n
52        TEST_FINI();
(gdb) n
All tests passed!

这是我在运行目标文件时遇到的错误:

segmentation fault
segmentation fault
segmentation fault
3 test(s) failed

(编辑) 嗨,抱歉更新晚了,我尝试调试它,但我仍然没有运气。我正在尝试创建一个迷宫类,它可以读取具有迷宫描述的输入流并返回迷宫。但是,当我使用这个给定的输入流运行测试时:

20 10
####################
#................<.#
#..................#
#...###............#
#.....#............#
#.....#............#
#...###............#
#..................#
#..................#
####################

它给出了一个分段错误,我在 valgrind 上运行目标文件来检查发生了什么:

Invalid write of size 8
==2482545==    at 0x4032CD: Maze::setTile(Position const&, Tile*) (maze.cpp:47)
==2482545==    by 0x40347B: Maze::read(std::istream&) (maze.cpp:67)
.....
==2482545==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

我真的不明白为什么会出现分段错误或无效写入,在我的代码中,我应该在 setTile 函数中为每个图块分配空间,所以应该有空间供我编写。我还将 tile_collection 与我的构造函数堆叠在一起,因此当我调用 Maze(20,10) 时应该初始化 tile_collection,并且 setTile 内部的调整大小应该可以正常工作。你能指出我错过了什么吗?先感谢您。 这是我的头文件,不包括函数声明:

class Maze {
private:
  // TODO: add fields
  int Width;
  int Height;
  std::vector<Tile*> tile_collection;

这是我的 cpp 文件:

Maze::Maze(int width,int height):
  Width(width),Height(height){
  tile_collection[(height)*(width-1)];
}


void Maze::setTile(const Position &pos,Tile *tile){
  tile_collection.resize(pos.getX()+pos.getY()*Width);
  tile_collection[pos.getX()+pos.getY()*(Width)]=tile;
}


Maze *Maze::read(std::istream &in){
  int x;int y;char c;
  if ((in>>x)&&(in>>y)){
      Maze *new_maze=new Maze(x,y);
      //loop over the specified maze dimension
        for (int i=0;i<y;i++){
          for (int j=0;j<x;j++){
            if (in>>c){
              //using tilefactory to change character into a tile
              TileFactory *fac=fac->getInstance();
              Tile* temp=fac->createFromChar(c);
              //if createFromChar fails, return nullptr, otherwise set tile at position j,i
              if (temp==nullptr){
                return nullptr;
              }
              else{
                new_maze->setTile(Position(j,i),temp);
              }
            }
          }
        }
        return new_maze;
  }
  else{
    return nullptr;
  }
}


【问题讨论】:

  • A segmentation fault 在访问内存中的受限区域时发生。它可能表明您的内存访问有时是应用程序内存的一部分,有时不是。尝试检查警告,使用valgrind,或发布您的代码。
  • 您想在 gdb 中重现分段错误吗?
  • 你知道什么程序正在打印segmentation fault 吗? shell会打印Segmentation fault,大写S。如果是你自己的程序,能不能给我们看一下相关代码?
  • 无论如何,在运行程序之前在 gdb 中输入set disable-randomization off 可能会导致这些分段错误发生,但我不确定它们是否发生在您的程序或其他进程中。你能描述一下你的程序是如何创建和运行其他进程的吗?
  • @MarkPlotnick 嗨,我试过了,找到了分段错误发生的位置——它发生在我调用 setTile 函数时

标签: c++ debugging segmentation-fault gdb


【解决方案1】:

在 Linux 上,segmentation fault(请参阅signal(7)...)可以生成core dump。见core(5)。您可能需要启用它们(例如,在您的终端中使用一些适当的 ulimit 内置函数,请参阅由您的 shell 完成的 setrlimit(2))。

gdb debugger 能够分析诸如core 文件的事后分析。

当然,用g++ -Wall -Wextra -g编译你的C++代码

【讨论】:

    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 2017-08-05
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 2014-11-30
      • 2019-10-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      相关资源
      最近更新 更多