CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Segmentation Fault caused by a pointer (https://www.cfd-online.com/Forums/openfoam-programming-development/143146-segmentation-fault-caused-pointer.html)

floquation October 17, 2014 10:01

Segmentation Fault caused by a pointer
 
Hello,


I am writing a custom CloudFunctionObject, which I based on "ParticleTrap".
Code:

vi $FOAM_SRC/lagrangian/intermediate/submodels/CloudFunctionObjects/ParticleTrap/ParticleTrap.C
For this CloudFunctionObject I will need to interpolate continuum values to particle positions, for which I use "interpolationCellPoint". My pointer to it seems, however, to fail somehow.

Without using parallelisation, I get the following output/error, including my test messages:
Code:

Solving 2-D cloud inclusion
[0] preEvolve begins.
[0] alphaInterpPtr_.valid()? 0
[0] alphaInterpPtr_.empty()? 1
[0] cellI of (0,0.015,0) = 59899
[0] start of if-scope.
[0] alpha has been found.
[0] alphaPtr_ is set.
[0] interpolator is constructed
[0] alphaInterpPtr_ is set.
[0] INSIDE scope test:
[0] alpha at cellCenter = 0
[0] alpha at (0,0.015,0) = 0
[0] alphaInterpPtr_.valid()? 1
[0] alphaInterpPtr_.empty()? 0
[0] OUTSIDE scope test:
[0] alpha at cellCenter = 0
[0] alpha at (0,0.015,0) = 0
[0] OUTSIDE scope test:
[0] alpha at cellCenter = 0
[0] alpha at (0,0.015,0) = 0
[0] POSTMOVE begin
[0] p.origId() = 0
[0] POSTMOVE --> cellI of (0,0.015,0) = 59899
[0] alphaInterpPtr_.valid()? 1
[0] alphaInterpPtr_.empty()? 0
[0] POSTMOVE scope test:
[0] alpha at cellCenter = 0
#0  Foam::error::printStack(Foam::Ostream&) in "/apps/OpenFOAM/OpenFOAM-2.3.x/platforms/linux64GccDPOpt/lib/libOpenFOAM.so"
#1  Foam::sigSegv::sigHandler(int) in "/apps/OpenFOAM/OpenFOAM-2.3.x/platforms/linux64GccDPOpt/lib/libOpenFOAM.so"
#2  __restore_rt at sigaction.c:0
#3  Foam::kvaParticleCaptureAndHold<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > >::postMove(Foam::KinematicParcel<Foam::particle>&, int, double, Foam::Vector<double> const&, bool&) in "/home/A077594/OpenFOAM/A077594-2.3.x/platforms/linux64GccDPOpt/lib/libcustomCloudFunctionObjects_v3.so"
#4  Foam::CloudFunctionObjectList<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > >::postMove(Foam::KinematicParcel<Foam::particle>&, int, double, Foam::Vector<double> const&, bool&) in "/apps/OpenFOAM/site/2.3.x/platforms/linux64GccDPOpt/lib/libsimpleLagrangianFunctionObjects.so"
#5  bool Foam::KinematicParcel<Foam::particle>::move<Foam::KinematicParcel<Foam::particle>::TrackingData<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > > >(Foam::KinematicParcel<Foam::particle>::TrackingData<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > >&, double) in "/apps/OpenFOAM/site/2.3.x/platforms/linux64GccDPOpt/lib/libsimpleLagrangianFunctionObjects.so"
#6  void Foam::InjectionModel<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > >::inject<Foam::KinematicParcel<Foam::particle>::TrackingData<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > > >(Foam::KinematicParcel<Foam::particle>::TrackingData<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > >&) in "/apps/OpenFOAM/site/2.3.x/platforms/linux64GccDPOpt/lib/libsimpleLagrangianFunctionObjects.so"
#7  void Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > >::evolveCloud<Foam::KinematicParcel<Foam::particle>::TrackingData<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > > >(Foam::KinematicParcel<Foam::particle>::TrackingData<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > >&) in "/apps/OpenFOAM/site/2.3.x/platforms/linux64GccDPOpt/lib/libsimpleLagrangianFunctionObjects.so"
#8  void Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > >::solve<Foam::KinematicParcel<Foam::particle>::TrackingData<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > > >(Foam::KinematicParcel<Foam::particle>::TrackingData<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > >&) in "/apps/OpenFOAM/site/2.3.x/platforms/linux64GccDPOpt/lib/libsimpleLagrangianFunctionObjects.so"
#9  Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > >::evolve() in "/apps/OpenFOAM/site/2.3.x/platforms/linux64GccDPOpt/lib/libsimpleLagrangianFunctionObjects.so"
#10  Foam::EvolveCloudFunctionObject<Foam::KinematicCloud<Foam::Cloud<Foam::KinematicParcel<Foam::particle> > > >::execute(bool) in "/apps/OpenFOAM/site/2.3.x/platforms/linux64GccDPOpt/lib/libsimpleLagrangianFunctionObjects.so"
#11  Foam::functionObjectList::execute(bool) in "/apps/OpenFOAM/OpenFOAM-2.3.x/platforms/linux64GccDPOpt/lib/libOpenFOAM.so"
#12  Foam::Time::run() const in "/apps/OpenFOAM/OpenFOAM-2.3.x/platforms/linux64GccDPOpt/lib/libOpenFOAM.so"
#13  main in "/apps/OpenFOAM/OpenFOAM-2.3.x/platforms/linux64GccDPOpt/bin/interFoam"
#14  __libc_start_main in "/lib64/libc.so.6"
#15  __gxx_personality_v0 in "/apps/OpenFOAM/OpenFOAM-2.3.x/platforms/linux64GccDPOpt/bin/interFoam"
Segmentation fault

Judging from the location of the crash (red in the code below), there is something wrong with the pointer.
More specifically, the line which crashes is:
Code:

        scalar testVal = alphaInterpPtr_->interpolate(testPoint, testCell); //Does the pointer work?
Which could be the interpolator, for all we know. However, the line
Code:

alphaInterpPtr_.clear();
causes a crash as well, indicating that I have a pointer issue.
Not using the autoPtr class, but a regular C-pointer (VariableName*), will yield exactly the same result.

Question:
Does anyone know what goes wrong?
Or alternatively, does someone know a work-around / good practice to use?
(I'm trying not to construct a new interpolationCellPoint<scalar> in each postMove(), since it will be called thousands of times per iteration.)



--- Code Appendix ---

Snippet from the header:

Code:

    #include "CloudFunctionObject.H"
    #include "volFields.H"
    #include "interpolationCellPoint.H"

class kvaParticleCaptureAndHold
:
    public CloudFunctionObject<CloudType>
{

        //- Pointer to the volume fraction field
        const volScalarField* alphaPtr_;
        autoPtr<interpolationCellPoint<scalar> > alphaInterpPtr_;
        //const interpolationCellPoint<scalar>* alphaInterpPtr_;


public:

            //- Pre-evolve hook
            virtual void preEvolve();

            //- Post-evolve hook
            virtual void postEvolve();

            //- Post-move hook
            virtual void postMove
            (
                typename CloudType::parcelType& p,
                const label cellI,
                const scalar dt,
                const point& position0,
                bool& keepParticle
            );
}



C-file (preEvolve()):
(For a single processor, this code executes without a problem. In parallel, this code crashes. This is probably for the same reason as my serial code crashes in postMove(), so let's ignore that for now.)
Code:

template<class CloudType>
void Foam::kvaParticleCaptureAndHold<CloudType>::preEvolve()
{
    Sout << "[" << Pstream::myProcNo() << "] " << "preEvolve begins." << nl;
    Sout << "[" << Pstream::myProcNo() << "] " << "alphaInterpPtr_.valid()? " << (alphaInterpPtr_.valid()) << nl;
    Sout << "[" << Pstream::myProcNo() << "] " << "alphaInterpPtr_.empty()? " << (alphaInterpPtr_.empty()) << nl;
    vector testPoint(0.,0.015,0.);
    label testCell = this->owner().mesh().findCell(testPoint);
    Sout << "[" << Pstream::myProcNo() << "] " << "cellI of (0,0.015,0) = " << testCell << nl;

    if (alphaPtr_ == NULL)
    {
        Sout << "[" << Pstream::myProcNo() << "] " << "start of if-scope." << nl;
        const fvMesh& mesh = this->owner().mesh();
        const volScalarField& alpha =
            mesh.lookupObject<volScalarField>(alphaName_);
        Sout << "[" << Pstream::myProcNo() << "] " << "alpha has been found." << nl;

        alphaPtr_ = &alpha;

        Sout << "[" << Pstream::myProcNo() << "] " << "alphaPtr_ is set." << nl;

        interpolationCellPoint<scalar> alphaInterp(*alphaPtr_);
        Sout << "[" << Pstream::myProcNo() << "] " << "interpolator is constructed" << nl;

        alphaInterpPtr_.set(&alphaInterp);
        Sout << "[" << Pstream::myProcNo() << "] " << "alphaInterpPtr_ is set. " << nl;

        if(testCell != -1){ //if point is inside mesh (of the current processor)
                Sout << "[" << Pstream::myProcNo() << "] " << "INSIDE scope test: " << nl;
                scalar alphaAtP = alphaPtr_->internalField()[testCell]; //Does the pointer work? 
                Sout << "[" << Pstream::myProcNo() << "] " << "alpha at cellCenter = " << alphaAtP << nl;
                scalar testVal = alphaInterpPtr_->interpolate(testPoint, testCell); //Does the pointer work?
                Sout << "[" << Pstream::myProcNo() << "] " << "alpha at (0,0.015,0) = " << testVal << nl;
        }
    }
    Sout << "[" << Pstream::myProcNo() << "] " << "alphaInterpPtr_.valid()? " << (alphaInterpPtr_.valid()) << nl;
    Sout << "[" << Pstream::myProcNo() << "] " << "alphaInterpPtr_.empty()? " << (alphaInterpPtr_.empty()) << nl;

    if(testCell != -1){ //if point is inside mesh (of the current processor)
        Sout << "[" << Pstream::myProcNo() << "] " << "OUTSIDE scope test: " << nl;
        scalar alphaAtP = alphaPtr_->internalField()[testCell]; //Does the pointer work? 
        Sout << "[" << Pstream::myProcNo() << "] " << "alpha at cellCenter = " << alphaAtP << nl;
        scalar testVal = alphaInterpPtr_->interpolate(testPoint, testCell); //Does the pointer work?
        Sout << "[" << Pstream::myProcNo() << "] " << "alpha at (0,0.015,0) = " << testVal << nl;
    }

}

C-file (postMove()):
(Just so you know: this method is called for each particle several times, but the code crashes for the very first time this method is called.)
Code:

template<class CloudType>
void Foam::kvaParticleCaptureAndHold<CloudType>::postMove
(
    parcelType& p,              //reference to parcel, e.g.: KinematicParcel<ParcelType> (which extends ParcelType); Where e.g.: ParcelType = particle.
    const label cellI,          //cellID in which the movement took place (movement across a cell border is done in a separate step and thus a separate postMove() call!)
    const scalar dt,            //delta time
    const point& position0,    //position before moving
    bool&                      //keepParticle variable
)
{
    Sout << "[" << Pstream::myProcNo() << "] " << "POSTMOVE begin" << nl;

    //alphaInterpPtr_.clear(); //Line inserted to see if the autoPtr object responds to me //CRASH if uncommented
    //Sout << "[" << Pstream::myProcNo() << "] " << "alphaItnerPtr_ is cleared." << nl;

    vector testPoint(0.,0.015,0.);
    label testCell = this->owner().mesh().findCell(testPoint);
    Sout << "[" << Pstream::myProcNo() << "] " << "POSTMOVE --> cellI of (0,0.015,0) = " << testCell << nl;
    Sout << "[" << Pstream::myProcNo() << "] " << "alphaInterpPtr_.valid()? " << (alphaInterpPtr_.valid()) << nl;
    Sout << "[" << Pstream::myProcNo() << "] " << "alphaInterpPtr_.empty()? " << (alphaInterpPtr_.empty()) << nl;
    if(testCell != -1){ //if point is inside mesh (of the current processor)
        Sout << "[" << Pstream::myProcNo() << "] " << "POSTMOVE scope test: " << nl;
        scalar alphaAtP = alphaPtr_->internalField()[testCell]; //Does the pointer work? 
        Sout << "[" << Pstream::myProcNo() << "] " << "alpha at cellCenter = " << alphaAtP << nl;
        scalar testVal = alphaInterpPtr_->interpolate(testPoint, testCell); //Does the pointer work? //CRASH if "alphaInterpPtr_.clear();" above is commented
        Sout << "[" << Pstream::myProcNo() << "] " << "alpha at (0,0.015,0) = " << testVal << nl;
    }
}


floquation October 17, 2014 11:43

Solved.

It always works to talk to the teddybear on your desk, or to post something at the forums. For some reason, you always figure out the problem shortly thereafter (even though you had been trying for the past 3 days).


I'm not exactly sure what I effectively changed (I started from scratch)...
My hypothesis is that this was my problem:

Good:
Code:

header:
const interpolationCellPoint<scalar>* alphaInterpPtr_;

C:
alphaInterpPtr_ = new interpolationCellPoint<scalar>(*alphaPtr_);

Bad:
Code:

header:
autoPtr<interpolationCellPoint<scalar> > alphaInterpPtr_;

C:
interpolationCellPoint<scalar> alphaInterp(*alphaPtr_);
alphaInterpPtr_ = &alphaInterp;

Hypothesis:
Using "&alphaInterp" for the pointer somehow corrupts the pointer as we leave the method 'preEvolve()' (scope)?
No idea (I'm new to C; Experienced in Java) whether that's true.
Anyone knows the difference (other than the usage of autoPtr; that's not the problem)?


All times are GMT -4. The time now is 11:54.