This is Info file nana.info, produced by Makeinfo version 1.68 from the
input file nana.texi.

START-INFO-DIR-ENTRY
* Nana: (nana).          The GNU Nana library (assertions, logging, forall,etc)
END-INFO-DIR-ENTRY

   This file documents the features and implementation of the GNU Nana
library.

   Copyright (C) 1996, 1997, 1998, P.J.Maker

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.


File: nana.info,  Node: Library,  Prev: Statement,  Up: Tracing

Library tracing
===============

   On most UNIX machines there exists a tool for tracing the system
calls executed by a program. If you haven't used one of these tools
(e.g. ktrace) then now is a good time to learn. Being able to trace the
User/Kernel interface is an excellent way to understand complex
applications.

   The `nana-libtrace' facility generalises this idea to provide a GDB
based function call tracer for all functions in which are defined in a
particular library.  For example the `make ex-libtrace' command in the
`gdb' directory produces a trace of all calls to `libc'.

   * `nana-libtrace a.out' - reads a list of function names one per line
     from the standard input and writes the corresponding gdb(1) script
     to the standard output. Note that all functions specified in the
     input must exist in the executable for them to be passed through
     to the output. This may require compilation of your program with
     `-static' linking.(1)  For example:

          % gcc -g -static test.c -lm
          % ./nana-libtrace a.out >test.gdb
          printf
          write
          % cat test.gdb
          % cat test.gdb
          break printf
          command $bpnum
          silent
          where 1
          cont
          end
          break write
          command $bpnum
          silent
          where 1
          cont
          end
          % nana-run a.out -x test.gdb
          Breakpoint 1 at 0x1483: file /usr/.../libc/stdio/printf.c, line 65.
          Breakpoint 2 at 0x8c78
          #0  printf (fmt=0x1116 "** main()\n")
              at /usr/src/lib/libc/../libc/stdio/printf.c:65
          #0  0x8c78 in write ()
          ** main()
          #0  printf (fmt=0x1121 "** 1: %d\n")
              at /usr/src/lib/libc/../libc/stdio/printf.c:65
          #0  0x8c78 in write ()
          ** 1: 6
          #0  printf (fmt=0x112b "** 2: %d\n")
              at /usr/src/lib/libc/../libc/stdio/printf.c:65
          #0  0x8c78 in write ()
          ** 2: 7
          #0  printf (fmt=0x1135 "** 3: %d\n")
              at /usr/src/lib/libc/../libc/stdio/printf.c:65
          #0  0x8c78 in write ()
          ** 3: 8
          
          Program exited with code 010.

   * `nana-libtrace a.out /usr/lib/libc.a' - trace all calls to `libc'
     from `a.out'. A subset of the output is given below:

          #0  printf (fmt=0x1135 "** 3: %d\n")
              at /usr/src/lib/libc/../libc/stdio/printf.c:65
          #0  vfprintf (fp=0xa1d4, fmt0=0x1135 "** 3: %d\n", ap=0xefbfd888 "\b")
              at /usr/src/lib/libc/../libc/stdio/vfprintf.c:428
          #0  vfprintf (fp=0xefbfd5b8, fmt0=0x1135 "** 3: %d\n", ap=0xefbfd888 "\b")
              at /usr/src/lib/libc/../libc/stdio/vfprintf.c:428
          #0  __sfvwrite (fp=0xefbfd5b8, uio=0xefbfd184)
              at /usr/src/lib/libc/../libc/stdio/fvwrite.c:68
          #0  0x8ff8 in memcpy ()
          #0  0x8ff8 in memcpy ()
          #0  __sfvwrite (fp=0xefbfd5b8, uio=0xefbfd184)
              at /usr/src/lib/libc/../libc/stdio/fvwrite.c:68
          #0  0x8ff8 in memcpy ()
          #0  fflush (fp=0xefbfd5b8) at /usr/src/lib/libc/../libc/stdio/fflush.c:60
          #0  __sflush (fp=0xefbfd5b8) at /usr/src/lib/libc/../libc/stdio/fflush.c:84
          #0  __swrite (cookie=0xa1d4, buf=0xefbfd1b8 "** 3: 8\nain()\n", n=8)
              at /usr/src/lib/libc/../libc/stdio/stdio.c:78
          #0  0x8c78 in write ()
          ** 3: 8

     Note that your library code must be compiled with `-g' to put in
     the debugging information if you wish to have the arguments
     displayed symbolically. This is fairly easy on most systems, e.g
     on FreeBSD you edit the global compile options `/etc/make.conf'
     and rebuild/install the entire system.

     Ideally we would also like to be able to trace only entry calls and
     not internal calls to libc. This can be done by inserting a counter
     which is incremented on call and decremented on return. We print
     the trace messages iff the counter is 1. This extension (perhaps
     to GNU libc) may be written if people are interested.

   ---------- Footnotes ----------

   (1) If possible we should replace the call to `nm' with a call to
