Debugging and profiling: Difference between revisions

From Alliance Doc
Jump to navigation Jump to search
No edit summary
No edit summary
 
(43 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{Draft}}
<languages />
<translate>
<!--T:1-->
An important step in the software development process, particularly for compiled languages like Fortran and C/C++, concerns the use of a program called a debugger to detect and identify the origin of runtime errors (e.g. memory leaks, floating point exceptions and so forth) so that they can be eliminated. Once the program's correctness is assured, a further step is profiling the software. This involves the use of another software tool, a profiler, determine what percentage of the total execution time each section of the source code is responsible for when run with a representative test case. A profiler can give information like how many times a particular function is called, which other functions are calling it and how many milli-seconds of time each invocation of this function costs on average. 


The Compute Canada national clusters offer a variety of debugging and profiling tools, both command line and those with a graphical user interface, whose use requires an X11 connection. Note that debugging sessions should be conducted using an [[Running_jobs#Interactive_jobs | interactive job]] and not run on the login node.
= Debugging and profiling tools= <!--T:2-->


== Gnu Debugger (gdb) ==
<!--T:3-->
Our national clusters offer a variety of debugging and profiling tools, both command line and those with a graphical user interface, whose use requires an X11 connection. Note that debugging sessions should be conducted using an [[Running_jobs#Interactive_jobs | interactive job]] and not run on a login node.


Please see the [[GBD page]]
== GNU debugger (gdb) == <!--T:4-->


== PGI Debugger (pgdb) ==
<!--T:5-->
Please see the [[GDB | GDB page]].


== ARM Debugger (ddt) ==
== PGI debugger (pgdb) == <!--T:6-->
Please see the [https://docs.alliancecan.ca/wiki/Pgdbg Pgdbg page].


== ARM debugger (ddt) == <!--T:7-->
<!--T:8-->
Please see the [[ARM software | ARM software page]].
Please see the [[ARM software | ARM software page]].


==Gprof ==
==GNU profiler (gprof) == <!--T:9-->


==Valgrind==
<!--T:10-->
Please see the [[Gprof | Gprof  page]].


[http://valgrind.org/ Valgrind] is a powerful debugging tool to detect bad memory usage. It can detect memory leaks, but also access to unallocated or deallocated memory, multiple deallocation or other bad memory usage. If your program ends with a ''segmentation fault'', ''broken pipe'' or ''bus error'', you most likely have such a problem in your code.
== Scalasca profiler (scalasca, scorep, cube) == <!--T:11-->


[http://valgrind.org/ Valgrind] is installed on most of the Calcul Québec clusters and is available through a module. To know the exact name of the module on the server you are using, run the following command:
<!--T:19-->
{{Commande|module avail 2>&1 {{!}} grep valgrind}}
Scalasca is an open source, GUI-driven parallel profiling tool set. It is currently available for <b>gcc 9.3.0</b> and <b>OpenMPI 4.0.3</b>, with AVX2 or AVX512 architecture. Its environment can be loaded with:


=== Preparing your application ===
<!--T:20-->
To get useful information from [http://valgrind.org/ Valgrind], you first need to compile your code with debuging information enabled. With the [[GCC/en|GNU]] and [[Intel/en|Intel]] compilers, you do so by adding a "<tt>-g</tt>" option on compilation. For other compilers, check their documentation.
<code>module load StdEnv/2020 gcc/9.3.0 openmpi/4.0.3 scalasca</code>


Some aggressive optimisations may yield false errors in Valgrind if they result in unsupported operations. This is the case for example with some operations implemented in the [[MKL/en|MKL]] library. Since you don't want to diagnose errors in those libraries, but rather errors in your own code, you should compile and link your code against non-optimized versions of the libraries (such as the Netlib implementation of BLAS/LAPACK) that will not do those operations. This is of course only to diagnose issues. When time comes to run real simulations, you should link against optimized libraries.
<!--T:21-->
The current version is <b>2.5</b>. More information can be found in the 2.x user guide, which contains workflow examples [https://apps.fz-juelich.de/scalasca/releases/scalasca/2.5/docs/manual/ here].


=== Using Valgrind ===
== PGI profiler (pgprof) == <!--T:12-->
Once your code is compiled with the proper options, you execute it within Valgrind with the following command :
Please see the [[PGPROF | Pgprof page]].
{{Commande|valgrind --tool{{=}}memcheck --leak-check{{=}}yes --show-reachable{{=}}yes ./votre_programme}}


For more information about valgrind, we recommend [http://www.cprogramming.com/debugging/valgrind.html this page].
== Nvidia command-line profiler (nvprof) == <!--T:13-->
Please see the [[Nvprof | nvprof page]].


==== Words of wisdom ====
==Valgrind== <!--T:15-->
* When you run your code in Valgrind, your application is executed within a virtual machine that validates every memory access. It will therefore run '''much slower''' than usual. Choose the size of the problem to test with caution, much smaller than what you would usually run.
* You do not need to run the exact same problem that results in a segmentation fault to detect memory issues in your code. Very frequently, memory access problem, such as reading data outside of the bounds of an array, will go undetected for small size problems, but will cause a segmentation fault for large ones. Valgrind will detect even the slightest access outside of the bounds of an array.


==== Some typical error messages ====
<!--T:22-->
Here are some problems that Valgrind will help you detect, and the error messages that it will produce.
Please see the [[Valgrind | Valgrind page]].


===== Memory leak =====
= External references = <!--T:16-->
The error message for a memory leak will be given at the end of the program execution, and will look like this :
<syntaxhighlight lang=text>
==2116== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2116==    at 0x1B900DD0: malloc (vg_replace_malloc.c:131)
==2116==    by 0x804840F: main (in /home/cprogram/example1)
</syntaxhighlight>


===== Invalid pointer access/out of bound errors =====
<!--T:17-->
If you attempt to read or write to an unallocated pointer or outside of the allocated memory, the error message will look like this:
* [https://docs.scinet.utoronto.ca/index.php/Introduction_To_Performance Introduction to (Parallel) Performance] from SciNet
<syntaxhighlight lang=text>
* [https://www.youtube.com/watch?v=YsF5KMr9uEQ Code profiling on Graham], video, 54 minutes.
==9814==  Invalid write of size 1
==9814==    at 0x804841E: main (example2.c:6)
==9814==  Address 0x1BA3607A is 0 bytes after a block of size 10 alloc'd
==9814==    at 0x1B900DD0: malloc (vg_replace_malloc.c:131)
==9814==    by 0x804840F: main (example2.c:5)
</syntaxhighlight>


===== Usage of uninitialized variables =====
<!--T:18-->
If you use an uninitialized variable, you will get an error message such as
[[Category:Pages with video links]]
<syntaxhighlight lang=text>
</translate>
==17943== Conditional jump or move depends on uninitialised value(s)
==17943==    at 0x804840A: main (example3.c:6)
</syntaxhighlight>

Latest revision as of 17:40, 5 June 2023

Other languages:

An important step in the software development process, particularly for compiled languages like Fortran and C/C++, concerns the use of a program called a debugger to detect and identify the origin of runtime errors (e.g. memory leaks, floating point exceptions and so forth) so that they can be eliminated. Once the program's correctness is assured, a further step is profiling the software. This involves the use of another software tool, a profiler, determine what percentage of the total execution time each section of the source code is responsible for when run with a representative test case. A profiler can give information like how many times a particular function is called, which other functions are calling it and how many milli-seconds of time each invocation of this function costs on average.

Debugging and profiling tools

Our national clusters offer a variety of debugging and profiling tools, both command line and those with a graphical user interface, whose use requires an X11 connection. Note that debugging sessions should be conducted using an interactive job and not run on a login node.

GNU debugger (gdb)

Please see the GDB page.

PGI debugger (pgdb)

Please see the Pgdbg page.

ARM debugger (ddt)

Please see the ARM software page.

GNU profiler (gprof)

Please see the Gprof page.

Scalasca profiler (scalasca, scorep, cube)

Scalasca is an open source, GUI-driven parallel profiling tool set. It is currently available for gcc 9.3.0 and OpenMPI 4.0.3, with AVX2 or AVX512 architecture. Its environment can be loaded with:

module load StdEnv/2020 gcc/9.3.0 openmpi/4.0.3 scalasca

The current version is 2.5. More information can be found in the 2.x user guide, which contains workflow examples here.

PGI profiler (pgprof)

Please see the Pgprof page.

Nvidia command-line profiler (nvprof)

Please see the nvprof page.

Valgrind

Please see the Valgrind page.

External references