Debugging Octave: Difference between revisions

From Octave
Jump to navigation Jump to search
(9 intermediate revisions by 5 users not shown)
Line 5: Line 5:
mkdir dbg-octave
mkdir dbg-octave
cd dbg-octave
cd dbg-octave
/path/to/octave/source/configure FFLAGS=-g CFLAGS=-g CXXFLAGS=-g --enable-bounds-check --prefix=/opt/dbg-octave
/path/to/octave/source/configure FFLAGS=-g CFLAGS=-g CXXFLAGS=-g --enable-address-sanitizer-flags --prefix=/opt/dbg-octave
make # or make -jN where N is the number of CPU cores
make # or make -jN where N is the number of CPU cores
</syntaxhighlight>
</syntaxhighlight>
Line 11: Line 11:
This will create a new build of Octave in a different directory without optimisations (no -O2 gcc parameter) and with debug symbols compiled in. This build is useful for debugging Octave itself.
This will create a new build of Octave in a different directory without optimisations (no -O2 gcc parameter) and with debug symbols compiled in. This build is useful for debugging Octave itself.


= Debugging oct-files =
= Debugging Source files without GUI=
 
Ubuntu introduced a patch to disallow ptracing of non-child processes by non-root users - ie. only a process which is a parent of another process can ptrace it for normal users - whilst root can still ptrace every process.
That's why gdb won't be able to link to the octave process if you start gdb from within an Octave session using the command


To debug oct-files, avoid making any optimization during compilation. Use <code>export CXXFLAGS="-ggdb -Wall -O0"</code> for C++ code or <code>export CFLAGS="-ggdb -Wall -O0"</code> for C code to suppress optimization. Compile the oct-file with the debug flag <code>-g</code> which enables debug symbols
<syntaxhighlight lang="bash">
octave> system (sprintf ("gnome-terminal --command 'gdb -p %d'", getpid ()), "async");
</syntaxhighlight>


You can temporarily disable this restriction by doing:
<syntaxhighlight lang="bash">
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
</syntaxhighlight>
and then reopen the gdb using the command mentioned above from within an Octave session or if you have admin right you can simply do:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
mkoctfile -g file.cpp
octave> system (sprintf ("gnome-terminal --command 'sudo gdb -p %d'", getpid ()), "async");
</syntaxhighlight>
</syntaxhighlight>


start now the GNU debugger with octave.  On most Unixy systems, you can start gdb from within an Octave session by evaluating a command like


Instead you can debug octave without gui using: 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
octave> system (sprintf ("gnome-terminal --command 'gdb -p %d'", getpid ()), "async");
./run-octave -g --no-gui
 
</syntaxhighlight>
</syntaxhighlight>


at the Octave prompt. This command will open a terminal window running gdb attached to the Octave process.  At this point, Octave will be stopped.  To tell Octave to continue, type
= Debugging oct-files =
 
To debug oct-files, avoid making any optimization during compilation. Use <code>export CXXFLAGS="-ggdb -Wall -O0"</code> for C++ code or <code>export CFLAGS="-ggdb -Wall -O0"</code> for C code to suppress optimization. Compile the oct-file with the debug flag <code>-g</code> which enables debug symbols


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
(gdb) continue
mkoctfile -g file.cpp
</syntaxhighlight>
</syntaxhighlight>


at the gdb prompt. The symbols from your oct-file will only be available to gdb once the oct-file is loaded in Octave.  To do that without executing any functions from the oct-file, you can ask Octave to display the help for the oct-file:
In next step you will use GNU debugger or gdb. The symbols from your oct-file will only be available to gdb once the oct-file is loaded in Octave.  To do that without executing any functions from the oct-file, you can ask Octave to display the help for the oct-file:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 37: Line 50:
</syntaxhighlight>
</syntaxhighlight>


Now halt execution of Octave by typing ctrl+c, you'll see again the gdb prompt. Set now a breakpoint in the line of interest
start now the GNU debugger with octave.  On most Unixy systems, you can start gdb from within an Octave session by evaluating a command like
 
<syntaxhighlight lang="bash">
octave> system (sprintf ("gnome-terminal --command 'gdb -p %d'", getpid ()), "async");
</syntaxhighlight>
 