something which can print all the symbols for a dynamically linked
library. Unfortunately GDB gets upset if you try to set a breakpoint
for a function that does not exist. I suppose we could use gdb to print
the symbol list out.


File: nana.info,  Node: Usage,  Next: FAQ,  Prev: Tracing,  Up: Top

Using Nana
**********

   This chapter is intended to provide some hopefully useful examples of
Nana. If any of the users of this library would be so kind as to
contribute a section on their usage I would be obliged.

   *This section is under development*

* Menu:

* Simplest::
* Syslog::
* GNU::
* Embedded Systems::
* Realtime::
* A database::
* Visualisation::


File: nana.info,  Node: Simplest,  Next: Syslog,  Prev: Usage,  Up: Usage

Simplest example
================

   As a nice simple, indeed trivial example consider the following:

  1. Include `nana.h' in your project wide include file.

  2. Use `I' to check invariants in your code. In particular all
     functions or methods should be required to check their pre and post
     conditions.

  3. Use `DL' to print debugging messages in your code. This means that
     debugging messages only occur when you run the program under the
     debugger.(1)

   ---------- Footnotes ----------

   (1) Of course you also need to use the gdb commands generated by the
`nana' command, perhaps using `nana-clg'


File: nana.info,  Node: Syslog,  Next: GNU,  Prev: Simplest,  Up: Usage

Syslog
======

   `syslog' is a comprehensive logging system written by Eric Allman
which is available on most UNIX systems. It provides facilities for
sorting messages by source or severity and mechanisms for sending
messages off to files, terminals or other machines. See chapter 12 of
the "UNIX System Administration Handbook (2nd Edition)" by Nemeth,
Snyder, Seebass and Hein for an excellent tutorial on `syslog'.

   The rules used by `syslog' are normally defined in
`/etc/syslog.conf'. Each line specifies the destination for messages
with particular sources and priorities.  For example:

     # log mail messages at priority info to mailinfo
     mail.info /var/log/mailinfo
     # log all ftp information to syslog on a remote machine
     ftp.* @remote-machine.cs.ntu.edu.au
     # all critical errors to console
     *.crit   /dev/console

   To use `syslog' we merely redefine the default handlers and
parameter values for `nana'. For example:

     #include <syslog.h>
     #define L_DEFAULT_HANDLER syslog /* replaces fprintf(3) by syslog(3) */
     #define L_DEFAULT_PARAMS LOG_USER /* default priority for syslog info */
     #include <nana.h>
     
     int main() {
          openlog("nana", /* identifier for these log messages */
             LOG_PID, /* also log the process id */
             LOG_DAEMON /* facility */
          );
     
          L("temperature is falling to %d", 35); /* logged at LOG_USER priority */
          LP(LOG_CRIT, "the snow is falling in Darwin"); /* LOG_CRIT message */
     
          closelog();
          return 0;
     }

   This program results in the following addition to
`/var/adm/messages':

     Jun 12 16:04:46 chingiz nana[2671]: the temperature is falling to 35
     Jun 12 16:04:46 chingiz nana[2671]: the snow is falling in Darwin

   In addition the `LOG_CRIT' message about snow falling in Darwin is
sent to the console for immediate action.

   *Note:* `syslog' normally uses `UDP' for its network communications
