Problem 2230 - Visual Studio Debug multithreaded build crashes in G4LossTableBuilder constructor
Summary: Visual Studio Debug multithreaded build crashes in G4LossTableBuilder constru...
Status: RESOLVED FIXED
Alias: None
Product: Geant4
Classification: Unclassified
Component: processes/electromagnetic (show other problems)
Version: 10.6
Hardware: All Windows
: P4 normal
Assignee: Vladimir.Ivantchenko
URL:
Depends on:
Blocks:
 
Reported: 2020-02-19 08:39 CET by Sergio Losilla
Modified: 2020-05-01 13:42 CEST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this problem.
Description Sergio Losilla 2020-02-19 08:39:05 CET
On G4LossTableBuilder.cc line 97, non-master threads attempt to unlock a mutex that was never locked, which is undefined behavior and causes this type of build to crash.

The Geant4 version tested was 10.6.1, with Visual Studio 16.4.5.

The affected code looks like this:

G4LossTableBuilder::G4LossTableBuilder(G4bool master) : isMaster(master) 
{
  theParameters = G4EmParameters::Instance();
  splineFlag = true;
  isInitialized = false;
  if(isMaster || !theFlag) {
#ifdef G4MULTITHREADED
    G4MUTEXLOCK(&ltbMutex);
    if(isMaster || !theFlag) {
#endif
      isMaster = true;
      theDensityFactor = new std::vector<G4double>;
      theDensityIdx = new std::vector<G4int>;
      theFlag = new std::vector<G4bool>;
    } else {
      isMaster = false; <--- This line is never hit in multithreaded builds
    }
#ifdef G4MULTITHREADED
  }
  G4MUTEXUNLOCK(&ltbMutex); <---- CRASH
#endif
}

I am not quite sure what is supposed to happen, but if G4MULTITHREADED is defined the code can be simplified to this:

G4LossTableBuilder::G4LossTableBuilder(G4bool master) : isMaster(master) 
{
  theParameters = G4EmParameters::Instance();
  splineFlag = true;
  isInitialized = false;
  if(isMaster || !theFlag) {
    G4MUTEXLOCK(&ltbMutex);
    isMaster = true;
    theDensityFactor = new std::vector<G4double>;
    theDensityIdx = new std::vector<G4int>;
    theFlag = new std::vector<G4bool>;
  }
  G4MUTEXUNLOCK(&ltbMutex);
}

So if isMaster is false, this will result in undefined behavior. Also, note that the line "isMaster = false" is never hit for multithreaded builds.
Comment 1 Vladimir.Ivantchenko 2020-05-01 13:42:04 CEST
Hello,

thank you very much for this post. The bug is fixed, included in the Geant4 development version, and will be available with the public release.

VI