Introduction to debugging
To debug the code we recommend using:
- valgrind (also with alleyoop)
- kcachegrind (requries callgrind tool from valgrind to run)
- ddd, gdb
- kompare, kdiff3
Compile with debug information
Before doing any debugging you must make sure that yade is compiled with debug information (check installation instructions)
When yade is compiled with debug information all its files will be much bigger (like 50 times bigger) than without debug info, resulting in around 100MB in total.
Debugging with iostream
A very simple method is putting
std::cerr << "x= " << x << "\n";
here and there. And in fact I like this method more than kdevelop's builtin debugger, because this method encourages thinking. While built-in debugger does not. You just click, and forget to think.
Debugging with Data Display Debugger
DDD, the Data Display Debugger allows not only to display the values of debugged variables, but also to plot them using interactive graphical data display, where data structures are displayed as graphs. Just take a look at the screenshots on the bottom of ddd's webpage. To use it, simply run:
DDD may be an interesting option when debuuging the code. A very nice feature is that it allows to undo last debugging action.
YADE_PTR_CAST), they expand to
static_ptr_cast) in optimized build and to
dynamic_ptr_cast) in debug build. Dynamic casts are slower, but they will throw if the conversion is invalid. Static cast are fast, but may make debugging very difficult.
- Use standard
static_castwhere you are sure that the cast is valid.
- use standard
dynamic_castif you need to make decisions based on the result of conversion.
In debug build, yade will run debugger if there are "segmentation fault" (SEGV) or abort (ABRT, e.g. from failed assertion) signals. It will show you backtrace of all thread, which makes it possible to identify quickly the place where something went wrong. Therefore: in debug mode, always run yade from console. It shows valuable information.
To avoid using things like
cerr<<"a="<<a<<endl; use macros
LOG_FATAL. You can filter messages of severity of your choice, redirect messages to a file etc.
- In your class declaration (in the header file), say
DECLARE_LOGGER;. It will create logger member for your class.
- In your implementation file, say (at the top level):
muPlugin1is the class for which you declared the logger.
- The logger will be called "yade.myPlugin1" and you will be able to filter messages from this logger.
LOG_*macros expand to stream, therefore you can say
LOG_WARN("Distance is negative ("<<distance"<<), resetting to zero.");
(This will work fully only if you compile with log4cxx (default), but will still work somewhat if you dont: TRACE and DEBUG messages will be discarded and all other will be written to standard error.)