2016-02-03 2 views
1

Я в настоящее время отлаживаю программу C/C++, которую я написал, которая использует Bullet Physics. Я работаю над Ubuntu 14.04.3, используя g ++ 4.8.4, valgrind 3.10.1 и Bullet Physics 2.82.Программа остановки останова GDB (точка останова в библиотеке Bullet Physics)

Моя команда компиляции (для отладки) является:

g++ -fno-inline -O0 -g -Wall -Wl,-rpath=./more_libs/lib,--enable-new-dtags -std=gnu++11 -I../bullet-2.82-r2704/Demos/OpenGL/ -I./more_libs/include/ -I../bullet-2.82-r2704/src/ ./main.cpp -L../bullet-2.82-r2704/Glut/ -L./more_libs/lib/ -L./more_libs/mesa -L../bullet-build/Demos/OpenGL/ -L../more_libs/lib/x86_64-linux-gnu -L../bullet-build/src/BulletDynamics/ -L../bullet-build/src/BulletCollision/ -L../bullet-build/src/LinearMath/ -lOpenGLSupport -lGL -lGLU -lglut -lBulletDynamics -lBulletCollision -lLinearMath -lXi -lXxf86vm -lX11 -o ./app 

(разница между отладкой и нормальной является -O0 и -fno-инлайн варианты я добавляю библиотеки путь, потому что мне нужна эта программа для. . быть переносимым на кластере я не имею права суперпользователя на)

Использование Valgrind, я нашел тонну подобных ошибок UNINITIALIZED Value, которые выглядят следующим образом:

Conditional jump or move depends on uninitialised value(s) 
    at 0x4608C1: btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject**, int, btPersistentManifold**, int, btTypedConstraint**, int, btContactSolverInfo const&, btIDebugDraw*) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app) 
    by 0x4591FC: btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject**, int, btPersistentManifold**, int, btTypedConstraint**, int, btContactSolverInfo const&, btIDebugDraw*, btDispatcher*) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app) 
    by 0x46A3FF: btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo&) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app) 
    by 0x467584: btDiscreteDynamicsWorld::internalSingleStepSimulation(float) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app) 
    by 0x465459: btDiscreteDynamicsWorld::stepSimulation(float, int, float) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app) 
    by 0x4088F4: NoiseWorld::clientMoveAndDisplay() (NoiseWorld.cpp:288) 
    by 0x409A28: main (main.cpp:46) 
    Uninitialised value was created by a heap allocation 
    at 0x4C2ABBD: malloc (vg_replace_malloc.c:296) 
    by 0x4EE043: btAlignedAllocDefault(unsigned long, int) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app) 
    by 0x40BC09: btHingeConstraint::operator new(unsigned long) (btHingeConstraint.h:103) 
    by 0x40CF73: NoiseWorld::CreateHinge(int, int, int, float, float, float, float, float, float, float, float, bool) (NoiseWorld.h:332) 
    by 0x40807C: NoiseWorld::initPhysics() (NoiseWorld.cpp:193) 
    by 0x4099F4: main (main.cpp:41) 

Я попытался посмотреть, что происходит в solveGroupCacheFriendlySetup(), но когда я установил там точку останова и запустил GDB, программа не останавливается - она ​​просто заканчивается. Я установил точку останова по функции и по памяти (которая является постоянной по проверкам valgrind), но ни одна из них не найдена/использована.

Итак, вот вопрос: как я могу посмотреть, что происходит в решении GroupCacheFriendlySetup() во время запуска программы? Оттуда я думаю, что смогу выяснить, что осталось неинициализированным.

Извините, если это простой вопрос, но я не смог найти ответ в течение последних двух дней. Я начинающий программист, и я взялся за большой проект, поэтому я предполагаю, что есть что-то простое, что я делаю неправильно, но я точно не знаю, что спросить на этом этапе.

EDIT: Вот функция, я должен смотреть на время работы, согласно предложению πάντα ῥεῖ в. Онлайн-документацию для этой функции можно найти здесь: http://bulletphysics.org/Bullet/BulletFull/classbtSequentialImpulseConstraintSolver.html

Примечание: эта часть кода не была написана мной, и я не на 100%, что она делает. Я уверен, что ошибка лежит где-то в другом месте; что я недостаточно настраиваю физико-симуляторную среду.

