Double Free or Corruption Occurs During L1ActionInitialization Destruction

My program runs and executes the macro script correctly, but I notice that every time it finishes, it reports a “double free or corruption” error.

To ensure that objects are properly deleted, I added log messages like
G4cout << "L1SteppingAction destroyed" << G4endl;
in the destructor sections of all .cc files.

In multithreaded runs, I observe that all threads correctly destroy their instances of PrimaryGenerator, Event, and SteppingAction, and the main thread’s DetectorConstruction is also released correctly (only deleted once). However, ActionInitialization does not print the destruction message or get released normally; instead, it crashes directly with the error:
“double free or corruption (!prev) Aborted (core dumped)”.

What’s going on here? I’m sure that none of my destructors do anything other than closing file streams (and I even commented all those out, leaving the destructors empty), but the issue still occurs.

My L1ActionInitialization.hh and L1ActionInitialization.cc source files are shown below.
L1ActionInitialization.hh:


#ifndef L1ActionInitialization_h
#define L1ActionInitialization_h 1

#include "G4VUserActionInitialization.hh"

/// Action initialization class.

class L1DetectorConstruction;
class L1RunAction;
class L1ActionInitialization : public G4VUserActionInitialization
{
  public:
    L1ActionInitialization();
    virtual ~L1ActionInitialization();
    virtual void BuildForMaster() const ;
    virtual void Build() const ;
private:
};

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

#endif

L1ActionInitialization.cc:

#include "L1ActionInitialization.hh"
#include "L1PrimaryGeneratorAction.hh"
#include "L1RunAction.hh"
#include "L1EventAction.hh"
#include "L1SteppingAction.hh"
#include "L1DetectorConstruction.hh"
#include "G4RunManager.hh" 

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

L1ActionInitialization::L1ActionInitialization()
 : G4VUserActionInitialization()
	{
	}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

L1ActionInitialization::~L1ActionInitialization()
{  G4cout << "L1ActionInitialization destroyed" << G4endl;}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void L1ActionInitialization::BuildForMaster() const
{
  L1RunAction* runAction = new L1RunAction;
  SetUserAction(runAction);
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void L1ActionInitialization::Build() const
{    const auto* fDetConstruction = static_cast<const L1DetectorConstruction*>(G4RunManager::GetRunManager()->GetUserDetectorConstruction());
auto runAction = new L1RunAction;
    SetUserAction(runAction);
      auto eventAction = new L1EventAction(runAction);
  SetUserAction(eventAction);
   auto primaryGeneratorAction = new L1PrimaryGeneratorAction(fDetConstruction,runAction,eventAction);
    SetUserAction(primaryGeneratorAction);
   auto steppingAction = new L1SteppingAction(fDetConstruction, eventAction,runAction);
    SetUserAction(steppingAction);
}


_Geant4 Version:_10.7.3
_Operating System:_Ubuntu 20.04
Compiler/Version:
_CMake Version:_3.16.3


There’s nothing obvious from the code posted. Have you run the application through a debugger like gdb to trace where the double free occurs? This should give a clearer indication of where the problem lies.

The results of the gdb operation are as follows:

double free or corruption (!prev)
Thread 1 “array1” received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: no such file or directory
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff5178859 in __GI_abort () at abort.c:79
#2 0x00007ffff51e3266 in __libc_message (action=action@entry=do_abort,
fmt=fmt@entry=0x7ffff530d298 “%s\n”) at ../sysdeps/posix/libc_fatal.c:156
#3 0x00007ffff51eb2fc in malloc_printerr (
str=str@entry=0x7ffff530f690 “double free or corruption (!prev)”)
at malloc.c:5347
#4 0x00007ffff51ecfac in _int_free (av=0x7ffff5342b80 <main_arena>,
p=0x5555559942e0, have_lock=) at malloc.c:4317
#5 0x00007ffff79989aa in G4RunManager::DeleteUserInitializations() ()
from /home/geant4/geant4/geant4-install/lib/libG4run.so
#6 0x00007ffff7999c06 in G4RunManager::~G4RunManager() ()
from /home/geant4/geant4/geant4-install/lib/libG4run.so
#7 0x00007ffff79a02ad in G4MTRunManager::~G4MTRunManager() ()
from /home/geant4/geant4/geant4-install/lib/libG4run.so
#8 0x000055555555d7cc in main ()