at the Octave prompt.  This command will open a terminal window running gdb attached to the Octave process.  At this point, Octave will be stopped.
 
Now you can set a breakpoint in the line of interest of your oct-file in gdb prompt:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 54: Line 75:
== Producing a stack trace ==
== Producing a stack trace ==


Sometimes Octave will crash, meaning, it terminates abruptly and returns control to the operating system shell. In these cases, it is very helpful to produce a stack trace to diagnose the problem. To do so, you need to (re)compile Octave with debugging symbols and run the debugger, as explained above. Then, run Octave:
Sometimes Octave will crash, meaning, it terminates abruptly and returns control to the operating system shell. In these cases, it is very helpful to produce a stack trace to diagnose the problem. To do so, you need to (re)compile Octave with debugging symbols , only if you can afford such a huge work, and run the debugger, as explained above. Then execute whatever commands are necessary to cause Octave to crash.  At that point, you will be back in a gdb session. Type <code>where</code> at the gdb prompt to obtain a stack trace.
 
But if you can't or don't want to recompile octave ,which is totally normal, then you can get some help from your system tools. In most GNU/Linux systems whenever a crash happens in a software, a <i>core dump</i> will be generated. These core dumps are handled by a registered component of the system and finally can be stored somewhere in the directory tree. You should find them, view them and inspect them.


=== Where are core dumps stored? ===
It differs on each system. First you should see what does handle core dumps on your system. to do so, type this in a shell terminal:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
gdb> run
$ cat /proc/sys/kernel/core_pattern
</syntaxhighlight>
</syntaxhighlight>
This may print a file name pattern along with a path, where all core dumps will be saved <b>ONLY</b> if it does not start by a pipe or '|'. If it does, <i>the kernel will treat the rest of the pattern as a command to run.  The core dump will be written to the standard input of that program instead of to a file</i>, and you need to consult that program's help or manual.


execute whatever commands you think are necessary to produce the crash. When Octave crashes, you will be back in a gdb session. Type <code>bt</code> here to obtain a stack trace.
=== How to view a core dump? ===
To do this you should use gdb. Core dumps are saved under root user, so you may need to change owner of the core dump you are interested in if you are not logged in as root. After that type in the terminal:
<syntaxhighlight lang="bash">
gdb octave -c <Path to core dump>
</syntaxhighlight>


