问题
I'm currently writing my first big c++-project but encountered a segmentation fault when running the program. I already tried to debug it using valgrind, but so far without success. Since the program is quite big, I'll show only the relevant function in which the error occured:
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);
}
I put some messages into the function in order to track down where the error occurs. The output in the terminal is:
SetRotation BodyID: 0x854de60
SetPosition0
SetPositionBodyID0x854de60
SetPosition1
SetPositionEnd
SetRotation (Debug1) BodyID: 0x854de60
SetRotationEnd
RotateAroundAxis Debug
*** Program received signal SIGSEGV (Segmentation fault) ***
The function call to 'this->GetBodyId()' is executed before without any problem and then it suddenly produces the segfault and I have no clue why it does so. Using valgrind, I got following output:
==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==
(This goes on for quite a while. If it helps, I can post the full output.)
However, this doesn't help me at all because I have no clue what it tries to tell me. Searching for "valgrind Invalid read of size" did not give me any hints on where to start either.
So, any ideas on how to fix this error?
UPDATE:
Prior to this board entry, I tried to debug the error using gdb. Since this was the first time I encountered such an error, I prefered the GUI version (KDevelop 4). I set a breakpoint and then stepped trough the lines. However, according to the debugger the address, the this-pointer pointed to, was constant (and correct) all the time. Everything looked good till the line where the program crashed. And the crash report did not tell me anything valuable (Depending on which function I called through the this-pointer, it showed me that the source of the error was in one of the std libraries such as the "libstdc++.so.6", which I believed was unlikely.). Then I tried valgrind, a debugger that is specialised on this kind of memory access error (according to other forum entries).
After I reading the answers, I gave the noob-way of debugging another chance and I inserted the line 'std::cout<<"The this pointer points to" << this << std:: endl;' at various locations. And as it turns out, the pointer really points to null after calling the function 'SetRotation'. Inside of this function I wrote into the [12]th element of an array that has twelve elements (but starts at zero - therefore end at element [11]). A classical error for someone who works with Matlab most of the time. I fixed this and the program runs without any error. Then I insered the error again and had a second look using gdb. But it still says that the this pointer points to the correct place. I don't know what's the problem withe the debugger. Whether it does not update or whatever, but it does not give me any hints on what I did wrong.
So either the gdb or the KDevelop GUI for gdb has a bug that disguised my own error.
Thank you very much for helping me fix the error.
回答1:
Invalid read of size 8
means that the program tried to read 8 bytes from an invalid memory location.
Address 0x0 is not stack'd, malloc'd or (recently) free'd
means that the address was zero - so you're trying to read through a null pointer.
at 0x409AF5: RigidBody::RotateAroundAxis(double, boost::array, boost::array) (RigidBody.cpp:353)
means that the code that tried to do that was at line 353 of RigidBody.cpp
, in a function called RotateAroundAxis
. I suggest you look at that line; if there's no obvious problem, then perhaps you could mark it in your code sample so we can take a look. It might also be worth running the code in a debugger; it should stop at the segmentation fault and allow you to inspect the relevant variables.
回答2:
It looks to me like you're calling a RigidBody
function through a RigidBody*
that's set to 0
.
Alternatively, you have a bug in SetRotation
that mangles your memory beyond all recognition.
You need to use your debugger.
来源:https://stackoverflow.com/questions/16104364/segfault-in-c-program-incomprehensible-valgrind-output