Кроме того, я не знаю, что сообщение valgrind "(в/home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/C++/app)" означает с точки зрения попытки добавить точку останова которые GDB может найти при запуске программы.

btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) 
{ 
    m_fixedBodyId = -1; 
    BT_PROFILE("solveGroupCacheFriendlySetup"); 
    (void)debugDrawer; 

    m_maxOverrideNumSolverIterations = 0; 

#ifdef BT_ADDITIONAL_DEBUG 
    //make sure that dynamic bodies exist for all (enabled) constraints 
    for (int i=0;i<numConstraints;i++) 
    { 
     btTypedConstraint* constraint = constraints[i]; 
     if (constraint->isEnabled()) 
     { 
      if (!constraint->getRigidBodyA().isStaticOrKinematicObject()) 
      { 
       bool found=false; 
       for (int b=0;b<numBodies;b++) 
       { 

        if (&constraint->getRigidBodyA()==bodies[b]) 
        { 
         found = true; 
         break; 
        } 
       } 
       btAssert(found); 
      } 
      if (!constraint->getRigidBodyB().isStaticOrKinematicObject()) 
      { 
       bool found=false; 
       for (int b=0;b<numBodies;b++) 
       { 
        if (&constraint->getRigidBodyB()==bodies[b]) 
        { 
         found = true; 
         break; 
        } 
       } 
       btAssert(found); 
      } 
     } 
    } 
    //make sure that dynamic bodies exist for all contact manifolds 
    for (int i=0;i<numManifolds;i++) 
    { 
     if (!manifoldPtr[i]->getBody0()->isStaticOrKinematicObject()) 
     { 
      bool found=false; 
      for (int b=0;b<numBodies;b++) 
      { 

       if (manifoldPtr[i]->getBody0()==bodies[b]) 
       { 
        found = true; 
        break; 
       } 
      } 
      btAssert(found); 
     } 
     if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject()) 
     { 
      bool found=false; 
      for (int b=0;b<numBodies;b++) 
      { 
       if (manifoldPtr[i]->getBody1()==bodies[b]) 
       { 
        found = true; 
        break; 
       } 
      } 
      btAssert(found); 
     } 
    } 