and that `UDP' does not guarantee delivery.


File: nana.info,  Node: GNU,  Next: Embedded Systems,  Prev: Syslog,  Up: Usage

GNU Programs: how to avoid nana sometimes
=========================================

   Imagine you(1) are building a GNU program.  Ideally it should run on
systems without any other software including GCC, GDB and even Nana.

   To achieve this noble goal you can provide your configure script
with a `--without-nana'(2) flag which then `#define's' `WITHOUT_NANA'.
You should also use the `VL' macro rather than `L' macro since `L'
takes a variable number of arguments and will break non GNU C
preprocessors.

     int half(int n) {
       /* Don't use L(...) since it takes a variable number of args! */
       VL(("hello world = %d\n", 10)); /* Note the doubled (( */
       ...;
     }

   ---------- Footnotes ----------

   (1) Gordon Matzigkeit contributed some of the ideas presented here
and raised this problem.

   (2) Or add a `--with-nana' flag to configure that does the opposite.


File: nana.info,  Node: Embedded Systems,  Next: Realtime,  Prev: GNU,  Up: Usage

Embedded Systems: testing non-deterministic systems.
====================================================

   One of the uses (in fact the original use) for nana is in the
testing of non-deterministic systems. These systems behave in a
different way each time they are run because of timing or measurement
noise. Thus you can't just `diff' the results against a known good run
since they run differently each time.

   Instead you can use a series of programs which execute over a the
results of the program and check that the behaviour meets the
specification automatically.


File: nana.info,  Node: Realtime,  Next: A database,  Prev: Embedded Systems,  Up: Usage

Realtime Systems
================

   Assertions for the timing behaviour of you system can be done in nana
nicely. You might also consider using an instruction level simulator
such as PSIM and use the `cycles' variable to test realtime constraints.


File: nana.info,  Node: A database,  Next: Visualisation,  Prev: Realtime,  Up: Usage

A database
==========

   Ah databases, business boffins using assertions. It would nice to
get a real example for this one!


File: nana.info,  Node: Visualisation,  Prev: A database,  Up: Usage

Program Visualisation: pretty pictures
======================================

   One nice way to use `L', `DL', etc is to punt off the messages off
to a program which displays the information. You would use the
`L_DEFAULT_PARAM' argument to send commands off to a pipe with gnuplot
or TCL/TK interpreter running at the end.

   For a small example of this, see `tcl/status.c'.


File: nana.info,  Node: FAQ,  Next: Future,  Prev: Usage,  Up: Top

FAQ
***

   This chapter is intended to answer some general questions about the
usage of Nana. Most of the material (perhaps) has been presented
elsewhere, my apologies for repeating myself.

  1. Can I use GNU Nana in a commercial product?

     See the license details in the file `COPYING'. In summary GNU Nana
     is Free software which has been released under a license that
     allows commercial use provided the copyright is maintained. It is
     not under the GPL.

  2. How do you completely disable assertion checking?

     Set the `I_LEVEL' command to `0' using `-D' or `#define' before
     including `nana.h'.

  3. How do I find out about future releases?

     Subscribe to the nana mailing list by using the `make subscribe'
     target in the nana root directory.

  4. Where do I send bug reports, suggestions, etc?

     `nana-bug@it.ntu.edu.au' - bug archive

     `nana@it.ntu.edu.au' - mailing list

     `pjm@gnu.org' - the author



File: nana.info,  Node: Future,  Next: Index,  Prev: FAQ,  Up: Top

Future work
***********

   As usual, there is more work to be done than time to do it in.
Workers or test pilots are invited to apply for the following tasks
which may get down in the fullness of time minister.  I'm particularly
interested in which projects people think are worthwhile (or rubbish).

  1. Ada support - pre 1.00 versions of nana provided support for
      Ada. Adding a full version of nana into the GNATS compiler
      would probably be useful, particularly the real time part.

  2. FORTRAN support.

  3. Message browsing (`emacs/fess.el') - a very prototypical mode for
     browsing message logs is distributed with nana. Features include
     hiding/showing lines by regular expression or predicate. If
     someone who knows what they are doing rewrites this that would be
     a good thing. Or perhaps a modified version of `less' would be
     useful.

  4. Program Visualisation (`tcl/status.c') - another prototype which
     uses a small TCL/TK library and nana logging to generate some nice
     pictures showing the behaviour of the program. For example the
     history of variables over time can be recorded, graphs drawn and
     long message logs kept. A new version of this has been created and
     may be released shortly.

  5. Automated Testing - combine nana logs with a workbench that lets
     you verify properties of the logs using programs `gawk' or the
     `PRECC' (LL infinity version of YACC). This technique has been
     used on industrial strength products quite successfully.

  6. GNU standards - perhaps it would be worthwhile to set up a
     prototype for checking and logging in GNU tools.

  7. Extend GDB(1) so that we can support `Q.h' style quantifiers in
     `DI.h' expressions. Basically we need to add a restricted form of
     the statement value expression to GDB.

  8. Support for other (particularly ANSI only) compilers.


