Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crash, assert:physx::shdfnd::TlsSet (version: 3.3 ~ 4.1) #210

Open
yefansky opened this issue Oct 26, 2019 · 0 comments
Open

crash, assert:physx::shdfnd::TlsSet (version: 3.3 ~ 4.1) #210

yefansky opened this issue Oct 26, 2019 · 0 comments

Comments

@yefansky
Copy link

yefansky commented Oct 26, 2019

#include "stdafx.h"
#include "PxPhysicsAPI.h"
using namespace physx;

#define GAME_FPS 30

int main()
{
    static PxDefaultErrorCallback s_DefaultErrorCallback;
    static PxDefaultAllocator s_DefaultAllocatorCallback;
    auto pFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, s_DefaultAllocatorCallback,
        s_DefaultErrorCallback);
    auto pPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *pFoundation,
        PxTolerancesScale(), false, nullptr);
    auto pMaterial = pPhysics->createMaterial(0.5f, 0.5f, 0.1f);

    PxVec3 position(1.0f, 1.0f, 1.0f);
    PxRigidDynamic* pRigidBody = pPhysics->createRigidDynamic(PxTransform(position));
    PxShape* pBoxShape = pRigidBody->createShape(PxBoxGeometry(2.0f, 2.0f, 2.0f), *pMaterial);

    auto pCpuDispatcher = PxDefaultCpuDispatcherCreate(1);
    PxSceneDesc sceneDesc(pPhysics->getTolerancesScale());
    sceneDesc.gravity = PxVec3(PxZero);
    sceneDesc.cpuDispatcher = pCpuDispatcher;
    sceneDesc.filterShader = PxDefaultSimulationFilterShader;
    auto pPxScene = pPhysics->createScene(sceneDesc);

    pPxScene->simulate(1.0f / GAME_FPS);
    pPxScene->addActor(*pRigidBody);
    pPxScene->removeActor(*pRigidBody);
    pPxScene->fetchResults(true);
    pPxScene->release();
    pPxScene = nullptr;
    pRigidBody->release();
    pRigidBody = nullptr;

    getchar();

    return 0;
}

dump in linux:
#0 0x00007fee1de005f7 in raise () from /lib64/libc.so.6
#1 0x00007fee1de01ce8 in abort () from /lib64/libc.so.6
#2 0x00007fee1ee37b6e in (anonymous namespace)::DefaultAssertHandler::operator() (this=0x7fee1f1921b8 <(anonymous namespace)::sAssertHandler>,
expr=0x7fee1ef635d8 "!status", file=0x7fee1ef636d0 "./../../foundation/src/unix/PsUnixThread.cpp", line=429, ignore=@0x7fee1f19263a: false)
at ./../../foundation/src/PsAssert.cpp:52
#3 0x00007fee1ee44f45 in physx::shdfnd::TlsSet (index=24, value=0x100) at ./../../foundation/src/unix/PsUnixThread.cpp:429
#4 0x00007fee1f48b65a in physx::NpScene::startWrite (this=0xfb4ffe0, allowReentry=true) at ./../../PhysX/src/NpScene.cpp:2804
#5 0x00007fee1f4c4af3 in physx::NpWriteCheck::NpWriteCheck (this=0x7ffdb7ac85b0, scene=0xfb4ffe0, functionName=0x7fee1f836058 "release", allowReentry=true)
at ./../../PhysX/src/NpWriteCheck.cpp:25
#6 0x00007fee1f473307 in physx::NpRigidDynamic::release (this=0xffc0b00) at ./../../PhysX/src/NpRigidDynamic.cpp:44

this demo code in debug, error log:
....\PhysX\src\NpWriteCheck.cpp (29) : invalid operation : An API write call (physx::NpRigidDynamic::release) was made from thread 75568 but PxScene::lockWrite() was not called first, note that when PxSceneFlag::eREQUIRE_RW_LOCK is enabled all API reads and writes must be wrapped in the appropriate locks.

