Box2D Forums

It is currently Fri May 24, 2013 2:45 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Thu Nov 03, 2011 3:09 am 
Offline

Joined: Sat Sep 10, 2011 12:24 am
Posts: 2
I'm experiencing a peculiar crash in a very specific scenario (albeit a scenario that is not entirely uncommon in my case) after calling b2Body::SetTransform.

I've cut down the majority of my game's code and I've managed to reproduce the same bug I'm seeing with the following test case:

Code:
#include <Box2D/Box2D.h>

b2World* world;

b2BodyDef bodyDefDynamic;
b2BodyDef bodyDefStatic;

b2Body* bodyDynamic;
b2Body* bodyStaticA;
b2Body* bodyStaticB;

b2FixtureDef fixtureDef;

void CreateBodies()
{
   bodyDynamic = world->CreateBody(&bodyDefDynamic);
   bodyDynamic->CreateFixture(&fixtureDef);
   bodyDynamic->SetType(b2_staticBody);

   bodyStaticA = world->CreateBody(&bodyDefStatic);
   bodyStaticA->CreateFixture(&fixtureDef);
   bodyStaticA->SetTransform(bodyStaticA->GetPosition(), bodyStaticA->GetAngle());

   bodyStaticB = world->CreateBody(&bodyDefStatic);
   bodyStaticB->CreateFixture(&fixtureDef);

   bodyDynamic->SetType(b2_dynamicBody);
   bodyDynamic->GetFixtureList()->SetFilterData(bodyDynamic->GetFixtureList()->GetFilterData());
}

void DestroyBodies()
{
   world->DestroyBody(bodyDynamic);
   world->DestroyBody(bodyStaticA);
   world->DestroyBody(bodyStaticB);   
}

int main()
{
   world = new b2World(b2Vec2(0.0f, 0.0f));

   b2CircleShape shapeCircle;
   shapeCircle.m_radius = 1.0f;
   fixtureDef.shape = &shapeCircle;

   bodyDefDynamic.type = b2_dynamicBody;
   bodyDefStatic.type = b2_staticBody;

   CreateBodies();
   DestroyBodies();
   CreateBodies();
   DestroyBodies();

   delete world;
   return 0;
}

When bodyStaticA->SetTransform() is called for the second time around, I get a crash in b2ContactManager::AddPair on the following line:

Code:
b2Body* bodyA = fixtureA->GetBody();

fixtureA is at this point set to 0xfdfdfdfd, and my full callstack looks like this:

Code:
>   Box2D Test Case.exe!b2Fixture::GetBody()  Line 275 + 0x3 bytes   C++
    Box2D Test Case.exe!b2ContactManager::AddPair(void * proxyUserDataA=0x00329738, void * proxyUserDataB=0x00329778)  Line 188 + 0x8 bytes   C++
    Box2D Test Case.exe!b2BroadPhase::UpdatePairs<b2ContactManager>(b2ContactManager * callback=0x00329240)  Line 218   C++
    Box2D Test Case.exe!b2ContactManager::FindNewContacts()  Line 175   C++
    Box2D Test Case.exe!b2Body::SetTransform(const b2Vec2 & position={...}, float angle=0.00000000)  Line 426   C++
    Box2D Test Case.exe!CreateBodies()  Line 24   C++
    Box2D Test Case.exe!main()  Line 52   C++
    Box2D Test Case.exe!__tmainCRTStartup()  Line 586 + 0x19 bytes   C
    Box2D Test Case.exe!mainCRTStartup()  Line 403   C

I'm using an entirely unmodified version of Box2D 2.2.1 with Visual Studio 2008 SP1. The specific problem outlined above only occurs in debug builds. The same thing occurs under Debian 6 using Box2D 2.2.1 and g++ (Debian 4.4.5-8) 4.4.5 - again, compiling with _DEBUG defined. I'm going out on a limb, here, but could this be a bug in b2BlockAllocator?

Any help would be greatly appreciated, and thanks for an excellent physics library.


Top
 Profile  
 
PostPosted: Thu Nov 03, 2011 4:44 am 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1517
Location: Tokyo
Same behavior confirmed on
OSX g++
svn r237
cmake .. -DCMAKE_CXX_FLAGS="_DEBUG=1"

