Skip to content

Commit

Permalink
Merge pull request #646 from clebergnu/doc_review_v2
Browse files Browse the repository at this point in the history
Documentation Review (v2)
  • Loading branch information
lmr committed Jun 8, 2015
2 parents b814f32 + 333fad7 commit 4e88248
Show file tree
Hide file tree
Showing 16 changed files with 385 additions and 323 deletions.
2 changes: 1 addition & 1 deletion avocado/core/plugins/gdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def configure(self, parser):
default=[], metavar='BINARY_PATH:COMMANDS_PATH',
help=('After loading a binary in binary in GDB, '
'but before actually running it, execute '
'the given GDB commands in the given file.'
'the given GDB commands in the given file. '
'BINARY_PATH is optional and if omitted '
'will apply to all binaries'))

Expand Down
28 changes: 14 additions & 14 deletions docs/source/Configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Avocado utilities have a certain default behavior based on educated, reasonable
users like to use their systems. Of course, different people will have different needs and/or dislike our defaults,
and that's why a configuration system is in place to help with those cases

The avocado config file format is based on the (informal)
The Avocado config file format is based on the (informal)
`INI file 'specification' <http://en.wikipedia.org/wiki/INI_file>`__, that is implemented by
python's :mod:`ConfigParser`. The format is simple and straightforward, composed by `sections`,
that contain a number of `keys` and `values`. Take for example a basic avocado config file::
Python's :mod:`ConfigParser`. The format is simple and straightforward, composed by `sections`,
that contain a number of `keys` and `values`. Take for example a basic Avocado config file::

[datadir.paths]
base_dir = ~/avocado
Expand All @@ -18,7 +18,7 @@ that contain a number of `keys` and `values`. Take for example a basic avocado c
logs_dir = ~/avocado/job-results

The ``datadir.paths`` section contains a number of keys, all of them related to directories used by
the test runner. The ``base_dir`` is the base directory to other important avocado directories, such
the test runner. The ``base_dir`` is the base directory to other important Avocado directories, such
as log, data and test directories. You can also choose to set those other important directories by
means of the variables ``test_dir``, ``data_dir`` and ``logs_dir``. You can do this by simply editing
the config files available.
Expand All @@ -27,22 +27,22 @@ the config files available.
Config file parsing order
=========================

Avocado starts by parsing what it calls system wide config file, that is shipped to all avocado users on a system
Avocado starts by parsing what it calls system wide config file, that is shipped to all Avocado users on a system
wide directory, ``/etc/avocado/avocado.conf``. Then it'll verify if there's a local user config file, that is located
usually in ``~/.config/avocado/avocado.conf``. The order of the parsing matters, so the system wide file is parsed,
then the user config file is parsed last, so that the user can override values at will. There is another directory
that will be scanned by extra config files, ``/etc/avocado/conf.d``. This directory may contain plugin config files,
and extra additional config files that the system administrator/avocado developers might judge necessary to put there.

Please note that for base directories, if you chose a directory that can't be properly used by avocado (some directories
require read access, others, read and write access), avocado will fall back to some defaults. So if your regular user
wants to write logs to ``/root/avocado/logs``, avocado will not use that directory, since it can't write files to that
Please note that for base directories, if you chose a directory that can't be properly used by Avocado (some directories
require read access, others, read and write access), Avocado will fall back to some defaults. So if your regular user
wants to write logs to ``/root/avocado/logs``, Avocado will not use that directory, since it can't write files to that
place. A new location, by default ``~/avocado/job-results`` will be selected instead.

Plugin config files
===================

Plugins can also be configured by config files. In order to not disturb the main avocado config file, those plugins,
Plugins can also be configured by config files. In order to not disturb the main Avocado config file, those plugins,
if they wish so, may install additional config files to ``/etc/avocado/conf.d/[pluginname].conf``, that will be parsed
after the system wide config file. Users can override those values as well at the local config file level.
Considering the config for the hypothethical plugin ``salad``::
Expand Down Expand Up @@ -83,7 +83,7 @@ system.
Config plugin
=============

