| Summary: | Code error in G4ExcitationHandler.cc | ||
|---|---|---|---|
| Product: | Geant4 | Reporter: | Tom Roberts <tjrob> |
| Component: | processes/hadronic/models/de_excitation/handler | Assignee: | alexander.howard |
| Status: | RESOLVED FIXED | ||
| Severity: | major | CC: | alexander.howard, porosev |
| Priority: | P5 | ||
| Version: | 8.3 | ||
| Hardware: | All | ||
| OS: | All | ||
Could you include a description of the situation which reproduces this problem - there are a number of possible fixes but we should verify that it's successful. Thanks, Alex This occurs when tracking charged particles through matter, running wih G4SYSTEM=WIN32-VC. This routine is called by photon evaporation. This is stochastic: several of my simulations run 10,000 events without crashing. One simulation crashes on event # 5, but not again until some event # > 1000 -- this simulation has 10 GeV/c protons entering a carbon target 50 mm in radius and 1,000 mm long; the target is along the axis of a 20 T solenoid; physics=QGSP_BIC. This _is_ a clear coding error: decrementing a std::list<>::iterator from begin() is documented as undefined behavior. Apparently g++ does something different from VC++, as it does not crash on any of my simulations, for G4SYSTEM = Linux-g++, Darwin-g++, or Windows-g++. Note, however, that I have NOT verified that with g++ it executes the loop correctly, just that it does not crash. Note that I am really using Geant4.8.2, but this file is unchanged in 8.3, so I reported the bug in the latter release. *** Problem 944 has been marked as a duplicate of this problem. *** This code is now corrected and will be in Geant4 release 9.0 (end of June 2007). Can be supplied if required before. |
On WIN32-VC, the following coding error generates a General Protection Fault by attempting to dereference a null pointer within the STL::list<> class. This is a VERY flaky problem, and only appears occasionally for some simulations, and not at all for others. File G4ExcitationHandler.cc (loop at line 215): std::list<G4Fragment*>::iterator j; for (j = theResultList.begin(); j != theResultList.end(); j++) { if( /* some test */) { // some code delete(*j); theResultList.erase(j--); // some code not using j } else { // some code that uses j } } Clearly j can be decremented to point "previous" to begin(), which is undefined. Apparently on gcc it is OK (well, does not generate a fault, but I have no idea if it runs correctly). On Windows, VC++ generates a fault, at least if the list becomes empty from the erase(). This avoids the fault, BUT CHANGES THE LOGIC: // replace the above delete and erase() with: theResultList.erase(j); delete *j; if(theResultList.size() == 0) break; j--; While that permits my simulation to execute, I believe it can omit generating some secondaries, so an expert on this process needs to look at it. I recommend changing that std::list<> to a std::vector<> and using an integer to index the vector -- an integer can be validly decremented to point before the start and then incremented before next use; an iterator cannot. NOTE -- on WIN32-VC you must also implement the workaround to the compiler bug I reported in the "Installation and Configuration" forum thread 865.