#endif //BT_ADDITIONAL_DEBUG 


    for (int i = 0; i < numBodies; i++) 
    { 
     bodies[i]->setCompanionId(-1); 
    } 


    m_tmpSolverBodyPool.reserve(numBodies+1); 
    m_tmpSolverBodyPool.resize(0); 

    //btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); 
    //initSolverBody(&fixedBody,0); 

    //convert all bodies 

    for (int i=0;i<numBodies;i++) 
    { 
     int bodyId = getOrInitSolverBody(*bodies[i],infoGlobal.m_timeStep); 

     btRigidBody* body = btRigidBody::upcast(bodies[i]); 
     if (body && body->getInvMass()) 
     { 
      btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId]; 
      btVector3 gyroForce (0,0,0); 
      if (body->getFlags()&BT_ENABLE_GYROPSCOPIC_FORCE) 
      { 
       gyroForce = body->computeGyroscopicForce(infoGlobal.m_maxGyroscopicForce); 
       solverBody.m_externalTorqueImpulse -= gyroForce*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep; 
      } 
     } 
    } 

    if (1) 
    { 
     int j; 
     for (j=0;j<numConstraints;j++) 
     { 
      btTypedConstraint* constraint = constraints[j]; 
      constraint->buildJacobian(); 
      constraint->internalSetAppliedImpulse(0.0f); 
     } 
    } 

    //btRigidBody* rb0=0,*rb1=0; 

    //if (1) 
    { 
     { 

      int totalNumRows = 0; 
      int i; 

      m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints); 
      //calculate the total number of contraint rows 
      for (i=0;i<numConstraints;i++) 
      { 
       btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i]; 
       btJointFeedback* fb = constraints[i]->getJointFeedback(); 
       if (fb) 
       { 
        fb->m_appliedForceBodyA.setZero(); 
        fb->m_appliedTorqueBodyA.setZero(); 
        fb->m_appliedForceBodyB.setZero(); 
        fb->m_appliedTorqueBodyB.setZero(); 
       } 

       if (constraints[i]->isEnabled()) 
       { 
       } 
       if (constraints[i]->isEnabled()) 
       { 
        constraints[i]->getInfo1(&info1); 
       } else 
       { 
        info1.m_numConstraintRows = 0; 
        info1.nub = 0; 
       } 
       totalNumRows += info1.m_numConstraintRows; 
      } 
      m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows); 


      ///setup the btSolverConstraints 
      int currentRow = 0; 

      for (i=0;i<numConstraints;i++) 
      { 
       const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i]; 

       if (info1.m_numConstraintRows) 
       { 
        btAssert(currentRow<totalNumRows); 

        btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow]; 
        btTypedConstraint* constraint = constraints[i]; 
        btRigidBody& rbA = constraint->getRigidBodyA(); 
        btRigidBody& rbB = constraint->getRigidBodyB(); 

        int solverBodyIdA = getOrInitSolverBody(rbA,infoGlobal.m_timeStep); 
        int solverBodyIdB = getOrInitSolverBody(rbB,infoGlobal.m_timeStep); 

        btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA]; 
        btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB]; 




        int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations; 
        if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations) 
         m_maxOverrideNumSolverIterations = overrideNumSolverIterations; 


        int j; 
        for (j=0;j<info1.m_numConstraintRows;j++) 
        { 
         memset(&currentConstraintRow[j],0,sizeof(btSolverConstraint)); 
         currentConstraintRow[j].m_lowerLimit = -SIMD_INFINITY; 
         currentConstraintRow[j].m_upperLimit = SIMD_INFINITY; 
         currentConstraintRow[j].m_appliedImpulse = 0.f; 
         currentConstraintRow[j].m_appliedPushImpulse = 0.f; 
         currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA; 
         currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB; 
         currentConstraintRow[j].m_overrideNumSolverIterations = overrideNumSolverIterations; 
        } 

        bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); 
        bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); 
        bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); 
        bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); 
        bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); 
        bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); 
        bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); 
        bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); 


        btTypedConstraint::btConstraintInfo2 info2; 
        info2.fps = 1.f/infoGlobal.m_timeStep; 
        info2.erp = infoGlobal.m_erp; 
        info2.m_J1linearAxis = currentConstraintRow->m_contactNormal1; 
        info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; 
        info2.m_J2linearAxis = currentConstraintRow->m_contactNormal2; 
        info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; 
        info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this 
        ///the size of btSolverConstraint needs be a multiple of btScalar 
        btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint)); 
        info2.m_constraintError = &currentConstraintRow->m_rhs; 
        currentConstraintRow->m_cfm = infoGlobal.m_globalCfm; 
        info2.m_damping = infoGlobal.m_damping; 
        info2.cfm = &currentConstraintRow->m_cfm; 
        info2.m_lowerLimit = &currentConstraintRow->m_lowerLimit; 
        info2.m_upperLimit = &currentConstraintRow->m_upperLimit; 
        info2.m_numIterations = infoGlobal.m_numIterations; 
        constraints[i]->getInfo2(&info2); 

        ///finalize the constraint setup 
        for (j=0;j<info1.m_numConstraintRows;j++) 
        { 
         btSolverConstraint& solverConstraint = currentConstraintRow[j]; 

         if (solverConstraint.m_upperLimit>=constraints[i]->getBreakingImpulseThreshold()) 
         { 
          solverConstraint.m_upperLimit = constraints[i]->getBreakingImpulseThreshold(); 
         } 

         if (solverConstraint.m_lowerLimit<=-constraints[i]->getBreakingImpulseThreshold()) 
         { 
          solverConstraint.m_lowerLimit = -constraints[i]->getBreakingImpulseThreshold(); 
         } 

         solverConstraint.m_originalContactPoint = constraint; 

         { 
          const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal; 
          solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor(); 
         } 
         { 
          const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; 
          solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor(); 
         } 

         { 
          btVector3 iMJlA = solverConstraint.m_contactNormal1*rbA.getInvMass(); 
          btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal; 
          btVector3 iMJlB = solverConstraint.m_contactNormal2*rbB.getInvMass();//sign of normal? 
          btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal; 

          btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal1); 
          sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); 
          sum += iMJlB.dot(solverConstraint.m_contactNormal2); 
          sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); 
          btScalar fsum = btFabs(sum); 
          btAssert(fsum > SIMD_EPSILON); 
          solverConstraint.m_jacDiagABInv = fsum>SIMD_EPSILON?btScalar(1.)/sum : 0.f; 
         } 



         { 
          btScalar rel_vel; 
          btVector3 externalForceImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalForceImpulse : btVector3(0,0,0); 
          btVector3 externalTorqueImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalTorqueImpulse : btVector3(0,0,0); 

          btVector3 externalForceImpulseB = bodyBPtr->m_originalBody ? bodyBPtr->m_externalForceImpulse : btVector3(0,0,0); 
          btVector3 externalTorqueImpulseB = bodyBPtr->m_originalBody ?bodyBPtr->m_externalTorqueImpulse : btVector3(0,0,0); 

          btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rbA.getLinearVelocity()+externalForceImpulseA) 
               + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()+externalTorqueImpulseA); 

          btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rbB.getLinearVelocity()+externalForceImpulseB) 
                   + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()+externalTorqueImpulseB); 

          rel_vel = vel1Dotn+vel2Dotn; 
          btScalar restitution = 0.f; 
          btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2 
          btScalar velocityError = restitution - rel_vel * info2.m_damping; 
          btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; 
          btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; 
          solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; 
          solverConstraint.m_appliedImpulse = 0.f; 


         } 
        } 
       } 
       currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows; 
      } 
     } 

     convertContacts(manifoldPtr,numManifolds,infoGlobal); 

    } 

