It sounds like your objects are moving too fast in each simulation step. The result of this could cause the two objects to over-penetrate. In the case of the character controller code provided there is a recoverFromPenetration that is called to move the object that caused the collision backwards (backwards being defined as calculated from the normals of the penetrating polygons) until it is no longer penetrating.
void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld)
{
int numPenetrationLoops = 0;
m_touchingContact = false;
while (recoverFromPenetration (collisionWorld))
{
numPenetrationLoops++;
m_touchingContact = true;
if (numPenetrationLoops > 4)
{
//printf("character could not recover from penetration = %d\n", numPenetrationLoops);
break;
}
}
m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
m_targetPosition = m_currentPosition;
// printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]);
}
It tries to do this 4 times and if it does not resolve the penetration the recovery code fails and terminates with the objects still penetrating one another. This controller code is not intended to be production code but rather a starting point and framework for further customization and development. It serves its purpose pretty well but as you have discovered there are limitations.