【问题标题】:Segfault in c++ program; Incomprehensible valgrind outputc++程序中的段错误;难以理解的 valgrind 输出
【发布时间】:2013-04-19 12:13:11
【问题描述】:

我目前正在编写我的第一个大型 c++ 项目,但在运行程序时遇到了分段错误。我已经尝试使用 valgrind 对其进行调试,但到目前为止还没有成功。 由于程序很大,我只展示发生错误的相关函数:

void RigidBody::RotateAroundAxis(   dReal Angle,
                                    dRealVector3 Axis,
                                    dRealVector3 Anchor)
{   
    std::cout<<"RotateAroundAxis BodyID: " << this->GetBodyId()<<std::endl;
    dRealMatrix3 RotationMatrix=HelperFunctions::RotateAroundAxis(Angle, Axis);
    dRealMatrix3 CurrentRotation=this->GetRotation();
    dRealVector3 Position=this->GetPosition();
    dRealMatrix3 newRotationMatrix=boost::numeric::ublas::prod(RotationMatrix,CurrentRotation);
    std::cout<<"RotateAroundAxis (Debug0) BodyID: " << this->GetBodyId()<<std::endl;    
    SetRotation(newRotationMatrix);
    std::cout<<"RotateAroundAxis Debug"<<std::endl;// This is the last line that is processed without an error.
    std::cout<<"RotateAroundAxis (Debug1) BodyID: " << this->GetBodyId()<<std::endl; // This line probably causes the error.
    //  object is now rotated but needs to be translated
    boost::numeric::ublas::bounded_vector<dReal,3> PosRelToAnchor;
    std::cout<<"RotateAroundAxis (Debug2) BodyID: " << this->GetBodyId()<<std::endl;
    for(unsigned int i=0;i<3;i++){PosRelToAnchor[i]=Position[i]-Anchor[i];};
    PosRelToAnchor=boost::numeric::ublas::prod(RotationMatrix,PosRelToAnchor);
    for(unsigned int i=0;i<3;i++){Position[i]=PosRelToAnchor(i)+Anchor[i];};
    SetPosition(Position);
}

我将一些消息放入函数中,以便追踪错误发生的位置。终端中的输出是:

SetRotation BodyID: 0x854de60
SetPosition0
SetPositionBodyID0x854de60
SetPosition1
SetPositionEnd
SetRotation (Debug1) BodyID: 0x854de60
SetRotationEnd
RotateAroundAxis Debug
*** Program received signal SIGSEGV (Segmentation fault) ***

'this->GetBodyId()' 的函数调用之前执行没有任何问题,然后它突然产生段错误,我不知道为什么会这样。 使用 valgrind,我得到以下输出:

==10910== Invalid read of size 8
==10910==    at 0x409AF5: RigidBody::RotateAroundAxis(double, boost::array<double, 3ul>, boost::array<double, 3ul>) (RigidBody.cpp:353)
==10910==    by 0x40FFF7: Joints::Hinge::Hinge(dxWorld*, std::string, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double) (Joints.cpp:55)
==10910==    by 0x410563: BioFlexRotatory::BioFlexRotatory(dxWorld*, unsigned char, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double, double, double) (BioFlexRotatory.cpp:30)
==10910==    by 0x40BE9B: Universe::AddBioFlexRotatory(unsigned char, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double, double, double) (Universe.cpp:186)
==10910==    by 0x406CFE: main (main.cpp:75)
==10910==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==10910== 
==10910== 
==10910== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==10910==  Access not within mapped region at address 0x0
==10910==    at 0x409AF5: RigidBody::RotateAroundAxis(double, boost::array<double, 3ul>, boost::array<double, 3ul>) (RigidBody.cpp:353)
==10910==    by 0x40FFF7: Joints::Hinge::Hinge(dxWorld*, std::string, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double) (Joints.cpp:55)
==10910==    by 0x410563: BioFlexRotatory::BioFlexRotatory(dxWorld*, unsigned char, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double, double, double) (BioFlexRotatory.cpp:30)
==10910==    by 0x40BE9B: Universe::AddBioFlexRotatory(unsigned char, boost::array<double, 3ul>, boost::array<double, 3ul>, boost::shared_ptr<RigidBody>, boost::shared_ptr<RigidBody>, double, double, double) (Universe.cpp:186)
==10910==    by 0x406CFE: main (main.cpp:75)
==10910==  If you believe this happened as a result of a stack
==10910==  overflow in your program's main thread (unlikely but
==10910==  possible), you can try to increase the size of the
==10910==  main thread stack using the --main-stacksize= flag.
==10910==  The main thread stack size used in this run was 8388608.
==10910== 
==10910== FILE DESCRIPTORS: 3 open at exit.
==10910== Open file descriptor 2: /dev/pts/6
==10910==    <inherited from parent>
==10910== 
==10910== Open file descriptor 1: /dev/pts/6
==10910==    <inherited from parent>
==10910== 
==10910== Open file descriptor 0: /dev/pts/6
==10910==    <inherited from parent>
==10910== 
==10910== 
==10910== HEAP SUMMARY:
==10910==     in use at exit: 5,521 bytes in 36 blocks
==10910==   total heap usage: 39 allocs, 3 frees, 5,803 bytes allocated
==10910== 
==10910== 24 bytes in 1 blocks are still reachable in loss record 1 of 36
==10910==    at 0x4C286E7: operator new(unsigned long) (vg_replace_malloc.c:287)
==10910==    by 0x40C990: Universe::AddRigidBody(std::string, dMass, boost::array<double, 3ul>, boost::numeric::ublas::c_matrix<double, 3ul, 3ul>, boost::array<double, 3ul>, std::string) (shared_count.hpp:91)
==10910==    by 0x4068AE: main (main.cpp:52)
==10910== 
==10910== 24 bytes in 1 blocks are still reachable in loss record 2 of 36
==10910==    at 0x4C286E7: operator new(unsigned long) (vg_replace_malloc.c:287)
==10910==    by 0x40C990: Universe::AddRigidBody(std::string, dMass, boost::array<double, 3ul>, boost::numeric::ublas::c_matrix<double, 3ul, 3ul>, boost::array<double, 3ul>, std::string) (shared_count.hpp:91)
==10910==    by 0x406A0E: main (main.cpp:56)
==10910== 

