Problem 597 - Segmentation violation in G4NavigationHistory.icc due to index out of bounds
Summary: Segmentation violation in G4NavigationHistory.icc due to index out of bounds
Status: RESOLVED FIXED
Alias: None
Product: Geant4
Classification: Unclassified
Component: geometry/volumes (show other problems)
Version: 6.0
Hardware: All All
: P2 critical
Assignee: Gabriele Cosmo
URL:
Depends on:
Blocks:
 
Reported: 2004-03-02 10:40 CET by azoglauer
Modified: 2004-03-04 01:11 CET (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 azoglauer 2004-03-02 10:40:20 CET
Hello,


For the following I assume Geant4.6.0-p01 on a Linux machine.

I have a highly nested geometry (> 20 volumes), which leads to a segmentation
violation in the class G4NavigationLevel at line 196:

inline
void G4NavigationHistory::NewLevel( G4VPhysicalVolume *pNewMother,
                                    EVolume vType,
                                    G4int nReplica )
{
        EnlargeHistory();  // Enlarge if required
        fStackDepth++;
l.196   fNavHistory[fStackDepth] =
        G4NavigationLevel( pNewMother,
                       fNavHistory[fStackDepth-1].GetTransform(),
                       G4AffineTransform(pNewMother->GetRotation(),
                       pNewMother->GetTranslation()),
                       vType,
                       nReplica );
        // The constructor computes the new global->local transform
}

In my program, index fStackDepth=16 (17th element!) where the size of
fNavHistory is only 16 elements, which causes the segmentation violation.

The reason for this is in the function EnlargeHistory():

inline
void G4NavigationHistory::EnlargeHistory()
{
        G4int len = fNavHistory.size();
l.179   if ( len==fStackDepth )
        {
          // Note: Resize operation clears additional entries
          //
          G4int nlen = len+kHistoryStride;
          fNavHistory.resize(nlen);
        }
}

fNavHistory is increased only if  fNavHistory.size()==fStackDepth (l.178). In my
example, in NewLevel(...) before the call of EnlargeHistory()
fNavHistory.size()=16 and fStackDepth=15, so no increase is necessary. But then
(l.195) fStackdepth is increased and fNavHistory[fStackDepth] leads to a
segmentation violation.

So the solution would be, to simply exchange the lines EnlargeHistory() and
fStackDepth++:

inline
void G4NavigationHistory::NewLevel( G4VPhysicalVolume *pNewMother,
                                    EVolume vType,
                                    G4int nReplica )
{
  fStackDepth++;
  EnlargeHistory();  // Enlarge if required
  fNavHistory[fStackDepth] =
    G4NavigationLevel( pNewMother,
                       fNavHistory[fStackDepth-1].GetTransform(),
                       G4AffineTransform(pNewMother->GetRotation(),
                       pNewMother->GetTranslation()),
                       vType,
                       nReplica );
  // The constructor computes the new global->local transform
}

This solution worked flawlessly on SuSE 9.0.

This bug did probably not appear up to now, since per default fNavHistory has a
size of 16 and geometries with with more than 16 nested volumes are probably rare.

Let me know in which Geant version this will be fixed

Ciao,
Andreas Zoglauer
Comment 1 Gabriele Cosmo 2004-03-04 01:10:59 CET
Thanks for the report and the proposed solution. The fix has now been included
in the development tag "geomvol-V06-00-01" and will be provided in the next
patch or minor release of the toolkit.