1

I'm a newbie using OpenFOAM-6. I'm trying to read the source codes by GDB. However, I cannot understand why GDB cannot step into the constructor of some classes like fvMesh. Also GDB reports something like

(gdb) p mesh
$1 = <incomplete type>

I first compiled an application rhoSimpleFoam in Debug mode. Basically, I export the variable WM_COMPILE_OPTION from Opt to Debug, and then compile the application. I also tried compiling the whole bunch of OpenFOAM in the Debug mode. No effects on what I will describe below. The Debug mode of rhoSimpleFoam is 3.8MB while the Opt version is 889KB.

Then I use gdb to run rhoSimpleFoam by

gdb <ThePathToDebugMode>/rhoSimpleFoam

The rhoSimpleFoam.C is as follows,

#include "fvCFD.H"
#include "fluidThermo.H"
#include "turbulentFluidThermoModel.H"
#include "simpleControl.H"
#include "pressureControl.H"
#include "fvOptions.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

int main(int argc, char *argv[])
{
    #include "postProcess.H"

    #include "setRootCaseLists.H"
    #include "createTime.H"
    #include "createMesh.H"
    #include "createControl.H"
    #include "createFields.H"
    #include "createFieldRefs.H"
    #include "initContinuityErrs.H"

    turbulence->validate();

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    Info<< "\nStarting time loop\n" << endl;

    while (simple.loop(runTime))
    {
        Info<< "Time = " << runTime.timeName() << nl << endl;

        // Pressure-velocity SIMPLE corrector
        #include "UEqn.H"
        #include "EEqn.H"

        if (simple.consistent())
        {
            #include "pcEqn.H"
        }
        else
        {
            #include "pEqn.H"
        }

        turbulence->correct();

        runTime.write();

        Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
            << "  ClockTime = " << runTime.elapsedClockTime() << " s"
            << nl << endl;
    }

    Info<< "End\n" << endl;

    return 0;

What I want to know is how the fvMesh is initialized, which should be done in #include "createMesh.H". The file createMesh.H is as follows,

Foam::Info
    << "Create mesh for time = "
    << runTime.timeName() << Foam::nl << Foam::endl;

Foam::fvMesh mesh
(
    Foam::IOobject
    (
        Foam::fvMesh::defaultRegion,
        runTime.timeName(),
        runTime,
        Foam::IOobject::MUST_READ
    )
);

I set a breakpoint at Foam::fvMesh mesh in GDB and run to there. However, GDB cannot step into the constructor of that fvMesh. Instead GDB steps into runTime.timeName(). After that, GDB gets out of that file createMesh.H. The corresponding constructor of that fvMesh is as follows,

Foam::fvMesh::fvMesh(const IOobject& io)
:
    polyMesh(io),
    surfaceInterpolation(*this),
    fvSchemes(static_cast<const objectRegistry&>(*this)),
    fvSolution(static_cast<const objectRegistry&>(*this)),
    data(static_cast<const objectRegistry&>(*this)),
    boundary_(*this, boundaryMesh()),
    lduPtr_(nullptr),
    curTimeIndex_(time().timeIndex()),
    VPtr_(nullptr),
    V0Ptr_(nullptr),
    V00Ptr_(nullptr),
    SfPtr_(nullptr),
    magSfPtr_(nullptr),
    CPtr_(nullptr),
    CfPtr_(nullptr),
    phiPtr_(nullptr)
{
    if (debug)
    {
        InfoInFunction << "Constructing fvMesh from IOobject" << endl;
    }

    // Check the existence of the cell volumes and read if present
    // and set the storage of V00
    if (fileHandler().isFile(time().timePath()/"V0"))
    {
        V0Ptr_ = new DimensionedField<scalar, volMesh>
        (
            IOobject
            (
                "V0",
                time().timeName(),
                *this,
                IOobject::MUST_READ,
                IOobject::NO_WRITE,
                false
            ),
            *this
        );

        V00();
    }

    // Check the existence of the mesh fluxes, read if present and set the
    // mesh to be moving
    if (fileHandler().isFile(time().timePath()/"meshPhi"))
    {
        phiPtr_ = new surfaceScalarField
        (
            IOobject
            (
                "meshPhi",
                time().timeName(),
                *this,
                IOobject::MUST_READ,
                IOobject::NO_WRITE,
                false
            ),
            *this
        );

        // The mesh is now considered moving so the old-time cell volumes
        // will be required for the time derivatives so if they haven't been
        // read initialise to the current cell volumes
        if (!V0Ptr_)
        {
            V0Ptr_ = new DimensionedField<scalar, volMesh>
            (
                IOobject
                (
                    "V0",
                    time().timeName(),
                    *this,
                    IOobject::NO_READ,
                    IOobject::NO_WRITE,
                    false
                ),
                V()
            );
        }

        moving(true);
    }
}

Another problem I cannot understand is as follows. GDB is still in the file createMesh.H. GDB knows nothing about some variables, just like the following output.

(gdb) p runTime
$1 = <incomplete type>
(gdb) p runTime.timeName()
Couldn't find method Foam::Time::timeName

In fact, I use info sources in GDB to show the loaded symbols. For references for info sources, check this webpage. The symbols have already been loaded.

So it seems like GDB knows really a little about OpenFOAM. GDB cannot step into a function body in some OpenFOAM classes. GDB cannot find some methods in OpenFOAM either.

Anyone could help me understand what's going on? Thanks!

Jingchang

石京昶
  • 31
  • 6

0 Answers0