| Summary: | out of bounds lookup in G4SeltzerBergerModel::ReadData | ||
|---|---|---|---|
| Product: | Geant4 | Reporter: | Chris Pinkenburg <pinkenburg> |
| Component: | processes/electromagnetic/standard | Assignee: | Vladimir.Ivantchenko |
| Status: | RESOLVED FIXED | ||
| Severity: | minor | ||
| Priority: | P4 | ||
| Version: | 10.4 | ||
| Hardware: | All | ||
| OS: | All | ||
sorry this source was from 10.02.p02, 10.04.p02 should loke like this, replace:
if(v->Retrieve(fin)) {
if(useBicubicInterpolation) { v->SetBicubicInterpolation(true); }
dataSB[Z] = v;
static const G4double emaxlog = 4*G4Log(10.);
ylimit[Z] = v->Value(0.97, emaxlog, idx, idy);
} else {
by
if(v->Retrieve(fin)) {
if(useBicubicInterpolation) { v->SetBicubicInterpolation(true); }
dataSB[Z] = v;
static const G4double emaxlog = 4*G4Log(10.);
// check if cached idx/idy is inside of bounds, if not reset to 0
// to be safe
if (idx > v->GetLengthX()-2)
{
idx = 0;
}
if (idy > v->GetLengthY()-2)
{
idy = 0;
}
ylimit[Z] = v->Value(0.97, emaxlog, idx, idy);
} else {
Hello, thank you very much for the detailed report on the problem. The problem is fixed and the fix will be available in the next public release of Geant4. Vladimir |
valgrind flagged an invalid read in G4Physics2DVector.icc called by this method: ==25172== Invalid read of size 8 ==25172== at 0x1CD71EF7: FindBin (G4Physics2DVector.icc:114) ==25172== by 0x1CD71EF7: FindBinLocationX (G4Physics2DVector.icc:123) ==25172== by 0x1CD71EF7: G4Physics2DVector::Value(double, double, unsigned long&, unsigned long&) const (G4Physics2DVector.cc:166) ==25172== by 0x1A7146D4: G4SeltzerBergerModel::ReadData(int, char const*) (G4SeltzerBergerModel.cc:175) It's been doing this for the last few versions, normally we work with 10.02.p02.This here is for the latest version 10.04.p02. The underlying reason is some caching in G4SeltzerBergerModel of the x/y index (idx, idy) of an array which is being read in where the previous lookup of a fixed number succeeded (in G4Physics2DVector::FindBin()). First the value is compared to the first and last entry (1 to idxmax-2), if it is within this range the cached index (idx) is used for an initial guess of the correct array index to save time for the lookup (it works most of the time). That works beautifully until the array is smaller and those initial lookups are out of bounds. The value z is inside the array but the lookup for the initial guess is out of bounds: if(z < v[idx] || z >= v[idx+1]) This happens for the data files GEMLOW6.48/brem_SB/br94 and GEMLOW6.48/brem_SB/br97 where the maximum indices are 14 in x and 31 in y but cached index is 22 and 55. Since the value of z is most likely not between the values of these random memory locations which then forces lookup, the results are very unlikely to be affected. The path for this would be to compare the value of idx and idy to the number of entries in the array: replacing: if(v->Retrieve(fin)) { if(useBicubicInterpolation) { v->SetBicubicInterpolation(true); } dataSB[Z] = v; ylimit[Z] = v->Value(0.97, emaxlog, idx, idy); } else { by if(v->Retrieve(fin)) { if(useBicubicInterpolation) { v->SetBicubicInterpolation(true); } dataSB[Z] = v; // check if cached idx/idy is inside of bounds, if not reset to 0 // to be safe if (idx > v->GetLengthX()-2) { idx = 0; } if (idy > v->GetLengthY()-2) { idy = 0; } ylimit[Z] = v->Value(0.97, emaxlog, idx, idy); }