File: nana.info,  Node: Index,  Prev: Future,  Up: Top

Index
*****

* Menu:

* ( <1>:                                 Qstl.h.
* (:                                     Q.h.
* 0 <1>:                                 DI.h.
* 0 <2>:                                 I.h.
* 0 <3>:                                 DL.h.
* 0:                                     L.h.
* 1 <1>:                                 L.h.
* 1 <2>:                                 I.h.
* 1 <3>:                                 DI.h.
* 1:                                     DL.h.
* 2 <1>:                                 DL.h.
* 2 <2>:                                 DI.h.
* 2 <3>:                                 I.h.
* 2:                                     L.h.
* A <1>:                                 Q.h.
* A:                                     Introduction.
* abort():                               Variables.
* ALWAYS_INCLUDE_MALLOC:                 Variables.
* AO:                                    Qstl.h.
* asm("hlt"):                            Variables.
* asm("unimp"):                          Variables.
* C <1>:                                 Introduction.
* C:                                     Q.h.
* calls_add:                             calls.h.
* calls_delete:                          calls.h.
* calls_exec:                            calls.h.
* CHECK:                                 REQUIRE....
* CHECK_ALL:                             EIFFEL_CHECK.
* CHECK_ENSURE:                          EIFFEL_CHECK.
* CHECK_INVARIANT:                       EIFFEL_CHECK.
* CHECK_LOOP:                            EIFFEL_CHECK.
* CHECK_NO:                              EIFFEL_CHECK.
* CHECK_REQUIRE:                         EIFFEL_CHECK.
* CO:                                    Qstl.h.
* cycles:                                cycles.h.
* CYCLES:                                cycles.h.
* cycles_diff:                           cycles.h.
* cycles_per_second:                     cycles.h.
* cycles_per_second_max:                 cycles.h.
* cycles_per_second_min:                 cycles.h.
* DI:                                    DI.h.
* DI.h:                                  nana.h.
* DI_DEFAULT_GUARD:                      DI.h.
* DI_DEFAULT_HANDLER:                    DI.h.
* DI_DEFAULT_PARAMS:                     DI.h.
* DI_LEVEL:                              DI.h.
* DI_MAKE_VALID_BREAKPOINT <1>:          Variables.
* DI_MAKE_VALID_BREAKPOINT:              DI.h.
* DIG:                                   DI.h.
* DIGH:                                  DI.h.
* DIGHP:                                 DI.h.
* DIGP:                                  DI.h.
* DIH:                                   DI.h.
* DIHP:                                  DI.h.
* DIP:                                   DI.h.
* DL:                                    DL.h.
* DL.h:                                  nana.h.
* DL_DEFAULT_GUARD:                      DL.h.
* DL_DEFAULT_HANDLER:                    DL.h.
* DL_DEFAULT_PARAMS:                     DL.h.
* DL_LEVEL:                              DL.h.
* DL_MAKE_VALID_BREAKPOINT:              Variables.
* DL_SHOW_TIME:                          DL.h.
* DLG:                                   DL.h.
* DLGHP:                                 DL.h.
* DLGP:                                  DL.h.
* DLH:                                   DL.h.
* DLHP:                                  DL.h.
* DLP:                                   DL.h.
* DN:                                    DI.h.
* DNG:                                   DI.h.
* DNGH:                                  DI.h.
* DNGHP:                                 DI.h.
* DNGP:                                  DI.h.
* DNH:                                   DI.h.
* DNHP:                                  DI.h.
* DNP:                                   DI.h.
* DS:                                    DI.h.
* DSG:                                   DI.h.
* E <1>:                                 Introduction.
* E:                                     Q.h.
* E1 <1>:                                Q.h.
* E1:                                    Introduction.
* E1O:                                   Qstl.h.
* ENSURE:                                REQUIRE....
* EO:                                    Qstl.h.
* exprn <1>:                             DI.h.
* exprn:                                 I.h.
* file <1>:                              DI.h.
* file:                                  I.h.
* gcc-2.7.2:                             Required Software.
* GDB <1>:                               GDB.h.
* GDB:                                   Variables.
* gdb-4.16+:                             Required Software.
* GDB.h:                                 nana.h.
* GDBCALL:                               GDB.h.
* gmake:                                 Required Software.
* I:                                     I.h.
* I.h:                                   nana.h.
* I_DEFAULT_GUARD:                       I.h.
* I_DEFAULT_HANDLER <1>:                 Variables.
* I_DEFAULT_HANDLER:                     I.h.
* I_DEFAULT_PARAMS:                      I.h.
* I_LEVEL:                               I.h.
* ID:                                    I.h.
* IG:                                    I.h.
* IGH:                                   I.h.
* IGHP:                                  I.h.
* IGP:                                   I.h.
* IH:                                    I.h.
* IHP:                                   I.h.
* INVARIANT:                             REQUIRE....
* IP:                                    I.h.
* IS:                                    I.h.
* ISG:                                   I.h.
* L:                                     L.h.
* L.h:                                   nana.h.
* L_BUFFER:                              L_buffer.h.
* L_buffer_clear:                        L_buffer.h.
* L_buffer_create:                       L_buffer.h.
* L_buffer_delete:                       L_buffer.h.
* L_buffer_dump:                         L_buffer.h.
* L_buffer_printf:                       L_buffer.h.
* L_buffer_putchar:                      L_buffer.h.
* L_buffer_puts:                         L_buffer.h.
* L_buffer_wraparound:                   L_buffer.h.
* L_DEFAULT_GUARD:                       L.h.
* L_DEFAULT_HANDLER:                     L.h.
* L_DEFAULT_PARAMS:                      L.h.
* L_LEVEL:                               L.h.
* L_SHOW_TIME:                           L.h.
* L_SHOW_TIME_FORMAT:                    L.h.
* L_SHOW_TIME_NOW:                       L.h.
* L_TIMES:                               L_times.h.
* L_times_add:                           L_times.h.
* L_times_clear:                         L_times.h.
* L_times_create:                        L_times.h.
* L_times_delete:                        L_times.h.
* L_times_dump:                          L_times.h.
* L_times_wraparound:                    L_times.h.
* LG:                                    L.h.
* LGHP:                                  L.h.
* LGP:                                   L.h.
* LH:                                    L.h.
* LHP:                                   L.h.
* line <1>:                              DI.h.
* line:                                  I.h.
* LP:                                    L.h.
* N:                                     I.h.
* nana-clg:                              Invoking.
* nana-run:                              Invoking.
* nana-trace:                            Invoking.
* NG:                                    I.h.
* NGH:                                   I.h.
* NGHP:                                  I.h.
* NGP:                                   I.h.
* NH:                                    I.h.
* NHP:                                   I.h.
* now:                                   now.h.
* now_delta:                             now.h.
* now_reset:                             now.h.
* NP:                                    I.h.
* P:                                     Introduction.
* param <1>:                             I.h.
* param:                                 DI.h.
* Q.h:                                   nana.h.
* REQUIRE:                               REQUIRE....
* restart():                             Variables.
* S:                                     Introduction.
* struct:                                calls.h.
* typedef:                               calls.h.
* VDL:                                   DL.h.
* VDLG:                                  DL.h.
* VDLGHP:                                DL.h.
* VDLGP:                                 DL.h.
* VDLH:                                  DL.h.
* VDLHP:                                 DL.h.
* VDLP:                                  DL.h.
* VL:                                    L.h.
* VLG:                                   L.h.
* VLGHP:                                 L.h.
* VLGP:                                  L.h.
* VLH:                                   L.h.
* VLHP:                                  L.h.
* VLP:                                   L.h.


