Can you run in gdb or lldb to track down what’s happening/where the hang might be occurring. You could also try increasing the verbosity of Run/Event (/run/verbose, /event/verbose UI commands) as a first step.
...
G4WT6 > output pointer: 0x11f6786a0
G4WT4 > NULL returned from G4StackManager.
G4WT4 > Terminate current event processing.
G4WT4 > output pointer: 0x1208e73c0
...
Multiple output class copies are created. I guess it makes sense to have one output class object for each thread. But I don’t know how a singleton works in multi-thread mode…
What kind of things I need to pay attention to to make my custom output functions thread-safe?
The other option here would be to use a concrete G4UserSteppingAction as that shouldn’t require any special treatment, though it depends on exactly what your use case for recording/etc steps is.
G4UserSteppingAction does not have access to step 0 information, while G4SteppingVerbose does. I’m happy to switch if the behavior of G4UserSteppingAction is modified in Geant4.
It might also be possible to use a tracking action, as its PreUserTrackingAction is called immediately after SetInitialStep (see G4TrackingManager::ProcessOneTrack for details of the ordering). At least, that gives access to the track immediately, though a separate SteppingAction would also be needed.
Alternately, see the extended/field/field01 example for one that implements a custom stepping verbose, and in particular the use of the F01ActionInitialization::InitializeSteppingVerbose class/member function. That should allow per-thread instances of a concrete steppingverbose to be created.