【问题标题】:GDB breakpoint not stopping program (Breakpoint in Bullet Physics library)GDB 断点不停止程序(子弹物理库中的断点)
【发布时间】:2016-02-03 18:19:35
【问题描述】:

我目前正在调试我编写的使用 Bullet Physics 的 C/C++ 程序。我正在使用 g++ 4.8.4、valgrind 3.10.1 和 Bullet Physics 2.82 开发 Ubuntu 14.04.3。

我的编译命令(用于调试)是:

   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-inline 选项。我正在添加库路径,因为我需要将此程序移植到我没有超级用户权限的集群。)

使用 Valgrind,我发现了大量类似的未初始化值错误,如下所示:

    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 检查中是恒定的),但没有一个被找到/使用。

那么,问题来了:在程序运行期间如何查看solveGroupCacheFriendlySetup() 中发生了什么?从那里,我想我将能够找出未初始化的内容。

如果这是一个简单的问题,请提前抱歉,但过去两天我一直无法找到答案。我是一个新手程序员,我已经承担了一个大项目,所以我猜我做错了一些简单的事情,但我现在不知道具体要问什么。

编辑: 根据 πάντα ῥεῖ 的建议,这是我在运行时需要查看的功能。这个函数的在线文档可以在这里找到: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;

}

【问题讨论】:

  • 恐怕我们无法在信息范围狭窄的情况下给您一个简明的答案。至少显示solveGroupCacheFriendlySetup() 以及您设置断点的位置。
  • @πάνταῥεῖ 我添加了代码,但是,正如我在笔记中提到的,我认为这不是错误所在。根据 valgrind 的说法,我错误地初始化了物理模拟器中连接形状的铰链;只是这些值在solveGroupCacheFriendlySetup() 中使用。我很困惑如何解释 valgrind 消息的“(在 /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app)”部分。
  • 我猜你正在链接到一个静态发布库,它根本不会中断,除非你进入汇编。如果您可以链接到包含调试信息的调试版本,至少在 Windows 平台上,这允许调试器中断该函数。
  • 感谢@StarShine,确保我链接到动态库是解决方案的一部分。
  • @StarShine 如果您将您的评论作为答案发表,我会很乐意接受它以给予您适当的信任。虽然用户 phd 提供了帮助,但我已经知道该功能;您的意见是真正的游戏规则改变者。

标签: c++ gdb valgrind breakpoints


【解决方案1】:

如果您想在 valgrind 下运行程序时对其进行调试, 那么您可以执行以下操作:

valgrind --vgdb-error=1 .... 其余参数照常

然后在第一个错误时,valgrind 将停止,并等待 gdb 连接。 然后,您可以使用 gdb 命令和/或 valgrind 特定功能 调查问题。您可以使用 gdb continue 继续执行 命令,在下一个错误时停止。

更多信息请参见http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

【讨论】:

  • 这个,加上确保我链接到动态库就可以了。谢谢!
猜你喜欢
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 2012-03-11
相关资源
最近更新 更多