(这会持续很长时间。如果有帮助,我可以发布完整的输出。)

但是,这对我没有任何帮助,因为我不知道它试图告诉我什么。搜索“valgrind Invalid read of size”也没有给我任何关于从哪里开始的提示。

那么,关于如何修复此错误的任何想法?

更新:

在此板条目之前,我尝试使用 gdb 调试错误。因为这是我第一次遇到这样的错误,所以我更喜欢 GUI 版本(KDevelop 4)。我设置了一个断点,然后跨过这些线。但是,根据调试器,this 指针指向的地址始终是恒定的(并且正确的)。一切看起来都很好,直到程序崩溃的那一行。并且崩溃报告没有告诉我任何有价值的信息(取决于我通过 this 指针调用的函数,它向我表明错误的来源在一个标准库中,例如“libstdc++.so.6”,我认为这不太可能。)。然后我尝试了 valgrind,一个专门处理这种内存访问错误的调试器(根据其他论坛条目)。

在阅读完答案后,我给了调试另一个机会的菜鸟方式,我插入了行 'std::cout

因此,gdb 或 gdb 的 KDevelop GUI 都有一个错误,它掩盖了我自己的错误。

非常感谢您帮我修复错误。

【问题讨论】:

  • 你的函数完全无法辨认!你到底指望如何调试或维护这个烂摊子??
  • @Lightness:感谢您指出这一点。我总是欣赏建设性的批评。然而,有了函数应该做什么的知识,代码就很容易理解了。关于您的问题:我的调试计划是:使用调试器。如果失败,请尝试另一个调试器。如果失败,请在互联网上搜索答案。如果我没有找到答案,请在论坛中写下这个问题,看看是否有人愿意帮助我。

标签: c++ gdb segmentation-fault valgrind kdevelop


【解决方案1】:

大小为 8 的读取无效

表示程序试图从无效的内存位置读取 8 个字节。

地址 0x0 没有被堆栈、malloc 或(最近)释放

表示地址为零 - 因此您正试图读取空指针。

在 0x409AF5: RigidBody::RotateAroundAxis(double, boost::array, boost::array) (RigidBody.cpp:353)

表示尝试执行此操作的代码位于 RigidBody.cpp 的第 353 行,位于名为 RotateAroundAxis 的函数中。我建议你看看那条线;如果没有明显的问题,那么也许你可以在你的代码示例中标记它,以便我们看一下。在调试器中运行代码可能也是值得的;它应该在分段错误处停止并允许您检查相关变量。

【讨论】:

  • 这是手册的链接。它可能会因其他错误而变得方便:valgrind.org/docs/manual/mc-manual.html#mc-manual.errormsgs
  • '8' 或 '4' 在调试输出中总是可疑的 - sizeof int/pointer on 64/32 位系统。
  • @Martin:比如RigidBody::GetBodyId()的返回值?
  • @LightnessRacesinOrbit - 是的:)
  • @MartinJames:确实如此。也是sizeof (double),这里有装双打的容器。
【解决方案2】:

在我看来,您正在通过设置为 0RigidBody* 调用 RigidBody 函数。

或者,您在SetRotation 中存在一个错误,它会破坏您的记忆,无法辨认。

你需要使用你的调试器。

【讨论】:

  • +1 用于提及“调试器”。这段代码看起来很复杂 - 如果没有这些工具,我不会接近它。
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多