A configuration plugin is provided for users that wish to quickly see what's defined in all sections of their avocado
A configuration plugin is provided for users that wish to quickly see what's defined in all sections of their Avocado
configuration, after all the files are parsed in their correct resolution order. Example::

$ avocado config
Expand Down Expand Up @@ -132,22 +132,22 @@ it will give you an output similar to the one seen below::
data $HOME/avocado/data
logs $HOME/avocado/job-results

Note that, while avocado will do its best to use the config values you
Note that, while Avocado will do its best to use the config values you
provide in the config file, if it can't write values to the locations
provided, it will fall back to (we hope) reasonable defaults, and we
notify the user about that in the output of the command.

The relevant API documentation and meaning of each of those data directories
is in :mod:`avocado.data_dir`, so it's highly recommended you take a look.

You may set your preferred data dirs by setting them in the avocado config files.
The only exception for important data dirs here is the avocado tmp dir, used to
You may set your preferred data dirs by setting them in the Avocado config files.
The only exception for important data dirs here is the Avocado tmp dir, used to
place temporary files used by tests. That directory will be in normal circumstances
`/var/tmp/avocado_XXXXX`, (where `XXXXX` is in actuality a random string) securely
created on `/var/tmp/`, unless the user has the `$TMPDIR` environment variable set,
since that is customary among unix programs.

The next section of the documentation explains how you can see and set config
values that modify the behavior for the avocado utilities and plugins.
values that modify the behavior for the Avocado utilities and plugins.

[1] For example, autotest.
4 changes: 2 additions & 2 deletions docs/source/ContributionGuide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
Contribution and Community Guide
================================

Useful pointers on how to participate of the avocado community and contribute.
Useful pointers on how to participate of the Avocado community and contribute.

Contact information
===================

- Avocado-devel mailing list: `https://www.redhat.com/mailman/listinfo/avocado-devel <https://www.redhat.com/mailman/listinfo/avocado-devel>`_
- Avocado IRC channel: `irc.oftc.net #avocado <irc://irc.oftc.net/#avocado>`_

Contributing to avocado
Contributing to Avocado
=======================

Avocado uses github and the github pull request development model. You can
Expand Down
135 changes: 82 additions & 53 deletions docs/source/DebuggingWithGDB.rst
Original file line number Diff line number Diff line change
@@ -1,56 +1,46 @@
Debugging with GDB
==================

Avocado has two levels of GDB support, one by using the Avocado GDB APIs
to fire up GDB and interact with it, and other by transparently debugging
binaries inside the GNU Debugger based on command line only options. This
later option means that any test that uses :mod:`avocado.utils.process`
can transparently inspect processes during test run time.

API
---

Avocado's GDB module, provides three main classes that lets a test writer
interact with a `gdb` process, a `gdbserver` process and also use the GDB
remote protocol for interaction with a remote target.

Please refer to :mod:`avocado.gdb` for more information.

Example
~~~~~~~

Take a look at ``examples/tests/modify_variable.py`` test::

def runTest(self):
"""
Execute 'print_variable'.
"""
path = os.path.join(self.srcdir, 'print_variable')
app = gdb.GDB()
app.set_file(path)
app.set_break(6)
app.run()
self.log.info("\n".join(app.read_until_break()))
app.cmd("set variable a = 0xff")
app.cmd("c")
out = "\n".join(app.read_until_break())
self.log.info(out)
app.exit()
self.assertIn("MY VARIABLE 'A' IS: ff", out)

You can see that instead of running the binary using ``process.run`` we invoke
``gdb.GDB``. This allows us to automate the interaction with the GDB in means
of setting breakpoints, executing commands and querying for output.

When you check the output (``--show-job-log``) you can see that despite
declaring the variable as 0, ff is injected and printed instead.


Transparent Debugging Usage
---------------------------

This feature is implemented as a plugin, that adds the ``--gdb-run-bin``
option to the avocado ``run`` command.
Avocado has two different types of GDB support that complement each
other:

