GRASS Debugging: Difference between revisions

From GRASS-Wiki
Jump to navigation Jump to search
Line 18: Line 18:
== Using GDB ==
== Using GDB ==


The [http://sourceware.org/gdb/ GNU Debugger] may be used to diagnose <tt>Segmentation Fault</tt>s and other weirdness.
The [http://sourceware.org/gdb/ GNU Debugger] may be used to diagnose '''<tt>Segmentation Fault</tt>'''s and other weirdness.


=== Compile Time Setup ===
=== Compile Time Setup ===

Revision as of 00:24, 7 May 2008

The following hints assume to work on a working-copy of the GRASS CVS directory.

Additionally it is good to have set the debbugging symbols during compile-time. Do not strip the libraries or use optimization in the compile. see INSTALL and doc/debugging.txt in the source code for more information.

Setting GRASS-environment variables (numbers: 1-5)

g.gisenv set="DEBUG=1"
  • A higher debug level means you see more messages.
  • These messages are always present regardless of compiler settings.
  • A setting of "5" is the most verbose, "0" is no debug messages.

Watching top

top is a nice command line utility for watching a process's progression. While it won't give you many hard metrics it will give you an idea of what is happening. To make the view a little more stable, with top running from the command line press "M" to sort by memory usage.

Using GDB

The GNU Debugger may be used to diagnose Segmentation Faults and other weirdness.

Compile Time Setup

To add debugging information into the built binary, add -g to the CFLAGS arguments.

CFLAGS="-ggdb -Wall -Werror-implicit-function-declaration" ./configure ...

Do not use -O for optimization and do not strip the binaries with LDFLAGS="-s".

Using gdb on command line

  • Running a program inside GDB works (installation of GDB required :-)
(e.g. on Debian GNU/Linux: apt-get install gdb)
  • Use the exact module name on the command line (at the GRASS prompt) without arguments. Put any command line arguments on the (gdb) command line after the word run.
 gdb `which v.in.ogr`
 run "out=some_map dsn="PG:dbname=postgis user=me" olayer=postgislayer"
  • when it crashes, type "bt full" for a full backtrace
  • type "l" to list where in the source code it got to
  • type "frame 2" to switch to the second level function (see the backtrace), there you can again type "l" to see where it got up to.

or you can optionally add arguments to gdb directly on the commandline:

 gdb --args v.in.ogr out=bla dsn="PG:dbname=postgis user=me" olayer=postgislayer


  • Attaching to child process:
use "attach <pid>" to attach to an existing process (needed for DBMI debugging etc).
For details, see this hint

Using gdb within GNU Emacs

emacs general/manage/cmd/remove.c
  • create second buffer by C-x 2
  • move cursor to the second buffer by C-x o, then M-x gdb, Enter
  • type module name which you would like to debug, e.g. g.remove, Enter
  • now you can use gdb inside GNU Emacs

Using DDD (gdb graphical frontend)

  • running a program inside DDD works (installation of ddd and gdb required :-), (on Debian GNU/Linux: apt-get install gdb ddd)
ddd `which v.in.ogr`

http://mpa.itc.it/markus/grass61/debugging/crash_1_small.jpg

  • Run (from main menu PROGRAM): "out=bla dsn="PG:dbname=postgis user=me" olayer=postgislayer"

http://mpa.itc.it/markus/grass61/debugging/ddd_1_small.jpg

  • run with parameters
  • when it crashes, use the UP menu item to trace back

http://mpa.itc.it/markus/grass61/debugging/ddd_2_going_up_small.jpg

  • reach the line where it crashed
  • set a breakpoint, then run again to stop before the crash

http://mpa.itc.it/markus/grass61/debugging/ddd_3_breakpoint_small.jpg

  • right mouse button on variables permits to display them etc.

http://mpa.itc.it/markus/grass61/debugging/ddd_4_displ_vars_small.jpg

  • figure out why it crashed there. This requires PATIENCE. But you will nearly save the world if you identify the problem :-)


Using kdbg (gdb graphical frontend)

  • kdbg is not unlike DDD, but it's a KDE application.
  • Use is similar to DDD.
  • Start with (within GRASS):
kdbg `which g.module`
  • Fill in command line arguments with menu item Execution->Arguments.
  • Open the View->Locals window.
  • Click the Run icon (or Execution->Run) and see where it breaks.
  • Set pause-points by clicking a red stop-sign to the left of the "+" on a line of the source code. From there you can step through instructions.
  • Explore the values of variables in the locals window.

Using ldd

ldd will show the shared library dependencies for a program or library. For example:

For a module:

GRASS> ldd `which v.in.ogr`

For a library:

$ ldd /usr/src/grass/grass-6.2.2/dist.i686-pc-linux-gnu/lib/libgrass_gis.so

The output looks like this:

       libz.so.1 => /usr/lib/libz.so.1 (0x40077000)
       libgrass_datetime.so => not found
       libc.so.6 => /lib/libc.so.6 (0x4008a000)
       /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

In the above example libgrass_datetime.so is missing causing an Illegal Instruction error in libgis. A common error occurs when there are more than one versions of a support library installed, and the GRASS build is using the wrong one. ldd is good for spotting this.

Library search path

If a support library like libgdal can't be found, and you are sure it is installed, make sure the library search path is set correctly. For example in Linux if GDAL was installed to /usr/local, add the line "/usr/local/lib" to the /etc/ld.so.conf file, and as root run ldconfig to rebuild the library links and cache.

Alternatively you can add the library path to the $LD_LIBRARY_PATH environmental variable.

Using strace

  • running the command through strace could give you another hint what is going wrong somewhere.

For example:

strace v.in.ogr out=your_map dsn="PG:dbname=postgis user=me" olayer=postgislayer

Using Valgrind

  • Valgrind is a tool to check for memory leaks

(Insert howto here)

Examples:

  • analysis of heap usage
CMD="v.in.ascii -zt z=3 in=lidaratm2_250k.txt out=lidaratm2_250k fs=,"
valgrind --tool=massif --format=html  $CMD --o
  • analysis of memory leaks
Quick addrcheck tool
valgrind -v --tool=addrcheck --leak-check=yes  $CMD
Full memcheck tool, including non-orphaned, but left over, allocated memory
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes  $CMD --o


  • Valgrind can create PostScript output charts. To convert PostScript to PNG:
('pstoimg' is part of the latex2html Debian package)
pstoimg -aaliastext -flip r90 -out massif.550.png -scale 1.3 -crop a massif.550.ps

Using Electric Fence

  • Electric Fence checks for bad memory writes, ie specific malloc() over-runs and under-runs.

(Insert howto here)

Example:

CMD="gdalwarp -tps -srcnodata 255 -dstnodata 255 \
       -of GTiff -rcs ${TMP}.tif ${OUTFILE}_warp"
LD_PRELOAD=libefence.so.0.0 $CMD

Using a profiling tool

A profiling tool may be used to identify the bottlenecks in long running processes.

Kcachegrind

kcachegrind is a visualization tool for Valgrind's callgrind profiling tool (formerly known as the calltree skin). It is very simple to use. Install the GraphViz package as well.

Example:

# Spearfish dataset
g.region rast=elevation.dem
v.random n=10000 out=rand10k
v.db.addtable rand10k column="elev INT"
CMD="v.what.rast rand10k rast=elevation.dem column=elev"
valgrind --tool=callgrind --trace-children=yes $CMD

This creates a file containing profiling information which kcachegrind can load. We include --trace-children in the above example so we can profile the DBF driver process as well as the main v.what.rast process.

kcachegrind callgrind.out.12345

In the above example from the two process costs we can see that 99.5% is taken by the dbf process and 0.5% is taken by the v.what.rast process. Within the dbf process almost 50% is taken by G_debug() and G_strcasecmp().

gprof

(Insert howto here)

Using Mudflap

GCC built in feature, that "instruments all risky pointer/array dereferencing operations, some standard library string/heap functions, and some other associated constructs with range/validity tests. Modules so instrumented should be immune to buffer overflows, invalid heap use, and some other classes of C/C++ programming errors. The instrumentation relies on a separate runtime library (libmudflap), which will be linked into a program if -fmudflap -lmudflap is given at link time." GCC Wiki

  • Requires GCC with mudflap support (GCC 4.x with mudflap USE flag on Gentoo, separate library "libmudflap*" in other distros);
  • Add -fmudflap and -lmudflap options (Is this correct way? It works...):
    • in include/Make/Platform.make add -lmudflap to LD_SEARCH_FLAGS;
    • in include/Make/Platform.make add -fmudflap to CFLAGS1;
  • Disable mudflap during compilation
export MUDFLAP_OPTIONS='-mode-nop -viol-nop'
  • Compile GRASS (make clean && make). For best results use NO optimisations for compilation (-O0);
  • Use GRASS.
    • To disable warnings
export MUDFLAP_OPTIONS='-mode-nop -viol-nop'
    • To enable warnings
export MUDFLAP_OPTIONS='-mode-check -viol-nop -check-initialization'

More information about debugging with mudflap, can be found here.

Skimming the ChangeLog for changes

  • use the tool cvs2cl.pl for generating a local changelog-file
(it can be found in the tools/ directory in the GRASS 6 source code)


Patches

  • For instructions on creating and applying patches the see Patches wiki page.