....\PhysX\src\NpReadCheck.cpp (29) : invalid operation : An API read call (physx::NpShape::isExclusive) was made from thread 75568 but PxScene::lockRead() was not called first, note that when PxSceneFlag::eREQUIRE_RW_LOCK is enabled all API reads and writes must be wrapped in the appropriate locks.

....\PhysX\src\NpReadCheck.cpp (29) : invalid operation : An API read call (physx::NpShape::isExclusive) was made from thread 75568 but PxScene::lockRead() was not called first, note that when PxSceneFlag::eREQUIRE_RW_LOCK is enabled all API reads and writes must be wrapped in the appropriate locks.
this code in Physx will cause error log(in windows) or crash (in linux debug)
release will not crash, but the memory dirty will cause more danger crisis

reason:
when a rigidbody add to pxScene and remove in same frame, when simulation is running
the rigidbody will from INSERT_PENDING state transfer to NOT_IN_SCENE
and the member 'mScene'(pxScene) in this rigidbody were not clear
then, when this rigidbody release after the pxScene had release
it will crash, because this pointer to pxScene is invalid

PhysX3DEBUG_x64.dll!physx::shdfnd::internal::HashSetBase<physx::Scb::Base * __ptr64,physx::shdfnd::Hash<physx::Scb::Base * __ptr64>,physx::shdfnd::Allocator,1>::erase(physx::Scb::Base * const & k=0xcdcdcdcdcdcdcdcd) Line 524
PhysX3DEBUG_x64.dll!physx::Scb::ObjectTracker::remove(physx::Scb::Base & element={...}) Line 145
PhysX3DEBUG_x64.dll!physx::Scb::ObjectTracker::scheduleForRemove(physx::Scb::Base & element={...}) Line 84
PhysX3DEBUG_x64.dll!physx::Scb::Scene::removephysx::Scb::Body,1(physx::Scb::Body & v={...}, physx::Scb::ObjectTracker & tracker={...}, bool wakeOnLostTouch=true) Line 420
PhysX3DEBUG_x64.dll!physx::Scb::Scene::removeRigidBody(physx::Scb::Body & body={...}, bool wakeOnLostTouch=true, bool noSim=false) Line 601
PhysX3DEBUG_x64.dll!physx::NpScene::removeRigidDynamic(physx::NpRigidDynamic & body={...}, bool wakeOnLostTouch=true, bool removeFromAggregate=true) Line 835
PhysX3DEBUG_x64.dll!physx::NpScene::removeActorInternal(physx::PxActor & actor={...}, bool wakeOnLostTouch=true, bool removeFromAggregate=true) Line 681
PhysX3DEBUG_x64.dll!physx::NpScene::removeActor(physx::PxActor & actor={...}, bool wakeOnLostTouch=true) Line 663 C++
PhysxBugTest.exe!main()

template<typename T, bool removeFromPvd>
void Scb::Scene::remove(T& v, ObjectTracker &tracker, bool wakeOnLostTouch)
{
    if (!mIsBuffering)
    {
        ScSceneFns<T>::remove(mScene, v, wakeOnLostTouch);
        PvdFns<T, removeFromPvd>::releaseInstance(*this, getPvd(), &v);
        v.resetControl(ControlState::eNOT_IN_SCENE);
        v.setScbScene(NULL);
    }
    else
    {
        tracker.scheduleForRemove(v); // !!! <- not set ScbScene to NULL, just remove from buffer
    }
}

void Scb::ObjectTracker::scheduleForRemove(Scb::Base& element)
{
    ControlState::Enum state = element.getControlState();
    PxU32 flags = element.getControlFlags();

    PX_ASSERT(!(flags & ControlFlag::eIS_RELEASED));

    if(state == ControlState::eINSERT_PENDING)
    {
        element.setControlState(ControlState::eNOT_IN_SCENE);
        remove(element);// !!! <- just remove from buffer ???
    }
    else if(state == ControlState::eIN_SCENE)
    {
        element.setControlState(ControlState::eREMOVE_PENDING);
        if(!(flags & ControlFlag::eIS_UPDATED))
        insert(element);
    }
    else
    {
        PX_ALWAYS_ASSERT_MESSAGE("Trying to remove element not in scene.");
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant