|
[Sponsors] |
Segmentation fault by randomly passing parameter into a function when using PtrList |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
September 6, 2020, 09:21 |
Segmentation fault by randomly passing parameter into a function when using PtrList
|
#1 |
New Member
Nam Danh Nguyen
Join Date: Feb 2020
Location: UNIST-Ulsan-Korea
Posts: 25
Rep Power: 6 |
Dear Foamers!
I am developing real gas models such as EoS, thermodynamics and transport (including viscosity, thermal conductivity and Diffusion coefficients) in thermophysicalModels lib for Combustion solvers using OF-6. In diffusion model implementation, I create 2 new functions to return mass diffusivity in hePsiThermo class as following: Code:
template<class BasicPsiThermo, class MixtureType> Foam::tmp<Foam::volScalarField> Foam::hePsiThermo<BasicPsiThermo, MixtureType>::Dimix ( label speciei ) const { Info << "******Check Dimix function is called from hePsiThermo or not*********" << endl; Info << "The value of Dimix[i] with ith = " << speciei << " is = " << Dimix_[speciei] << endl; return Dimix_[speciei]; } template<class BasicPsiThermo, class MixtureType> Foam::tmp<Foam::scalarField> Foam::hePsiThermo<BasicPsiThermo, MixtureType>::Dimix ( const label speciei, const label patchi ) const { Info << "******Check Dimix(patchi) function is called from hePsiThermo or not*********" << endl; Info << "******Check in Dimix(i, patchi), index is = " << speciei << " and patchi is = " << patchi << endl; Info << "******Check the number of patchi in Dimix is= " << Dimix_[speciei].boundaryField().size() << endl; return Dimix_[speciei].boundaryField()[patchi]; } Code:
//- store list of mass diffusion coefficients PtrList<volScalarField> Dimix_; Code:
Dimix_(MixtureType::numberOfSpecies()); forAll(Dimix_, i) { Dimix_.set ( i, new volScalarField ( IOobject ( this->phasePropertyName("thermo:Dimix"), mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionSet(0, 2, -1, 0, 0) ) ); } The compilation was fine. But I got Segmentation fault when running reactingFoam solver even though I did not call any new function Dimix(speciei) or Dimix(speciei, patchi) like this: Code:
Starting time loop Courant Number mean: 2.73659e-05 max: 0.0017574 deltaT = 1.19999e-06 Time = 1.19999e-06 diagonal: Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0 ******Check Dimix(patchi) function is called from hePsiThermo or not********* ******Check in Dimix(i, patchi), index is = 47721810817392 and patchi is = 21400536 #0 Foam::error::printStack(Foam::Ostream&) at ??:? #1 Foam::sigSegv::sigHandler(int) at ??:? #2 ? in "/lib64/libc.so.6" #3 Foam::UPtrList<Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> >::operator[](long) const at ??:? #4 Foam::hePsiThermo<Foam::psiReactionThermo, Foam::SpecieMixture<Foam::mixReactingMixture<Foam::chungTransport<Foam::species::thermo<Foam::realJanafThermo<Foam::soaveRedlichKwong<Foam::mixSpecie> >, Foam::sensibleEnthalpy> > > > >::Dimix(long, long) const at ??:? #5 Foam::combustionModels::laminar<Foam::psiReactionThermo>::R(Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>&) const at ??:? #6 ? at ??:? #7 __libc_start_main in "/lib64/libc.so.6" #8 ? at ??:? Segmentation fault As far as I know this caused when a program tries to access memory outside its bounds. But I don't understand why even though I did not call Dimix(speciei, patchi) function while the program seems to be passed by a random value of speciei into this function. Does anyone know what the reason of this behavior could be? Thanks in advance for your help. |
|
September 6, 2020, 14:51 |
|
#2 |
Senior Member
Tom-Robin Teschner
Join Date: Dec 2011
Location: Cranfield, UK
Posts: 204
Rep Power: 16 |
well, let's look at the stack trace (helpful for future debugging as well):
Code:
#0 Foam::error::printStack(Foam::Ostream&) at ??:? #1 Foam::sigSegv::sigHandler(int) at ??:? #2 ? in "/lib64/libc.so.6" #3 Foam::UPtrList<Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> >::operator[](long) const at ??:? #4 Foam::hePsiThermo<Foam::psiReactionThermo, Foam::SpecieMixture<Foam::mixReactingMixture<Foam::chungTransport<Foam::species::thermo<Foam::realJanafThermo<Foam::soaveRedlichKwong<Foam::mixSpecie> >, Foam::sensibleEnthalpy> > > > >::Dimix(long, long) const at ??:? #5 Foam::combustionModels::laminar<Foam::psiReactionThermo>::R(Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>&) const at ??:? #6 ? at ??:? #7 __libc_start_main in "/lib64/libc.so.6" #8 ? at ??:? Segmentation fault So then the next thing you want to look at is what is the error. In this case it is a segmentation fault which is pretty much always memory related (from the top of my head I can't come up with any example where that would not be the case but others may come up with examples here where that would not be memory related). So, now we know where to look and what to look for. You're function that is called looks like this: Code:
template<class BasicPsiThermo, class MixtureType> Foam::tmp<Foam::scalarField> Foam::hePsiThermo<BasicPsiThermo, MixtureType>::Dimix ( const label speciei, const label patchi ) const { Info << "******Check Dimix(patchi) function is called from hePsiThermo or not*********" << endl; Info << "******Check in Dimix(i, patchi), index is = " << speciei << " and patchi is = " << patchi << endl; Info << "******Check the number of patchi in Dimix is= " << Dimix_[speciei].boundaryField().size() << endl; return Dimix_[speciei].boundaryField()[patchi]; } There are two possibilities here: 1.) Within the R function, we already passed garbage into the Dimixfunction (which means that something went wrong there and we need to spend our debugging effort on that function) or 2.) We pass the values correctly into the hePsiThemro class but the compiler is doing a conversion in the back for us, for example from a signed to an unsigned int. At compile time there is no error because we only know at runtime the values so the compiler can not make a check for that and thus will not complain. This is likely the error here. To illustrate point 2, consider the following example: Code:
#include <iostream> void print(unsigned short i) { std::cout << "i is: " << i << std::endl; } int main() { print(27); // OK, prints 27 which is less then 65535 print(65537); // also OK, but now prints 1, due to stack overflow return 0; } In this case you need to make sure that the variables passed to Dimixare the same as in the R function (i.e. you define both here as a lable, are they also defined in R the same way?) Looking at stack frame 4, the values passed in are Dimix(long, long), so my best guess here is that label is not equal to long on your machine. Quite lengthy, I admit (I might be wrong), well, but hope this is helpful anyways ... |
|
September 6, 2020, 22:14 |
|
#3 |
New Member
Nam Danh Nguyen
Join Date: Feb 2020
Location: UNIST-Ulsan-Korea
Posts: 25
Rep Power: 6 |
Hi Tom!
Thank you so much for your helpful explanation. Well, I have checked the function R as your suggestion. But it might not be the possibilities 2 because I could not see the relation or the argument that could pass the parameter into my new Dimix function. This is the code of function R in laminar class. Where R is a function returns the fuel consumption rate matrix based on the name of species. hePsiThermo class including new functions Dimix(speciei) and Dimix(speciei, patchi) is the derived class of ReactionThermo in this case. Code:
template<class ReactionThermo> Foam::tmp<Foam::fvScalarMatrix> Foam::combustionModels::laminar<ReactionThermo>::R(volScalarField& Y) const { Info << "*****Check R function is called from laminar class or not ****" << endl;//Nam tmp<fvScalarMatrix> tSu(new fvScalarMatrix(Y, dimMass/dimTime)); Info << "*****Check in R function - after make tSu ****" << endl; //Nam fvScalarMatrix& Su = tSu.ref(); Info << "*****Check in R function - after make Su ****" << endl; //Nam if (this->active()) { Info << "*****Check in R function - after active ****" << endl; //Nam Info << "*****Check in R function - Y.member() = " << Y.member() << endl; //Nam const label specieI = this->thermo().composition().species()[Y.member()]; Info << "check specieI in laminar class is = " << specieI << endl; //Nam Su += this->chemistryPtr_->RR(specieI); } return tSu; } Code:
Starting time loop Courant Number mean: 2.73659e-05 max: 0.0017574 deltaT = 1.19999e-06 Time = 1.19999e-06 diagonal: Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0 *****Check R function is called from laminar class or not **** *****Check in R function - after make tSu **** *****Check in R function - after make Su **** *****Check in R function - after active **** *****Check in R function - Y.member() = O2 ******Check Dimix(patchi) function is called from hePsiThermo or not********* ******Check in Dimix(i, patchi), index is = 47272830693744 and patchi is = 32541656 #0 Foam::error::printStack(Foam::Ostream&) at ??:? #1 Foam::sigSegv::sigHandler(int) at ??:? #2 ? in "/lib64/libc.so.6" #3 Foam::UPtrList<Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> >::operator[](long) const at ??:? #4 Foam::hePsiThermo<Foam::psiReactionThermo, Foam::SpecieMixture<Foam::mixReactingMixture<Foam::chungTransport<Foam::species::thermo<Foam::realJanafThermo<Foam::soaveRedlichKwong<Foam::mixSpecie> >, Foam::sensibleEnthalpy> > > > >::Dimix(long, long) const at ??:? #5 Foam::combustionModels::laminar<Foam::psiReactionThermo>::R(Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>&) const at ??:? #6 ? at ??:? #7 __libc_start_main in "/lib64/libc.so.6" #8 ? at ??:? Segmentation fault Code:
const label specieI = this->thermo().composition().species()[Y.member()]; One more interesting thing here is the values of speicei and patchi are passed differ from time to time. Code:
******Check in Dimix(i, patchi), index is = 47562861859184 and patchi is = 44112856 ******Check in Dimix(i, patchi), index is = 47948489318768 and patchi is = 19065816 ******Check in Dimix(i, patchi), index is = 46943863427440 and patchi is = 26770392 Once again, Thank you so much for your time. |
|
September 7, 2020, 01:30 |
|
#4 |
Senior Member
Tom-Robin Teschner
Join Date: Dec 2011
Location: Cranfield, UK
Posts: 204
Rep Power: 16 |
Getting different values for these variables is a clear sign that the memory for them has not been allocated and they are reading whatever variable (garbage) they find at that memory address when they are accidentally called.
This line Code:
const label specieI = this->thermo().composition().species()[Y.member()]; Code:
Info << "***** Temp 1 *****" << endl; const auto temp1 = this->thermo(); Info << "***** Temp 2 *****" << endl; const auto temp2 = temp1.composition(); Info << "***** Temp 3 *****" << endl; const auto temp3 = temp2.species(); Info << "***** Temp 4 *****" << endl; const auto temp 4 = temp3[Y.member()]; Code:
Info << "***** Temp 1 *****" << endl; auto temp1 = this->thermo(); Info << "***** Temp 2 *****" << endl; auto temp2 = temp1.composition(); Info << "***** Temp 3 *****" << endl; auto temp3 = temp2.species(); Info << "***** Temp 4 *****" << endl; auto temp 4 = temp3[Y.member()]; |
|
September 7, 2020, 02:15 |
|
#5 |
New Member
Nam Danh Nguyen
Join Date: Feb 2020
Location: UNIST-Ulsan-Korea
Posts: 25
Rep Power: 6 |
Hi Tom!
Thank you for your help. I am going to try to print more information about related classes and check your suggestions. I will let you know the results. Thanks you so much! |
|
September 7, 2020, 08:27 |
|
#6 |
New Member
Nam Danh Nguyen
Join Date: Feb 2020
Location: UNIST-Ulsan-Korea
Posts: 25
Rep Power: 6 |
Dear Tom!
I did try to add some lines of code as your suggestion but it seems to be not in that way. Compiler complained like this (the reason was clearly shown in the message): Code:
PaSR/../laminar/laminar.C: In member function ‘virtual Foam::tmp<Foam::fvMatrix<double> > Foam::combustionModels::laminar<ReactionThermo>::R(Foam::volScalarField&) const’: PaSR/../laminar/laminar.C:148:21: error: expected initializer before numeric constant const auto temp 4 = temp3[Y.member()]; ^ PaSR/../laminar/laminar.C: In instantiation of ‘Foam::tmp<Foam::fvMatrix<double> > Foam::combustionModels::laminar<ReactionThermo>::R(Foam::volScalarField&) const [with ReactionThermo = Foam::rhoReactionThermo; Foam::volScalarField = Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh>]’: PaSR/PaSRs.C:40:1: required from here PaSR/../laminar/laminar.C:142:37: error: cannot allocate an object of abstract type ‘Foam::rhoReactionThermo’ const auto temp1 = this->thermo(); ^ First I commented out 2 new Dimix(speciei) and Dimix(speciei, patchi) functions while remaining declaration and updating part of Dimix_ data member. The error disappeared. Then I made a new simple function to return just a scalar like this: Code:
virtual scalar Di(label speciei) const { Info << "*******Check Di(i) is called from psiThermo or not*******" << endl; Info << "Di[i] with ith = " << speciei << " is :" << endl; return 1; } This would means that whenever I put a any new function (I did tried with different returing Type) the program was crashed. Actually by this line of code: Code:
const label specieI = this->thermo().composition().species()[Y.member()]; It's not by the PtrList itself. Now I need to track back some function like thermo() in combustionModel classes, composition() in heThermo and species() in MixtureType to see what going on. I also draw an incomplete diagram to show how solver and classes that I am dealing with interface together for everyone can easier understand my case. https://ibb.co/dGY3BQx And pls let's me know if you have any idea about the possiblilities when you look at the above class diagram interface. And for others, any comment about this problem would be appreciated. Thank you so much! |
|
September 7, 2020, 10:12 |
|
#7 |
New Member
Nam Danh Nguyen
Join Date: Feb 2020
Location: UNIST-Ulsan-Korea
Posts: 25
Rep Power: 6 |
Dear Tom and everyone!
I am very happy to say that I have solved my problem. The reason is very simple. It can be seen in the class diagram posted above that combustionModel classes are based on Thermo Classes e.g., psiThermo, psiReactionThermo ... After I develop these class, I should connect them with combustionModel lib and compile this lib again. But I did not. So That why when I run the solver, there was a conflict in these libraries. It's my careless. Solution is modifying Make/options file of combustionModel as following to make sure it is updated based on modified Thermo classes: Code:
EXE_INC = \ -I$(WM_PROJECT_USER_DIR)/src/transportModels/compressible/lnInclude \ -I$(WM_PROJECT_USER_DIR)/src/thermophysicalModels/basic/lnInclude \ -I$(WM_PROJECT_USER_DIR)/src/thermophysicalModels/specie/lnInclude \ -I$(WM_PROJECT_USER_DIR)/src/thermophysicalModels/reactionThermo/lnInclude \ -I$(WM_PROJECT_USER_DIR)/src/thermophysicalModels/chemistryModel/lnInclude \ -I$(WM_PROJECT_USER_DIR)/src/TurbulenceModels/turbulenceModels/lnInclude \ -I$(WM_PROJECT_USER_DIR)/src/TurbulenceModels/compressible/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude LIB_LIBS = \ -L$(FOAM_USER_LIBBIN) \ -lcompressibleTransportModels \ -lturbulenceModels \ -lcompressibleTurbulenceModels \ -lchemistryModel \ -lfiniteVolume \ -lmeshTools This library would be published soon. Thank you all for your time. |
|
September 7, 2020, 15:17 |
|
#8 |
Senior Member
Tom-Robin Teschner
Join Date: Dec 2011
Location: Cranfield, UK
Posts: 204
Rep Power: 16 |
Good to hear you managed to fix it. This sound like an annoying error (typically you would get an "undefined reference" error at runtime if you don't compile against the required library). But that explains why you seemingly never called the function but still got a segmentation fault. Thanks for sharing the solution, might be of value for someone else in the future.
__________________
Learn to write CFD solvers at cfd.university |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
whats the cause of error? | immortality | OpenFOAM Running, Solving & CFD | 13 | March 24, 2021 07:15 |
[mesh manipulation] RefineMesh Error and Foam warning | jiahui_93 | OpenFOAM Meshing & Mesh Conversion | 4 | March 3, 2018 11:32 |
Temperature linearly rising after restarting a simulation | Gennaro | OpenFOAM Programming & Development | 2 | September 2, 2014 07:58 |
Problem with compile the setParabolicInlet | ivanyao | OpenFOAM Running, Solving & CFD | 6 | September 5, 2008 20:50 |
Droplet Evaporation | Christian | Main CFD Forum | 2 | February 27, 2007 06:27 |