// btContactSolverInfo info = infoGlobal; 


    int numNonContactPool = m_tmpSolverNonContactConstraintPool.size(); 
    int numConstraintPool = m_tmpSolverContactConstraintPool.size(); 
    int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size(); 

    ///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints 
    m_orderNonContactConstraintPool.resizeNoInitialize(numNonContactPool); 
    if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) 
     m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool*2); 
    else 
     m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool); 

    m_orderFrictionConstraintPool.resizeNoInitialize(numFrictionPool); 
    { 
     int i; 
     for (i=0;i<numNonContactPool;i++) 
     { 
      m_orderNonContactConstraintPool[i] = i; 
     } 
     for (i=0;i<numConstraintPool;i++) 
     { 
      m_orderTmpConstraintPool[i] = i; 
     } 
     for (i=0;i<numFrictionPool;i++) 
     { 
      m_orderFrictionConstraintPool[i] = i; 
     } 
    } 

    return 0.f; 

} 
+0

Боюсь, мы не можем дать вам краткий ответ с этим узким контекстом информации. По крайней мере, покажите 'solveGroupCacheFriendlySetup()' и где вы установили точку останова. –

+0

@ πάνταῥεῖ Я добавил код, однако, как я уже упоминал в своей заметке, я не думаю, что в этом ошибка. Согласно tor valgrind, я неправильно инициализировал шарниры, которые соединяют фигуры в физическом симуляторе; просто эти значения используются в решении GroupCacheFriendlySetup(). Я в основном смущен тем, как интерпретировать строки типа «(в/home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/C++/app)» часть сообщения valgrind. – KodoCoder

+0

Я предполагаю, что вы ссылаетесь на статическую версию lib, которая просто не прерывается, за исключением случаев, когда вы входите в сборку. Если вы можете ссылаться на отладочную версию, которая включает в себя информацию об отладке, по крайней мере на платформе Windows, это позволяет отладчику входить в функцию. – StarShine

ответ

1

Если вы хотите отлаживать программу при запуске под Valgrind, , то вы можете сделать следующее:

Valgrind --vgdb-ошибка = 1 .... остальные аргументы, как обычно,

Тогда при первой ошибке valgrind остановится и будет ждать подключения gdb. Затем вы можете использовать команды gdb и/или функции valgrind для определения проблемы . Вы можете продолжить выполнение с помощью команды gdb continue , чтобы остановить следующую ошибку.

Для получения дополнительной информации см. http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver.

+0

Это, плюс обеспечение того, что я связан с динамическими библиотеками, сделал трюк. Благодаря! – KodoCoder