Hmm, yeah smells like a bug... Erin will probably come by this thread anyway but it might still be a good idea to add an issue here:
http://code.google.com/p/box2d/issues/list


Top
 Profile  
 
PostPosted: Thu Nov 03, 2011 1:39 pm 
Offline
Site Admin

Joined: Thu Sep 06, 2007 12:34 am
Posts: 2931
Good find. Here's the fix.

Change:
Code:
void b2BroadPhase::UnBufferMove(int32 proxyId)
{
   for (int32 i = 0; i < m_moveCount; ++i)
   {
      if (m_moveBuffer[i] == proxyId)
      {
         m_moveBuffer[i] = e_nullProxy;
         return;
      }
   }
}


To:
Code:
void b2BroadPhase::UnBufferMove(int32 proxyId)
{
   for (int32 i = 0; i < m_moveCount; ++i)
   {
      if (m_moveBuffer[i] == proxyId)
      {
         m_moveBuffer[i] = e_nullProxy;
      }
   }
}


Top
 Profile  
 
PostPosted: Sat Nov 12, 2011 12:21 am 
Offline

Joined: Fri Sep 02, 2011 2:25 pm
Posts: 4
Location: Tucson, AZ
I was almost finished writing up a bug report for what I thought was a different crash when I realized that this fix has the side effect of fixing my crash. But just in case anyone runs into the same issue, the sequence is this:

1. Create body1 with attached fixture/shape
2. Create body2 with attached fixture/shape that overlaps body1
3. Call SetFilterData on body2's fixture so that it will still collide with body1
4. Call world->DestroyBody(body2)
5. Step() now causes crash

Code:
   b2BodyDef bodyDef;
   bodyDef.type = b2_dynamicBody;
   bodyDef.position.Set(0.0, 0.0);
   
   b2CircleShape circleShape;
   circleShape.m_radius = 1.0;
   
   // note: this is the default filter, not actually changing anything
   b2Filter filter;
   filter.categoryBits = (uint16) 0x1;
   filter.maskBits = (uint16) 0xff;
   filter.groupIndex = 0;
   
   b2World world(b2Vec2(0.0, 0.0), true);
   b2Body* circle1Body = world.CreateBody(&bodyDef);
   b2Fixture* circle1Fixture = circle1Body->CreateFixture(&circleShape, 1.0);
   
   b2Body* circle2Body = world.CreateBody(&bodyDef);
   b2Fixture* circle2Fixture = circle2Body->CreateFixture(&circleShape, 1.0);
   
   circle2Fixture->SetFilterData(filter);
   
   world.DestroyBody(circle2Body);
   world.Step(1.0 / 60.0, 10, 10);   


But the code change above also fixes this crash! Awesome.


Top
 Profile  
 
PostPosted: Mon Nov 14, 2011 2:07 am 
Offline

Joined: Tue Oct 04, 2011 1:12 am
Posts: 3
Thanks for the fix. I was facing the same problem.
After having used Box2D for past 2 years successfully and without any problems, I wasn't ready to believe that Box2D could have an internal bug. So I spent 2 days trying to rework my logic to find the reason for this crash.
Came on the forum, just to cross check if I was doing something wrong.
Thanks for the quick fix guys. (Though I haven't tried it yes, I am sure it will work)

Keep up the awesome work.


Top
 Profile  
 
PostPosted: Thu Dec 08, 2011 6:10 am 
Offline

Joined: Wed Jul 09, 2008 3:47 am
Posts: 37
Same here, painful hours that this bug brought me :-D (but still less than writing the entire phys. engine ;) )


Top
 Profile  
 
PostPosted: Mon Jul 02, 2012 6:01 pm 
Offline

Joined: Fri Mar 11, 2011 6:49 pm
Posts: 5
Thanks for this fix! I had been debugging my code for a few hours now, assuming the problem was in my code, which it is 99.99999% of the time.

This bug manifested itself inside b2ContactManager.cpp, line 188 was crashing when trying to use fixtureA, which was a dangling pointer.

Code:
   b2Body* bodyA = fixtureA->GetBody();
   b2Body* bodyB = fixtureB->GetBody();


The fix Erin posted worked for me. Thanks, Erin!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group