=== Most used commands ===
Always expect some warnings from gdb in a few first times of doing this. Most likely gdb will tell you that:
[http://www.gnu.org/software/gdb/documentation gdb documentation]


== Emacs ==
1. The core dump file is not in the correct format. It is the case if the core dump handler of your system compresses core dumps before storing them, and you need to decompress the core dump first.


In short:
2. Core dump was generated by a-path-to/octave-gui. Then quit gdb and start it again by:
<syntaxhighlight lang="bash">
gdb octave-gui -c <Path to core dump>
</syntaxhighlight>


To start Octave in debug mode within emacs type
3. Some debug info are missing. In this case gdb itself will tell you how to install them. Install them and start gdb again.


<code>
If everything worked fine, you can use 'where' command in gdb prompt to see a full stack trace of the crash.
M-x gud-gdb
<code>


then change the command in the minibuffer to run gud-gdb (like this):
=== Most used commands ===
[http://www.gnu.org/software/gdb/documentation gdb documentation]


    /path/to/octave/build/tree/run-octave -gud
For debugging octave_value variables (e.g. <code>my_octave_value</code>) to find out what the variable actually is (instead of just it's base class):


For more info use this
<syntaxhighlight lang="bash">
[http://www.gnu.org/software/emacs/manual/html_node/emacs/Debuggers.html#Debuggers link]
(gdb) print *(my_octave_value.rep)
to the emacs manual section on debuggers operation
</syntaxhighlight>


== ddd ==
== ddd ==

Revision as of 20:34, 1 June 2019

Preliminaries

Since compilation of all the source from scratch can take long it is good to have a source folder where most of the source has been compiled. To do this, you can create a parallel build:

mkdir dbg-octave
cd dbg-octave
/path/to/octave/source/configure FFLAGS=-g CFLAGS=-g CXXFLAGS=-g --enable-address-sanitizer-flags --prefix=/opt/dbg-octave
make # or make -jN where N is the number of CPU cores

This will create a new build of Octave in a different directory without optimisations (no -O2 gcc parameter) and with debug symbols compiled in. This build is useful for debugging Octave itself.

Debugging Source files without GUI

Ubuntu introduced a patch to disallow ptracing of non-child processes by non-root users - ie. only a process which is a parent of another process can ptrace it for normal users - whilst root can still ptrace every process. That's why gdb won't be able to link to the octave process if you start gdb from within an Octave session using the command

octave> system (sprintf ("gnome-terminal --command 'gdb -p %d'", getpid ()), "async");

You can temporarily disable this restriction by doing:

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

and then reopen the gdb using the command mentioned above from within an Octave session or if you have admin right you can simply do:

octave> system (sprintf ("gnome-terminal --command 'sudo gdb -p %d'", getpid ()), "async");


Instead you can debug octave without gui using:

./run-octave -g --no-gui

Debugging oct-files

To debug oct-files, avoid making any optimization during compilation. Use export CXXFLAGS="-ggdb -Wall -O0" for C++ code or export CFLAGS="-ggdb -Wall -O0" for C code to suppress optimization. Compile the oct-file with the debug flag -g which enables debug symbols

mkoctfile -g file.cpp

In next step you will use GNU debugger or gdb. The symbols from your oct-file will only be available to gdb once the oct-file is loaded in Octave. To do that without executing any functions from the oct-file, you can ask Octave to display the help for the oct-file:

octave> help file

start now the GNU debugger with octave. On most Unixy systems, you can start gdb from within an Octave session by evaluating a command like

octave> system (sprintf ("gnome-terminal --command 'gdb -p %d'", getpid ()), "async");

at the Octave prompt. This command will open a terminal window running gdb attached to the Octave process. At this point, Octave will be stopped.

Now you can set a breakpoint in the line of interest of your oct-file in gdb prompt:

(gdb) b file.cpp:40

by typing c the execution of octave will continue and you can run your oct-file directly or via an m-script.

octave> x = file(y)

the debugger will stop on the above defined line and you can start debugging according to the manual of GNU debugger.

Tools for debugging

Producing a stack trace

Sometimes Octave will crash, meaning, it terminates abruptly and returns control to the operating system shell. In these cases, it is very helpful to produce a stack trace to diagnose the problem. To do so, you need to (re)compile Octave with debugging symbols , only if you can afford such a huge work, and run the debugger, as explained above. Then execute whatever commands are necessary to cause Octave to crash. At that point, you will be back in a gdb session. Type where at the gdb prompt to obtain a stack trace.

But if you can't or don't want to recompile octave ,which is totally normal, then you can get some help from your system tools. In most GNU/Linux systems whenever a crash happens in a software, a core dump will be generated. These core dumps are handled by a registered component of the system and finally can be stored somewhere in the directory tree. You should find them, view them and inspect them.

Where are core dumps stored?

It differs on each system. First you should see what does handle core dumps on your system. to do so, type this in a shell terminal:

$ cat /proc/sys/kernel/core_pattern

This may print a file name pattern along with a path, where all core dumps will be saved ONLY if it does not start by a pipe or '|'. If it does, the kernel will treat the rest of the pattern as a command to run. The core dump will be written to the standard input of that program instead of to a file, and you need to consult that program's help or manual.

How to view a core dump?

To do this you should use gdb. Core dumps are saved under root user, so you may need to change owner of the core dump you are interested in if you are not logged in as root. After that type in the terminal:

gdb octave -c <Path to core dump>

Always expect some warnings from gdb in a few first times of doing this. Most likely gdb will tell you that:

1. The core dump file is not in the correct format. It is the case if the core dump handler of your system compresses core dumps before storing them, and you need to decompress the core dump first.

2. Core dump was generated by a-path-to/octave-gui. Then quit gdb and start it again by:

gdb octave-gui -c <Path to core dump>

3. Some debug info are missing. In this case gdb itself will tell you how to install them. Install them and start gdb again.

If everything worked fine, you can use 'where' command in gdb prompt to see a full stack trace of the crash.

Most used commands

gdb documentation

For debugging octave_value variables (e.g. my_octave_value) to find out what the variable actually is (instead of just it's base class):

(gdb) print *(my_octave_value.rep)

ddd

gui for gdb