Message: Re: Double delete when in MT mode Not Logged In (login)
 Next-in-Thread Next-in-Thread
 Next-in-Forum Next-in-Forum

Idea Re: Double delete when in MT mode 

Forum: Multithreading
Re: None Double delete when in MT mode (Giuseppe Vacanti)
Date: 16 Dec, 2016
From: Michael H. Kelsey <Michael H. Kelsey>

On Thu, 15 Dec 2016 16:50:24 GMT, Giuseppe Vacanti wrote:
> I have converted a G4 application to make use of MT. Now at the end of
> the run I regularly experience a core dump that seems to be due to a
> double delete.

Giuseppe, I recently encountered exactly the same issue myself. The solution (for my case) is straightforward, and it may be relevant to you as well. Do you make use of a G4VUserTrackInformation container, or G4Hits from sensitive detectors? If so, then you probably have classes where you have defined a G4Allocator<...> object, with operator new() and operator delete().

For example, in my application, I have a CDMSTrackInfo class, with the .hh file containing

#ifdef G4TRACK_ALLOC_EXPORT
   extern DLLEXPORT G4Allocator<CDMSTrackInfo> CDMSTrackInfo_Allocator;
#else
  extern DLLIMPORT G4Allocator<CDMSTrackInfo> CDMSTrackInfo_Allocator;
#endif

and inlined implementations of new and delete, e.g.,

inline void* operator new(size_t) {
  return (void*)CDMSTrackInfo_Allocator.MallocSingle();
}

When I moved to building and run in true multithreaded mode (i.e., with G4MTRunManager), I started getting segfaults with the traceback showing a double-delete of this object.

For MT compatibility, this object must be converted to a thread local pointer, with the pointer instantiation happening in operator new(), thus:

#ifdef G4TRACK_ALLOC_EXPORT
   extern DLLEXPORT G4ThreadLocal G4Allocator<CDMSTrackInfo>* CDMSTrackInfo_Allocator;
#else
  extern DLLIMPORT G4ThreadLocal G4Allocator<CDMSTrackInfo>* CDMSTrackInfo_Allocator;
#endif

inline void* operator new(size_t) {
  if (!CDMSTrackInfo_Allocator) CDMSTrackInfo_Allocator = new G4Allocator<CDMSTrackInfo>;
  return (void*)CDMSTrackInfo_Allocator->MallocSingle();
}

and then, in your .cc file, you need to initialize the global pointer to zero:

  G4ThreadLocal G4Allocator<CDMSTrackInfo>* CDMSTrackInfo_Allocator = 0;

This is documented in the MT migration guide (https://twiki.cern.ch/twiki/bin/view/Geant4/QuickMigrationGuideForGeant4V10), including an example showing how to do it for G4Hits (https://twiki.cern.ch/twiki/bin/view/Geant4/QuickMigrationGuideForGeant4V10#ThreadSafety).

Good luck!

      -- Michael Kelsey

 Add Message Add Message
to: "Re: Double delete when in MT mode"

 Subscribe Subscribe

This site runs SLAC HyperNews version 1.11-slac-98, derived from the original HyperNews