c++程序中的段故障难以理解的valgrind输出

Segfault in c++ program; Incomprehensible valgrind output

本文关键字:valgrind 输出 故障 程序 段故障 c++      更新时间:2023-10-16

我目前正在编写我的第一个大型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"也没有给我任何提示从哪里开始。

那么,关于如何修复这个错误有什么想法吗?

更新:

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

看完答案后,我给了调试的另一个机会,我插入了一行'std::cout<<this指针指向"<<"这& lt; & lt;Std:: endl;'在不同位置。结果是,指针在调用函数setrotion后真的指向null。在这个函数中,我写入了一个有12个元素的数组的第[12]个元素(但从0开始-因此在元素[11]结束)。对于大多数时间使用Matlab的人来说,这是一个典型的错误。我修复了这个问题,程序运行没有任何错误。然后我再次插入错误,并使用gdb进行了第二次查看。但它仍然说this指针指向正确的位置。我不知道调试器出了什么问题。它是否不更新或其他什么,但它并没有给我任何提示我做错了什么。

所以无论是gdb还是gdb的KDevelop GUI都有一个错误,掩盖了我自己的错误。

非常感谢您帮我修复错误

无效读取大小为8

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

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

意味着地址是零——所以你试图读一个空指针。

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

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

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

或者,您在SetRotation中有一个错误,它使您的内存无法识别。

你需要使用你的调试器