I’m trying to use gdb debugger to debug an error related to
Segmentation fault (core dumped)
Unfortunately, this message happens frequently for many different types of errors, also completely not correlated (bad pointer definition, out of memory, etc.). With gdb debugger, I get this message more specific:
Thread 10 "essn" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd1ffb700 (LWP 2001485)]
0x000000000042655a in NewSensitiveDetector::ProcessHits(G4Step*, G4TouchableHistory*) ()
Inside ProcessHits, the reasons of the bug could be different and I would like to know if there is a way to get more specific details of the error, considering that I’m spending significant time to find the bug here.
Any practical suggestion on how to use gdb (or other debugger) would be really appreciate.
Thanks in advance for your time.
PS: I’m asking practical suggestions, considering that the manual of gdb is very disracting with more than 600 pages.
Many problems like this can be tracked down in
gdb with the
bt (backtrace) command. That should give enough information to track down the function/location causing the issue. Breakpoints (
break command) can then be set, say at the start of the “bad” function to stop execution at that point. Finally,
step and similar can be used to continue execution line-by-lines from the break to track down the exact statement.
Arguments to those can help get more detail, and the program should be compiled in Debug mode to ensure things like line numbers/values are recorded.
I’m not sure these are what you mean by “practical” but there are also many online tutorials that will walk through typical sessions in more detail.
Thank you @bmorgan very much for your reply. I would ask another information, please: how can I compile Geant4 in debug mode?
Thank you very much for your time.
In your build directory, use the command
cmake -DCMAKE_BUILD_TYPE=Debug .
make clean install
The “.” at the end ensures that CMake will reuse the same configuration you set up previously (same source dir, same install dir, same options), and just switch the one option you list. The
make command uses “clean” to ensure that it recompiles everything, so you’ll get all the debugging symbols.
Note that a debug build can take up a lot more disk space than a “Release” build (the default).
Thank you very much for your answer. Before I was compiling in the following way:
cmake -DGeant4_DIR=/projects/Geant4/geant4.10.07/ ../ && make -j4
Considering your suggestion, I’ve been able to compile in debugging mode with this command:
cmake -DGeant4_DIR=/projects/Geant4/geant4.10.07/ -DCMAKE_BUILD_TYPE=Debug ../ && make -j4
I used gdb debugger and it seems that it works correctly by employing breakpoints, layout, etc.
If you have other suggestions to improve the debugging of Geant4, also using other tools, they are welcome. Thank you again for your time!
Slightly unrelated to your original question regarding the practicalities with regard to the gdb debugger but did you find out what caused the error? I sometimes get the same error when running my code multithreaded and looking at gdb. Before investing more of my time into debugging I searched for similar experiences and found this question.
Yes, I found that the error was related when I called
GetPreStepPoint from a boundary surface at the limit of the world geometry. For some reason, by calling
GetPreStepPoint->GetTouchableHandle()-> GetVolume () -> GetName ();, it allows to give an error since it seems that at this geometrical point, G4StepPoint is not associated to any physical detector.
In general, the error message
Thread 10 "input" received signal SIGSEGV, Segmentation fault.
can have many causes, as pointer definition or memory usage. Since this error message is too general, it is the reason why I’ve found the debugging of Geant4 so hard. Unfortunately, also searching around, I didn’t found a documentation that explains how to debug Geant4 in an efficient way.
The error message is generic because it is coming from the underlying operating system, not the application. That’s not Geant4’s fault, it’s the fault of the user application. In general, you should always check for a valid pointer before dereferencing it.
In this instance, I presume that your segfault happened bcause
preStepPoint->GetTouchableHandle() returned null. That’s something you should check before dereferencing it.
There are certainly well-defined cases in Geant4 where a null pointer return is “expected”, or at least indicates a known situation. For instance, a primary track will always return null for the creator process.
In addition to Mike’s answer. In gdb one can find null pointer dereferences by printing the pointer, e.g.
(gdb) p preStepPoint->GetTouchableHandle()
Ok, perfect! Thank you very much for your suggestion and information!
Thank you very much for your advise!