C++程序中的Segfault; 难以理解的valgrind输出

0 c++ gdb valgrind kdevelop segmentation-fault

我正在编写我的第一个大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);
}
Run Code Online (Sandbox Code Playgroud)

我在函数中添加了一些消息,以便跟踪错误发生的位置.终端的输出是:

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

函数调用'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== 
Run Code Online (Sandbox Code Playgroud)

(这种情况持续了很长一段时间.如果有帮助,我可以发布完整的输出.)

但是,这对我没有任何帮助,因为我不知道它试图告诉我什么.搜索"valgrind无效读取大小"并没有给我任何关于从哪里开始的提示.

那么,关于如何解决这个错误的任何想法?

更新:

在此电路板输入之前,我尝试使用gdb调试错误.由于这是我第一次遇到这样的错误,我更喜欢GUI版本(KDevelop 4).我设置了一个断点,然后走了一条线.但是,根据调试器,这个指针所指向的地址始终是恒定的(并且是正确的).一切都很好看,直到程序崩溃的路线.崩溃报告没有告诉我任何有价值的信息(根据我通过this-pointer调用的函数,它向我显示错误的来源是std库中的一个,例如"libstdc ++.so.6",我认为不太可能.)然后我尝试了valgrind,一个专门研究这种内存访问错误的调试器(根据其他论坛条目).

在我阅读了答案之后,我给了调试另一个机会的noob-way方式,我插入了行'std :: cout <<"这个指针指向"<< this << std :: endl;' 在不同的地方.事实证明,在调用函数'SetRotation'后,指针确实指向null.在这个函数内部,我写入了一个包含十二个元素的数组的第[12]元素(但从零开始 - 因此在元素[11]处结束).对于大多数时候使用Matlab的人来说,这是一个经典错误.我修复了这个,程序运行没有任何错误.然后我再次插入错误并使用gdb进行第二次查看.但它仍然说这个指针指向正确的位置.我不知道调试器有什么问题.无论是不更新还是其他什么,但它没有给我任何关于我做错的提示.

因此,gdb或gdb的KDevelop GUI都有一个伪装我自己错误的错误.

非常感谢您帮助我修复错误.

Mik*_*our 7

读取大小为8无效

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

地址0x0未堆叠,malloc'd或(最近)free'd

意味着地址为零 - 所以你试图读取空指针.

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

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


Lig*_*ica 5

在我看来,你正在RigidBody通过RigidBody*设置来调用函数0.

或者,你有一个错误,SetRotation会破坏你的记忆,超出所有认可.

您需要使用调试器.