* Transparent execution of binaries inside the GNU Debugger. This
takes standard and possibly unmodified tests that uses the
:mod:`avocado.utils.process` APIs for running processes. By using a
command line option, the binary is run on GDB. This allows the user
to interact with GDB, but to the test itself, things are pretty much
transparent.
* The :mod:`avocado.gdb` APIs that allows a test to interact with GDB,
including setting a binary to be run, setting breakpoints or any
other types of commands. This requires a test written with that
approach and API in mind.


Transparent Execution of Binaries
---------------------------------

This feature adds a few command line options to the Avocado ``run``
command::

$ avocado run --help
...
GNU Debugger support:
--gdb-run-bin BINARY_PATH
Set a breakpoint on a given binary to be run inside
the GNU debugger. Format should be
"<binary>[:breakpoint]". Breakpoint defaults to "main"
--gdb-prerun-commands BINARY_PATH:COMMANDS_PATH
After loading a binary in binary in GDB, but before
actually running it, execute the given GDB commands in
the given file. BINARY_PATH is optional and if omitted
will apply to all binaries
--gdb-coredump {on,off}
Automatically generate a core dump when the inferior
process received a fatal signal such as SIGSEGV or
SIGABRT
...

To get started you want to use ``--gdb-run-bin``, as shown in the example bellow.

Example
~~~~~~~
Expand All @@ -67,7 +57,7 @@ Optionally you can specify single breakpoint using
It's worth mentioning that when breakpoint is not reached, the test finishes
without any interruption. This is helpful when you identify regions where you
should never get in your code, or places which interests you and you can run
your code in production and gdb variants. If after a long time you get to this
your code in production and GDB variants. If after a long time you get to this
place, the test notifies you and you can investigate the problem. This is
demonstrated in ``examples/tests/doublefree_nasty.py`` test. To unveil the
power of Avocado, run this test using::
Expand Down Expand Up @@ -116,7 +106,7 @@ There are a two basic reasons for the mentioned caveats:
* The architecture of Avocado's GDB feature
* GDB's own behavior and limitations

When using the Avocado GDB plugin, that is, `--gdb-run-bin`, avocado runs a `gdbserver` instance
When using the Avocado GDB plugin, that is, `--gdb-run-bin`, Avocado runs a `gdbserver` instance
transparently and controls it by means of a `gdb` process. When a given event happens, say a
breakpoint is reached, it disconnects its own `gdb` from the server, and allows the user to use
a standard `gdb` to connect to the `gdbserver`. This provides a natural and seamless user experience.
Expand All @@ -126,7 +116,7 @@ But, `gdbserver` has some limitations at this point, including:
* Not being able to set a controlling `tty`
* Not separating its own `STDERR` content from the application being run

These limitations are being addressed both on Avocado and GDB, and will be resolved in future avocado
These limitations are being addressed both on Avocado and GDB, and will be resolved in future Avocado
versions.

Workaround
Expand All @@ -148,3 +138,42 @@ extension, though, uses :class:`avocado.utils.process.SubProcess` class to
execute `qemu` in the background.

This limitation will be addressed in future versions of `avocado` and `avocado-virt`.


:mod:`avocado.gdb` APIs
-----------------------

Avocado's GDB module, provides three main classes that lets a test writer
interact with a `gdb` process, a `gdbserver` process and also use the GDB
remote protocol for interaction with a remote target.

Please refer to :mod:`avocado.gdb` for more information.

Example
~~~~~~~

Take a look at ``examples/tests/modify_variable.py`` test::

def runTest(self):
"""
Execute 'print_variable'.
"""
path = os.path.join(self.srcdir, 'print_variable')
app = gdb.GDB()
app.set_file(path)
app.set_break(6)
app.run()
self.log.info("\n".join(app.read_until_break()))
app.cmd("set variable a = 0xff")
app.cmd("c")
out = "\n".join(app.read_until_break())
self.log.info(out)
app.exit()
self.assertIn("MY VARIABLE 'A' IS: ff", out)

You can see that instead of running the binary using ``process.run`` we invoke
``gdb.GDB``. This allows us to automate the interaction with the GDB in means
of setting breakpoints, executing commands and querying for output.

When you check the output (``--show-job-log``) you can see that despite
declaring the variable as 0, ff is injected and printed instead.

0 comments on commit 4e88248

Please sign in to comment.