Debugger-Tutorial

#### Search Results

Search

# Debugger-Tutorial

In diesem Tutorial werden die grundlegenden Funktionen des Debuggers vorgestellt und verschiedene Debugging-Methoden besprochen. Das Tutorial führt Sie durch ein einfaches Szenario, das demonstriert, wie der Debugger verwendet werden kann, um Laufzeitfehler zu analysieren und die Programmausführung zu kontrollieren.

Es ist wichtig, dass Sie die Sitzungen 1 bis 5 nacheinander durcharbeiten.

Anmerkungen:

1. Der Einfachheit halber zitiert das Tutorial hauptsächlich Direktkommandos zur Demonstration der Debugger-Funktionen und nicht die alternativen Menü-Funktionen.
2. Eine vollständige Beschreibung aller Debugger-Funktionen, die in diesem Tutorial erwähnt werden, finden Sie in den anschließenden Kapiteln der Debugger-Dokumentation.

- Voraussetzungen

- Grundlagen des Debugging

- Sitzung 1 - Analyse eines Natural-Fehlers

- Sitzung 2 - Einen Breakpoint benutzen

- Sitzung 3 - Einen Watchpoint benutzen

- Sitzung 4 - Verfolgen des logischen Ablaufs von Programmen

- Sitzung 5 - Verwendung von Statistiken über die Programmausführung

- Weitere Hinweise zur Benutzung des Debuggers

- Quellcode-Beispiele

## Voraussetzungen

- Sie sollten mit der Programmierung in Natural vertraut sein

- Bevor Sie mit Sitzung 1 beginnen, müssen Sie alle Beispielprogramme (`DEBUG1P` und `DEBUG2P`) und Subprogramme (`DEBUG1N`, `DEBUG2N`, `DEBUG3N` und `DEBUG4N`) erstellen, die im Abschnitt Beispiel-Quellcode weiter unten in diesem Tutorial vorhanden sind. Speichern und katalogisieren Sie diese Objekte mit dem Systemkommando `STOW`.

## Grundlagen des Debugging

Mit dem Debugger können Sie den Ausführungsfluss eines Natural-Objekts bei einem bestimmten Debug-Event (Ereignis) unterbrechen und Informationen zum aktuellen Status des unterbrochenen Objekts, z.B. das nächste auszuführende Statement, den Wert einer Variablen oder die Hierarchie (Programmebenen) aufgerufener Objekte erhalten.

Grundsätzlich müssen Sie die folgenden zwei Hauptschritte ausführen, um die Kontrolle an den Debugger für die Programmunterbrechung zu übergeben:

1. Aktivieren Sie den Debugger mit dem Systemkommando `TEST ON`.

   Dadurch kann der Debugger die Steuerung für jedes auszuführende Statement erhalten.

2. Setzen Sie einen oder mehrere Debug-Einträge (Breakpoints und Watchpoints) für die Natural-Objekte, die ausgeführt werden sollen.

   Dadurch kann der Debugger entscheiden, wann er die Kontrolle vom Natural-Laufzeitsystem übernimmt und die Programmausführung stoppt.

   Ein Natural-Fehler führt immer zur Unterbrechung des Programms.

   Es ist dann keine Debug-Eingabe erforderlich, der Debugger greift automatisch ein.

Im Folgenden finden Sie eine Übersicht über alle möglichen Programmunterbrechungen:

Programmunterbrechung | Erklärung
--- | ---
Breakpoint | Haltepunkt: Bewirkt eine Programmunterbrechung für eine Statement-Zeile in einem Natural-Objekt. Der Debugger unterbricht das Programm, sobald die Statement-Zeile, für die ein Breakpoint gesetzt ist, ausgeführt werden soll, d.h., bevor das in dieser Zeile enthaltene Statement verarbeitet wird.
Watchpoint | Haltepunkt: Bewirkt eine Programmunterbrechung für eine Variable in einem Natural-Objekt. Der Debugger unterbricht das Programm, sobald sich der Inhalt der Variablen, für die ein Watchpoint gesetzt ist, geändert hat, d.h., nachdem das Statement, das diese Variable referenziert, verarbeitet wird.
Step-Modus | Einzelschritt-Modus: Das Objekt wird schrittweise während der Programmausführung durchlaufen. Der Step-Modus wird durch ein Debugger-Kommando eingeleitet. Dazu muss der Debugger zuvor wegen eines Breakpoint- oder Watchpoint-Haltepunkts die Kontrolle erhalten haben. Im Step-Modus unterbricht der Debugger die Programmausführung, bevor ein ausführbares Statement, das in diesem Objekt enthalten ist, verarbeitet wird.
Natural-Fehler | Bewirkt eine automatische Programmunterbrechung.

## Sitzung 1 - Analyse eines Natural-Fehlers

Diese Sitzung beschreibt Untersuchungsmethoden für einen Natural-Fehler, der während der Programmausführung auftritt.

Um einen Natural-Fehler zu simulieren:

1. Führen Sie an der Eingabeaufforderung `NEXT` das Beispielprogramm `DEBUG1P` aus.

   Es erscheint folgende Natural-Meldung: `DEBUG1N 0180 NAT0954 Abnormal termination S0C7 during program execution.` (Abnormale Beendigung S0C7 während der Programmausführung).

   Die Meldung verweist auf die Zeile 180 im Subprogramm `DEBUG1N`: `BONUS := SALARY * PERCENT / 100`. Dies zeigt an, dass von einer oder mehreren der referenzierten Variablen falsche Werte zurückgegeben werden. Dies ist jedoch noch kein eindeutiger Hinweis darauf, was das Problem tatsächlich verursacht, und es könnte schwierig sein, die Ursache zu ermitteln, wenn die Variablenwerte aus einer Datenbank abgerufen wurden, so wie es typisch ist für Mitarbeiter-Datensätze (Employees Records).

Um den Debugger für die weitere Untersuchung des Problems zu aktivieren:

1. Geben Sie an der Eingabeaufforderung `NEXT` Folgendes ein:

       TEST ON

   Die Meldung `Test mode started.` (Test-Modus gestartet) zeigt an, dass der Debugger aktiviert ist.

   Anmerkung
   `TEST ON` bleibt aktiv für die Dauer der aktuellen Sitzung oder solange, bis Sie `TEST OFF` eingeben, um den Debugger zu deaktivieren.

2. Führen Sie an der Eingabeaufforderung `NEXT` wieder das Beispielprogramm `DEBUG1P` aus.

   Das Fenster Debug Break erscheint (Beispiel):

       +------------------- Debug Break -------------------+
       | Break by ABEND S0C7 at NATARI2+2A4-4 (NAT0954)    |
       | at line  180 in subprogram DEBUG1N (level 2)      |
       | in library DEBUG    in system file (10,32).       |
       |                                                   |
       |         G   Go                                    |
       |         L   List break                            |
       |         M   Debug Main Menu                       |
       |         N   Next break command                    |
       |         R   Run (set test mode OFF)               |
       |         S   Step mode                             |
       |         V   Variable maintenance                  |
       |                                                   |
       | Code .. G                                         |
       |                                                   |
       | Abnormal termination S0C7 during program execution|
       | PF2=Step,PF13=Next,PF14=Go,PF15=Menu,PF17=SkipS   |
       +---------------------------------------------------+

   Weil ein Natural-Fehler auftritt, greift der Debugger automatisch ein und zeigt das Fenster Debug Break.

   Am oberen Rand des Fensters werden zusätzliche Informationen dazu angezeigt, wo der Fehler auftritt: Das Modul (`NATARI2`) im Natural-Nucleus (nützlich für den Software AG Technical Support), der Objekttyp (`subprogram`), die Library (`DEBUG`) und die Datenbankkennung und Dateinummer (`10,32`) der Systemdatei.

   Außerdem sind im Fenster Debug Break Debugger-Funktionen verfügbar, die Sie benutzen können, um z.B. die Programmausführung fortzusetzen (Go oder Run), das Debugger-Hauptmenü (Debug Main Menu) aufzurufen oder den Step-Modus zu aktivieren. Sie können dazu entweder den entsprechenden Kennbuchstaben im Feld Code eingeben und Enter drücken oder die entsprechende PF-Taste drücken.

Um die fehlerhafte Statement-Zeile zu untersuchen:

1. Ersetzen Sie im Feld Code den Standardeintrag `G` durch `L`, um die Funktion List break auszuführen.

   Der Quellcode des Beispielprogramms `DEBUG1N` wird angezeigt:

       13:48:54              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON                - List Object Source -              Object DEBUG1N
                                                                        Bottom of data
       Co Line Source                                                    Message
       __ 0070   2 NUMCHILD  (N2)                                      |
       __ 0080   2 ENTRYDATE (D)                                       |
       __ 0090   2 SALARY    (P7.2)                                    |
       __ 0100   2 BONUS     (P7.2)                                    |
       __ 0110 LOCAL                                                   |
       __ 0120 1 TARGETDATE  (D)    INIT <D'2009-01-01'>               |
       __ 0130 1 DIFFERENCE  (P3.2)                                    |
       __ 0140 1 PERCENT     (P2.2) INIT <3.5>                         |
       __ 0150 END-DEFINE                                              |
       __ 0160 DIFFERENCE := (TARGETDATE - ENTRYDATE) / 365            |
       __ 0170 IF DIFFERENCE GE 10        /* BONUS FOR YEARS IN COMPAN | last line
       __ 0180   BONUS := SALARY * PERCENT / 100                       | * NAT0954 *
       __ 0190 END-IF                                                  |
       __ 0200 SALARY := SALARY + 1800    /* SALARY PLUS ANNUAL INCREA |
       __ 0210 END                                                     |

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Scan  Flip  -     +     Li Br <     >     Canc

   Die Meldung `last line` (letzte Zeile) zeigt an, dass das in Zeile 170 enthaltene Statement das letzte Statement ist, das erfolgreich ausgeführt wurde.

   Das Statement in Zeile 180, welches das Problem verursacht, ist hervorgehoben und mit der Anmerkung `* NAT0954 *` markiert.

   Dies zeigt an, dass der Fehler durch den Inhalt der Variablen `SALARY` (Gehalt) oder `PERCENT` (Prozent) verursacht wird. Höchstwahrscheinlich handelt es sich um `SALARY`, da `PERCENT` korrekt initialisiert ist.

Um den Inhalt der Variablen `SALARY` zu prüfen:

1. Geben Sie Folgendes in der Kommandozeile ein:

       DIS VAR SALARY

   Der Bildschirm Display Variable wird für die Variable `SALARY` angezeigt (Beispiel):

       18:59:51              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON          - Display Variable (Alphanumeric) -       Object DEBUG1N

       Name ...... EMPLOYEE.SALARY
       Fmt/Len ... P 7.2
       Type ...... parameter
       Index .....
       Range .....

       Position ..
       Contents ..

       Command ===>

       Variable contains invalid data.

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Mod   Flip              Li Br Alpha Hex   Canc

   Die Meldung `Variable contains invalid data.` (Variable enthält ungültige Daten) zeigt an, dass der Inhalt der Variablen, die scheinbar leer ist, nicht dem Format der Variablen entspricht. Dies wird deutlich, wenn Sie, wie im folgenden Schritt beschrieben, die hexadezimale Darstellung des Variableninhalts betrachten.

2. Drücken Sie PF11 (Hex), um den hexadezimalen Inhalt der Variablen anzuzeigen.

   Der Bildschirm sieht nun ähnlich aus wie im folgenden Beispiel:

       11:13:33              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON          - Display Variable (Hexadecimal) -        Object DEBUG1N

       Name ...... EMPLOYEE.SALARY
       Fmt/Len ... P 7.2
       Type ...... parameter
       Index .....
       Range .....

       Position ..
       Contents .. 4040404040

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Mod   Flip              Li Br Alpha Hex   Canc

   Der hexadezimale Wert zeigt, dass die Variable nicht in gepacktem numerischem Format vorliegt, was folglich bei der Programmausführung zu einem Rechenfehler führt. Das Programm `DEBUG1P` übergibt dem Subprogramm `DEBUG1N` einen inkorrekten Wert für die Variable `SALARY`.

   Tipp
   Sie können PF10 (Alpha) drücken, um wieder zur alphanumerischen Darstellung zurück zu wechseln.

3. Geben Sie in der Kommandozeile Folgendes ein:

       GO

   Das Kommando `GO` bewirkt, dass die Kontrolle vom Debugger an das Natural-Laufzeitsystem zurückgegeben und dass die Ausführung des Programms bis zum Programmende oder bis zum nächsten Debug-Ereignis (Event) fortgesetzt wird. Im vorliegenden Fall gibt es kein zusätzliches Debug-Ereignis. Die Eingabeaufforderung `NEXT` erscheint mit der bekannten Natural-Fehlermeldung (s.o.).

Um die Variable `SALARY` im Objekt-Quellcode zu korrigieren:

1. Öffnen Sie das Programm `DEBUG1P` mit dem Programm-Editor und entfernen Sie das das für `SALARY := 99000` eingegebene Kommentarzeichen (*).

2. Benutzen Sie das Systemkommando `STOW`, um das geänderte Programm zu speichern und zu katalogisieren.

3. Führen Sie das Programm `DEBUG1P` aus.

   Der Debugger unterbricht das Programm nicht, obwohl immer noch `TEST ON` gesetzt ist. Das Programm wird erfolgreich ausgeführt und gibt einen Bericht aus:

       Page      1                                                  07-09-06  15:28:06

       EMPLOYEE RECEIVES:   100800.00
           PLUS BONUS OF:     3465.00

       NEXT                                                               LIB=DEBUG

## Sitzung 2 - Einen Breakpoint benutzen

Sie können die Programmausführung an einer bestimmten Statement-Zeile unterbrechen, indem Sie einen Breakpoint (Haltepunkt) für diese Zeile setzen.

Um für eine Zeile im Subprogramm `DEBUG1N` einen Breakpoint zu setzen:

1. Geben Sie Folgendes an der Eingabeaufforderung `NEXT` ein:

       TEST SET BP DEBUG1N 170

   Die Meldung `Breakpoint DEBUG1N0170 set at line 170 of object DEBUG1N.` erscheint. Sie bestätigt, dass für die Statement-Zeile 170 im Subprogramm `DEBUG1N` ein Breakpoint mit dem Namen `DEBUG1N0170` gesetzt ist.

   Anmerkungen:

   1. Ein Breakpoint kann nur für ein ausführbares Statement gesetzt werden. Falls Sie versuchen, für ein nicht ausführbares Statement einen Breakpoint zu setzen, erscheint eine entsprechende Fehlermeldung.
   2. Normalerweise ist ein Breakpoint nur während der aktuellen Natural-Sitzung gültig. Falls erforderlich, können Sie einen Breakpoint für zukünftige Sitzungen speichern. Weitere Informationen siehe Breakpoints und Watchpoints speichern in Weitere Hinweise zur Benutzung des Debuggers.

2. Führen Sie das Programm `DEBUG1P` aus.

   Der Debugger unterbricht nun die Programmausführung an der Statement-Zeile, bei der der neue Breakpoint gesetzt ist. Das Fenster Debug Break erscheint:

        +------------------- Debug Break -------------------+
        | Break by breakpoint DEBUG1N0170                   |
        | at line  170 in subprogram DEBUG1N (level 2)      |
        | in library DEBUG    in system file (10,32).       |
        |                                                   |
        |         G   Go                                    |
        |         L   List break                            |
        |         M   Debug Main Menu                       |
        |         N   Next break command                    |
        |         R   Run (set test mode OFF)               |
        |         S   Step mode                             |
        |         V   Variable maintenance                  |
        |                                                   |
        | Code .. G                                         |
        |                                                   |
        |                                                   |
        | PF2=Step,PF13=Next,PF14=Go,PF15=Menu,PF17=SkipS   |
        +---------------------------------------------------+

   Das Fenster zeigt den Namen des Breakpoints, die entsprechende Statement-Zeile, das Objekt und die Library, in der das Objekt enthalten ist. Es zeigt auch die Bearbeitungsebene (Level) des Subprogramms `DEBUG1N`.

Um das im Fenster Debug Break gezeigte Statement zu betrachten:

- Führen Sie die Funktion List break aus.

  Der Quellcode des Subprogramms `DEBUG1N` wird im Bildschirm List Object Source angezeigt:

      11:36:45              ***** NATURAL TEST UTILITIES *****             2007-09-06
      Test Mode ON                - List Object Source -              Object DEBUG1N
                                                                       Bottom of data
      Co Line Source                                                    Message
      __ 0070   2 NUMCHILD  (N2)                                      |
      __ 0080   2 ENTRYDATE (D)                                       |
      __ 0090   2 SALARY    (P7.2)                                    |
      __ 0100   2 BONUS     (P7.2)                                    |
      __ 0110 LOCAL                                                   |
      __ 0120 1 TARGETDATE  (D)    INIT <D'2009-01-01'>               |
      __ 0130 1 DIFFERENCE  (P3.2)                                    |
      __ 0140 1 PERCENT     (P2.2) INIT <3.5>                         |
      __ 0150 END-DEFINE                                              |
      __ 0160 DIFFERENCE := (TARGETDATE - ENTRYDATE) / 365            | last line
      __ 0170 IF DIFFERENCE GE 10        /* BONUS FOR YEARS IN COMPAN | DEBUG1N0170
      __ 0180   BONUS := SALARY * PERCENT / 100                       |
      __ 0190 END-IF                                                  |
      __ 0200 SALARY := SALARY + 1800    /* SALARY PLUS ANNUAL INCREA |
      __ 0210 END                                                     |

      Command ===>

      Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
            Help  Step  Exit  Last  Scan  Flip  -     +     Li Br <     >     Canc

  Die im Fenster Debug Break angezeigte Statement-Zeile 170 ist hervorgehoben. In der Spalte Message wird der Name des für dieses Statement gesetzten Breakpoints (`DEBUG1N0170`) sowie die zuletzt ausgeführte Statement-Zeile angezeigt (die Zeile 160 ist als `last line` kommentiert).
  Zur Erinnerung: Ein Breakpoint unterbricht die Programmausführung vor dem Statement, für das der gesetzte Breakpoint verarbeitet wird.

  Es gibt mehrere Direktkommandos, die Sie auf dem Bildschirm List Object Source eingeben können, um weitere Informationen über das aktuelle Objekt zu erhalten. Sie können sich z. B. alle Variablen wie im folgenden Schritt beschrieben anzeigen lassen.

Um eine Liste der in `DEBUG1N` enthaltenen Variablen zu erhalten:

1. Geben Sie in der Kommandozeile Folgendes ein:

       DIS VAR

   Der Bildschirm Display Variables erscheint (Beipiel):

       11:06:13              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON         - Display Variables (Alphanumeric) -       Object DEBUG1N
                                                                                   All
       Co Le Variable Name                    F       Leng Contents               Msg.
           1 EMPLOYEE
       __  2 NAME                             A         20 MEIER
       __  2 ENTRYDATE                        D            1989-01-01
       __  2 SALARY                           P        7.2 99000.00
       __  2 BONUS                            P        7.2 *** invalid data ***
       __  1 TARGETDATE                       D            2009-01-01
       __  1 DIFFERENCE                       P        3.2 20.00
       __  1 PERCENT                          P        2.2 3.50

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Zoom  Flip  -     +     Li Br Alpha Hex   Canc

   Es werden alle in `DEBUG1N` definierten Variablen aufgelistet. Die Bemerkung `invalid data` (ungültige Daten) bei der Variablen `BONUS` können Sie unbeachtet lassen. Im vorliegenden Fall ist es nicht von Bedeutung, ob die Variable `BONUS` korrekt initialisiert wird, weil sie nur als Ziel-Operand benutzt wird.

   Um jedoch ein anderes Debugger-Kommando auszuführen, ändern Sie den Inhalt von `BONUS` im folgenden Schritt.

Um den Inhalt von `BONUS` zu prüfen und zu ändern:

1. Geben Sie in der Spalte Co neben `BONUS` folgendes Zeilenkommando ein:

       MO

   Oder:
   Geben Sie in der Kommandozeile Folgendes ein:

       MOD VAR BONUS

   Der Bildschirm Modify Variable wird angezeigt (Beispiel):

       11:29:50              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON          - Modify Variable (Alphanumeric) -        Object DEBUG1N

       Name ...... EMPLOYEE.BONUS
       Fmt/Len ... P 7.2
       Type ...... parameter
       Index .....
       Range .....

       Position .. 1
       Contents .. ___________

       Command ===>

       Variable contains invalid data.

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Save  Flip              Li Br Alpha Hex   Canc

2. Sie können die hexadezimale Anzeige benutzen, um sicherzustellen, dass die Variable nicht in Format P (gepackt numerisch) ist. Drücken Sie dazu PF10 (Alpha), um auf die alphanumerische Anzeige zurückzuschalten.

3. Geben Sie im Feld Contents einen Wert im Format P (numerisch gepackt) ein, z.B. `12345.00` und drücken Sie PF5 (Save).

   Der Bildschirm sieht nun folgendermaßen aus (Beispiel):

       11:50:00              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON          - Display Variable (Alphanumeric) -       Object DEBUG1N

       Name ...... EMPLOYEE.BONUS
       Fmt/Len ... P 7.2
       Type ...... parameter
       Index .....
       Range .....

       Position ..
       Contents .. 12345.00

       Command ===>

       Variable BONUS modified.

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Mod   Flip              Li Br Alpha Hex   Canc

   Die Änderung von Contents wird durch die Meldung `Variable BONUS modified.` (Variable `BONUS` geändert.) angezeigt.

4. Drücken Sie PF9 (Li Br) oder PF3 (Exit).

   Der Bildschirm List Object Source erscheint.

5. Geben Sie in der Kommandozeile Folgendes ein:

       GO

   Der Debugger gibt die Kontrolle an das Natural-Laufzeitsystem zurück, welches die Ausführung des Programms `DEBUG1P` beendet, weil kein weiteres Debug-Ereignis (Event) auftritt. Der vom Programm erstellte Bericht wird ausgegeben:

       Page      1                                                  07-09-06  10:02:51

       EMPLOYEE RECEIVES:   100800.00
           PLUS BONUS OF:     3465.00

       NEXT                                                               LIB=DEBUG

6. Bevor Sie fortfahren und mit der nächsten Sitzung beginnen, löschen Sie bitte alle aktuellen Breakpoints, indem Sie Folgendes an der Eingabeaufforderung `NEXT` eingeben:

       TEST DEL BP * *

   Es erscheint eine Meldung, die bestätigt, dass alle Breakpoints (im konkreten Fall nur ein Breakpoint) gelöscht sind.

## Sitzung 3 - Einen Watchpoint benutzen

Das Programm `DEBUG1P` und das Subprogramm `DEBUG1N` führen eine Berechnung für die Bonus- und Gehaltszahlung eines einzelnen Mitarbeiters durch. Wenn mehrere Mitarbeiterdatensätze verarbeitet würden, würden Sie wahrscheinlich prüfen, ob die Variable `BONUS` nun korrekt aktualisiert wird. Dies geschieht durch Setzen eines Watchpoints für diese Variable. Ein Watchpoint ermöglicht es dem Debugger, die Programmausführung zu unterbrechen, wenn sich der Inhalt der angegebenen Variablen ändert.

Um einen Watchpoint für die Variable `BONUS` zu setzen:

1. Geben Sie Folgendes an der Eingabeaufforderung `NEXT` ein:

       TEST SET WP DEBUG1N BONUS

   Die Meldung `Watchpoint BONUS set for variable EMPLOYEE.BONUS.` erscheint. Sie bestätigt, dass ein Watchpoint für die Variable `BONUS` in Beispiel-Subprogramm `DEBUG1N` gesetzt ist.

   Anmerkungen:

   1. Wenn Sie in der Kommandozeile eines Debugger-Bildschirms ein Debugger-Direktkommando eingeben, müssen Sie das Schlüsselwort `TEST` weglassen. Beispiel: Anstelle von `TEST SET WP DEBUG1N BONUS` geben Sie dann nur `SET WP DEBUG1N BONUS` ein.
   2. Normalerweise ist ein Watchpoint nur während der aktuellen Natural-Sitzung gültig. Falls erforderlich, können Sie einen Watchpoint für zukünftige Sitzungen speichern. Weitere Informationen siehe Breakpoints und Watchpoints speichern in Weitere Hinweise zur Benutzung des Debuggers.

2. Führen Sie das Programm `DEBUG1P` an der Eingabeaufforderung `NEXT` aus.

   Der Debugger unterbricht nun die Programmausführung an dem neuen Watchpoint. Das Fenster Debug Break erscheint:

       +------------------- Debug Break -------------------+
       | Break by watchpoint BONUS                         |
       | at line  180 in subprogram DEBUG1N (level 2)      |
       | in library DEBUG    in system file (10,32).       |
       |                                                   |
       |         G   Go                                    |
       |         L   List break                            |
       |         M   Debug Main Menu                       |
       |         N   Next break command                    |
       |         R   Run (set test mode OFF)               |
       |         S   Step mode                             |
       |         V   Variable maintenance                  |
       |                                                   |
       | Code .. G                                         |
       |                                                   |
       |                                                   |
       | PF2=Step,PF13=Next,PF14=Go,PF15=Menu,PF17=SkipS   |
       +---------------------------------------------------+

   In dem Fenster wird angezeigt, dass ein Watchpoint in Zeile 180 festgestellt wurde. Diese Zeile enthält das Statement, das die Variable `BONUS` verarbeitet.

   Der Debugger unterbrach die Programmausführung, nachdem das Statement für `BONUS` verarbeitet war. Erst dann konnte der Debugger erkennen, dass sich der Inhalt der Variablen geändert hat.

3. Führen Sie die Funktion List break aus.

   Der Bildschirm List Object Source erscheint (Beispiel):

       16:24:46              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON                - List Object Source -              Object DEBUG1N
                                                                        Bottom of data
       Co Line Source                                                    Message
       __ 0070   2 NUMCHILD  (N2)                                      |
       __ 0080   2 ENTRYDATE (D)                                       |
       __ 0090   2 SALARY    (P7.2)                                    |
       __ 0100   2 BONUS     (P7.2)                                    |
       __ 0110 LOCAL                                                   |
       __ 0120 1 TARGETDATE  (D)    INIT <D'2009-01-01'>               |
       __ 0130 1 DIFFERENCE  (P3.2)                                    |
       __ 0140 1 PERCENT     (P2.2) INIT <3.5>                         |
       __ 0150 END-DEFINE                                              |
       __ 0160 DIFFERENCE := (TARGETDATE - ENTRYDATE) / 365            |
       __ 0170 IF DIFFERENCE GE 10        /* BONUS FOR YEARS IN COMPAN | DEBUG1N0170
       __ 0180   BONUS := SALARY * PERCENT / 100                       | BONUS
       __ 0190 END-IF                                                  |
       __ 0200 SALARY := SALARY + 1800    /* SALARY PLUS ANNUAL INCREA |
       __ 0210 END                                                     |

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Scan  Flip  -     +     Li Br <     >     Canc

   Das Statement, welches die Variable `BONUS` referenziert, ist hervorgehoben. Die Meldung in der Spalte Message zeigt den Namen des für die Variable gesetzten Watchpoint.

Um auf Änderungen in `BONUS` zu prüfen:

1. Geben Sie in der Kommandozeile Folgendes ein:

       DIS VAR BONUS

   Der Bildschirm Display Variable erscheint. Im Feld Contents (Inhalt) wird der Wert `3465.00` angezeigt. Das zeigt, dass sich der Inhalt der Variablen `BONUS` geändert hat.

2. Drücken Sie PF3 (Exit), um zum Bildschirm List Object Source zurückzukehren.

Um auf Änderungen in `SALARY` zu prüfen:

1. Um den Inhalt der Variablen `SALARY` in einem späteren Schritt zu prüfen, setzen Sie einen Breakpoint für `SALARY`. Dazu geben Sie in der Spalte Co vor der Zeile 200 Folgendes ein:

       SE

   Vom Bildschirm List Object Source aus ist die Eingabe eines Zeilenkommandos wie `SE` eine bequeme Alternative zur Verwendung des Direktkommandos `SET BP`.

   In der Spalte Message wird angezeigt, dass ein Breakpoint (`BP`) für die Zeile 200 gesetzt ist:

       17:55:58              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON                - List Object Source -              Object DEBUG1N
                                                                        Bottom of data
       Co Line Source                                                    Message
       __ 0070   2 NUMCHILD  (N2)                                      |
       __ 0080   2 ENTRYDATE (D)                                       |
       __ 0090   2 SALARY    (P7.2)                                    |
       __ 0100   2 BONUS     (P7.2)                                    |
       __ 0110 LOCAL                                                   |
       __ 0120 1 TARGETDATE  (D)    INIT <D'2009-01-01'>               |
       __ 0130 1 DIFFERENCE  (P3.2)                                    |
       __ 0140 1 PERCENT     (P2.2) INIT <3.5>                         |
       __ 0150 END-DEFINE                                              |
       __ 0160 DIFFERENCE := (TARGETDATE - ENTRYDATE) / 365            |
       __ 0170 IF DIFFERENCE GE 10        /* BONUS FOR YEARS IN COMPAN | DEBUG1N0170
       __ 0180   BONUS := SALARY * PERCENT / 100                       | BONUS
       __ 0190 END-IF                                                  |
       __ 0200 SALARY := SALARY + 1800    /* SALARY PLUS ANNUAL INCREA | BP set
       __ 0210 END                                                     |

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Scan  Flip  -     +     Li Br <     >     Canc

2. Geben Sie in der Kommandozeile Folgendes ein:

       GO

   Das Fenster Debug Break erscheint:

       +------------------- Debug Break -------------------+
       | Break by breakpoint DEBUG1N0200                   |
       | at line  200 in subprogram DEBUG1N (level 2)      |
       | in library DEBUG    in system file (10,32).       |
       |                                                   |
       |         G   Go                                    |
       |         L   List break                            |
       |         M   Debug Main Menu                       |
       |         N   Next break command                    |
       |         R   Run (set test mode OFF)               |
       |         S   Step mode                             |
       |         V   Variable maintenance                  |
       |                                                   |
       | Code .. G                                         |
       |                                                   |
       |                                                   |
       | PF2=Step,PF13=Next,PF14=Go,PF15=Menu,PF17=SkipS   |
       +---------------------------------------------------+

3. Führen Sie die Funktion List break aus.

   Der Bildschirm List Object Source sieht jetzt wie im folgenden Beispiel aus:

       10:49:31              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON                - List Object Source -              Object DEBUG1N
                                                                        Bottom of data
       Co Line Source                                                    Message
       __ 0070   2 NUMCHILD  (N2)                                      |
       __ 0080   2 ENTRYDATE (D)                                       |
       __ 0090   2 SALARY    (P7.2)                                    |
       __ 0100   2 BONUS     (P7.2)                                    |
       __ 0110 LOCAL                                                   |
       __ 0120 1 TARGETDATE  (D)    INIT <D'2009-01-01'>               |
       __ 0130 1 DIFFERENCE  (P3.2)                                    |
       __ 0140 1 PERCENT     (P2.2) INIT <3.5>                         |
       __ 0150 END-DEFINE                                              |
       __ 0160 DIFFERENCE := (TARGETDATE - ENTRYDATE) / 365            |
       __ 0170 IF DIFFERENCE GE 10        /* BONUS FOR YEARS IN COMPAN | DEBUG1N0170
       __ 0180   BONUS := SALARY * PERCENT / 100                       | last line
       __ 0190 END-IF                                                  |
       __ 0200 SALARY := SALARY + 1800    /* SALARY PLUS ANNUAL INCREA | DEBUG1N0200
       __ 0210 END                                                     |

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Scan  Flip  -     +     Li Br <     >     Canc

   Da es sich hier um einen Breakpoint handelt, ist das Statement, das die Variable `SALARY` referenziert (und ändert), noch nicht ausgeführt worden. Folglich hat sich der Inhalt der Variablen nicht geändert.

4. Geben Sie `DIS VAR SALARY` in der Kommandozeile ein, um zu überprüfen, dass der er Inhalt der Variablen unverändert ist.

   Der Bildschirm Display Variable belegt, dass die Variable `SALARY` immer noch den Wert `99000` enthält. Dies ist der Anfangswert, der ihr im Programm `DEBUG1P` zugewiesen wurde.

5. Springen Sie nun zum nächsten Statement, um die Änderung des Variableninhalts zu betrachten. Wählen Sie eine der folgenden Methoden:

   Geben Sie in der Kommandozeile Folgendes ein:

       STEP

   Oder:
   Drücken Sie PF2 (Step).

   Der neue Bildschirm sieht ähnlich wie im folgenden Beispiel aus:

       13:38:24              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON                - List Object Source -              Object DEBUG1N
                                                                        Bottom of data
       Co Line Source                                                    Message
       __ 0070   2 NUMCHILD  (N2)                                      |
       __ 0080   2 ENTRYDATE (D)                                       |
       __ 0090   2 SALARY    (P7.2)                                    |
       __ 0100   2 BONUS     (P7.2)                                    |
       __ 0110 LOCAL                                                   |
       __ 0120 1 TARGETDATE  (D)    INIT <D'2009-01-01'>               |
       __ 0130 1 DIFFERENCE  (P3.2)                                    |
       __ 0140 1 PERCENT     (P2.2) INIT <3.5>                         |
       __ 0150 END-DEFINE                                              |
       __ 0160 DIFFERENCE := (TARGETDATE - ENTRYDATE) / 365            |
       __ 0170 IF DIFFERENCE GE 10        /* BONUS FOR YEARS IN COMPAN | DEBUG1N0170
       __ 0180   BONUS := SALARY * PERCENT / 100                       |
       __ 0190 END-IF                                                  |
       __ 0200 SALARY := SALARY + 1800    /* SALARY PLUS ANNUAL INCREA | last line
       __ 0210 END                                                     | step mode

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Scan  Flip  -     +     Li Br <     >     Canc

   Sie haben eine Zeile übersprungen und das nächste ausführbare Statement in Zeile 200 ausgeführt, welches die Variable `SALARY` ändert. In der Spalte Message wird angezeigt, dass Step-Modus gesetzt ist. Im Step-Modus setzt der Debugger die Programmausführung am nächsten ausführbaren Statement fort.

6. Geben Sie `DIS VAR SALARY` in der Kommandozeile ein, um den Variableninhalt zu prüfen.

   Der Bildschirm Display Variable erscheint und zeigt im Feld Contents einen Wert von `100800.00` an. Das belegt, dass sich der Inhalt der Variablen `SALARY` geändert hat.

7. Geben Sie in der Kommandozeile Folgendes ein:

       GO

   Der Debugger gibt die Kontrolle an das Natural-Laufzeitsystem zurück, welches die Ausführung des Programms `DEBUG1P` beendet, weil kein weiteres Debug-Ereignis (Event) auftritt. Der vom Programm erstellte Bericht wird ausgegeben.

## Sitzung 4 - Verfolgen des logischen Ablaufs von Programmen

Diese Sitzung beschreibt Debugging-Methoden, die Sie anwenden können, um eine komplexe Natural-Anwendung mit zahlreichen Objekten besser zu verstehen, zu überblicken und zu steuern.

Die Sitzung beginnt mit einer Anleitung zur Analyse des logischen Ablaufs einer Anwendung auf Statement-Ebene. Anschließend wird demonstriert, wie Breakpoints verwendet werden können, um die Reihenfolge der Programmausführung herauszufinden.

Die Anweisungen in dieser Sitzung basieren auf einer einfachen (aber zur Demonstration ausreichenden) Beispielanwendung. Diese besteht aus einem Programm (`DEBUG2P`) und drei Subprogrammen (`DEBUG2N`, `DEBUG3N` und `DEBUG4N`).

Um einen Breakpoint am Programmanfang oder -ende zu setzen:

1. Setzen Sie einen Breakpoint für `DEBUG2P`, indem Sie an der Eingabeaufforderung `NEXT` Folgendes eingeben:

       TEST SET BP DEBUG2P BEG

   Die Meldung `Breakpoint DEBUG2P-BEG set at line BEG of object DEBUG2P.` bestätigt, dass ein Breakpoint in `DEBUG2N` gesetzt ist.

   Die Verwendung des Schlüsselworts `BEG` anstelle einer bestimmten Zeilennummer bewirkt, dass der Breakpoint am Anfang des Programms, d. h. für das erste auszuführende Statement, gesetzt wird. Dies kann sogar das `DEFINE DATA`-Statement sein, wenn z. B. eine `INIT`-Klausel verwendet wird, die beim Katalogisieren des Programms ein ausführbares Statement erzeugt.

   Tipp
   Sie können auch das Schlüsselwort `END` angeben, um einen Breakpoint für das letzte auszuführende Statement zu setzen. Dies kann das `END`-Statement sein, aber auch das `FETCH`- oder `CALLNAT`-Statement.

2. Führen Sie das Programm `DEBUG2P` aus.

   Das Fenster Debug Break erscheint:

       +------------------- Debug Break -------------------+
       | Break by breakpoint DEBUG2P-BEG                   |
       | at line  130 in program DEBUG2P (level 1)         |
       | in library DEBUG    in system file (10,32).       |
       |                                                   |
       |         G   Go                                    |
       |         L   List break                            |
       |         M   Debug Main Menu                       |
       |         N   Next break command                    |
       |         R   Run (set test mode OFF)               |
       |         S   Step mode                             |
       |         V   Variable maintenance                  |
       |                                                   |
       | Code .. G                                         |
       |                                                   |
       |                                                   |
       | PF2=Step,PF13=Next,PF14=Go,PF15=Menu,PF17=SkipS   |
       +---------------------------------------------------+

   Der Debugger greift nun am ersten für das Programm gesetzten Breakpoint ein.

3. Führen Sie die Funktion List break aus, um den Quellcode zu prüfen und zu sehen, dass der Debugger jetzt am ersten ausführbaren Statement `NAME := 'MEIER'` eingreift.

Um eine Anwendung schrittweise auszuführen:

1. Setzen Sie im Bildschirm List Object Source den Step-Mode, indem Sie entweder PF2 (Step) drücken oder `STEP` in der Kommandozeile eingeben.

   Das zuletzt ausgeführte Statement ist mit `last line` (letzte Zeile) kommentiert. Das nächste auszuführende Statement ist hervorgehoben und mit `step mode` kommentiert.

   Tipp
   Wenn Sie nicht möchten, dass der Debugger bei jedem einzelnen Statement pausiert, sondern eine Anwendung schneller durchläuft, geben Sie im `STEP`-Kommando die Anzahl der Statements an, die Sie überspringen möchten, z.B.: `STEP 2` oder `STEP 10`.

2. Drücken Sie PF2 (Step) mehrmals, bis das `CALLNAT`-Statement mit `step mode` kommentiert ist.

3. Fahren Sie mit PF2 (Step) und führen Sie das `CALLNAT`-Statement aus.

   Das aufgerufene Subprogramm `DEBUG2N` wird angezeigt, wobei das nächste auszuführende Statement hervorgehoben ist:

       11:59:19              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON                - List Object Source -              Object DEBUG2N
                                                                           Top of data
       Co Line Source                                                    Message
       __ 0010 ** SUBPROGRAM DEBUG2N: CALLS 'DEBUG3N' AND 'DEBUG4N'FOR |
       __ 0020 ******************************************************* |
       __ 0030 DEFINE DATA                                             | step mode
       __ 0040 PARAMETER                                               |
       __ 0050 1 EMPLOYEE                                              |
       __ 0060   2 NAME      (A20)                                     |
       __ 0070   2 NUMCHILD  (N2)                                      |
       __ 0080   2 ENTRYDATE (D)                                       |
       __ 0090   2 SALARY    (P7.2)                                    |
       __ 0100   2 BONUS     (P7.2)                                    |
       __ 0110 LOCAL                                                   |
       __ 0120 1 TARGETDATE  (D)    INIT <D'2009-01-01'>               |
       __ 0130 1 DIFFERENCE  (P3.2)                                    |
       __ 0140 1 PERCENT     (P2.2) INIT <3.5>                         |
       __ 0150 END-DEFINE                                              |

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help  Step  Exit  Last  Scan  Flip  -     +     Li Br <     >     Canc

   Alternativ könnten Sie das `CALLNAT`-Statement überspringen, indem Sie `STEP SKIP` in der Kommandozeile eingeben.

   Sie würden dann nur die Statements in dem aufrufenden Programm `DEBUG2` schrittweise ausführen, jedoch nicht die Statements in einem aufgerufenen Programm.

Um die Ebenen zu betrachten, auf denen die Objekte ausgeführt werden:

1. Geben Sie im Bildschirm List Object Source für `DEBUG2N` Folgendes in der Kommandozeile ein:

       OBJCHAIN

   Der Bildschirm Break Information erscheint (Beispiel):

       13:45:34               ***** NATURAL TEST UTILITIES *****            2007-09-06
                                    - Break Information -

       No GDA active for the current program.

       Break by step mode
       at line   30 in subprogram DEBUG2N (level 2)
       in library DEBUG    in system file (10,32).

   Zusätzlich zu den bereits bekannten Objektinformationen zeigt dieser Bildschirm an, ob das Programm einen globalen Datenbereich (GDA, Global Data Area) referenziert.

2. Drücken Sie ENTER, um eine Seite weiter nach unten zu blättern.

   Der Bildschirm sieht jetzt aus wie im folgenden Beispiel:

       13:46:34               ***** NATURAL TEST UTILITIES *****            2007-09-06
                                  - Current Object Chain -

       Level Name     Type        Line Library   DBID   FNR
         2   DEBUG2N  Subprogram     0 DEBUG       10    32
         1   DEBUG2P  Program      170 DEBUG       10    32

   Dieser Bildschirm zeigt die Ebenen (Level) an, auf denen die Objekte ausgeführt werden: Subprogramm `DEBUG2N` wird auf Ebene 2 ausgeführt und das Programm `DEBUG2P` (welches das Subprogramm aufruft) wird auf der übergeordneten Ebene 1 ausgeführt.

3. Drücken Sie ENTER.

   Der Bildschirm List Object Source erscheint.

4. Geben Sie in der Kommandozeile Folgendes ein:

       GO

   Der Debugger gibt die Kontrolle zurück an das Natural-Laufzeitsystem. Dieses beendet die Ausführung von `DEBUG2P`, weil kein weiteres Debug-Ereignis auftritt. Der vom Programm erzeugte Bericht wird ausgegeben:

       Page      1                                                  07-09-06  10:04:21

       EMPLOYEE RECEIVES:    99300.00
           PLUS BONUS OF:     3565.00

       NEXT                                                               LIB=DEBUG

5. Löschen Sie alle zurzeit gesetzten Breakpoints, indem Sie Folgendes an der Eingabeaufforderung `NEXT` eingeben:

       TEST DEL BP * *

   Es erscheint eine Meldung, die bestätigt, dass alle Breakpoints gelöscht sind.

Um Breakpoints zur Verfolgung der Programmausführung zu setzen:

1. Geben Sie Folgendes an der Eingabeaufforderung `NEXT` ein:

       TEST SET BP ALL BEG

   Die Meldung `Breakpoint ALL-BEG set at line BEG of object ALL.` erscheint.

   Sie zeigt an, dass Sie einen Breakpoint für das erste ausführbare Statement jedes auszuführenden Objekts gesetzt haben.

2. Führen Sie das Programm `DEBUG2P` aus.

   Es erscheint ein Debug Break-Fenster für `DEBUG2P`.

3. Führen Sie die Funktion Go wiederholt aus.

   Jedes Mal, wenn Sie die Funktion Go ausführen, wird das nächste aufgerufene Objekt im Debug Break-Fenster angezeigt (`DEBUG2N` zuerst und dann `DEBUG3N` und `DEBUG4N`). So können Sie leicht feststellen, welche Objekte an welcher Stelle während der Programmausführung aufgerufen werden. Zusätzlich können Sie für jedes Objekt die Menüfunktionen des Debug Break-Fensters anwenden.

4. Wenn die Eingabeaufforderung `NEXT` erscheint, löschen Sie alle zurzeit gesetzten Breakpoints, indem Sie Folgendes eingeben:

       TEST DEL BP * *

   Es erscheint eine Meldung, die bestätigt, dass alle Breakpoints gelöscht sind.

## Sitzung 5 - Verwendung von Statistiken über die Programmausführung

Mit dem Debugger können Sie statistische Informationen darüber anzeigen, welche Objekte wie oft aufgerufen werden. Zusätzlich können Sie herausfinden, welche Statements ausgeführt werden und wie oft.

Um zu prüfen, welche Objekte während der Programmausführung aufgerufen werden:

1. Geben Sie Folgendes an der Eingabeaufforderung `NEXT` ein:

       TEST SET CALL ON

   Die Meldung `Call statistics started.` wird angezeigt. Sie bestätigt, das die Statistik-Funktion aktiviert ist.

2. Führen Sie das Programm `DEBUG2P` aus.

   Der Debugger protokolliert alle ausgeführten Objektaufrufe. Der vom Programm erstellte Bericht wird ausgegeben.

3. Geben Sie Folgendes an der Eingabeaufforderung `NEXT` ein:

       TEST DIS CALL

   Der Bildschirm Display Called Objects erscheint (Beispiel):

       10:43:47              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON              - Aufgerufene Objekte anzeigen-            Object
                                                                                   All
       Object   Library  Type         DBID   FNR S/C Ver Cat Date   Time       Calls
       *_______ DEBUG___
       DEBUG2P  DEBUG    Program        10    32 S/C 4.2 2007-08-30 13:48          1
       DEBUG2N  DEBUG    Subprogram     10    32 S/C 4.2 2007-08-30 13:48          1
       DEBUG3N  DEBUG    Subprogram     10    32 S/C 4.2 2007-08-30 13:48          1
       DEBUG4N  DEBUG    Subprogram     10    32 S/C 4.2 2007-08-30 13:48          1

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help        Exit  Last        Flip        +                       Canc

   Der Bildschirm zeigt eine Liste aller ausgeführten Objekte: Das aufrufende Programm (`DEBUG2P`) und alle anderen aufgerufenen Objekte (`DEBUG2N`, `DEBUG3N` und `DEBUG4N`). Außerdem wird angezeigt, wie oft ein Objekt aufgerufen wird (`CALLS`), der Typ des aufgerufenen Objekts, wo und unter welcher Natural-Version das Objekt gespeichert ist, ob Source-Objekte und katalogisierte Objekte existieren und wann das Objekt katalogisiert wurde.

4. Drücken Sie PF3 (Exit) oder PF12 (Canc) mehrmals, bis die Eingabeaufforderung `NEXT` erscheint.

Um zu prüfen, welche Statements während der Programmausführung ausgeführt werden:

1. Geben Sie Folgendes an der Eingabeaufforderung `NEXT` ein:

       TEST SET XSTAT COUNT

   Die Meldung `Statement execution counting started for library/object */*.` bestätigt, dass die Statistik-Funktion für alle Objekte aktiviert ist, die in der aktuellen Library und in allen, mit dieser Library verketteten Steplibs enthalten sind.

2. Führen Sie das Programm `DEBUG2P` aus.

   Der Debugger protokolliert alle von dem Programm verarbeiteten Statements. Anschließend wird der vom Programm erstellte Bericht ausgegeben.

3. Geben Sie Folgendes am Eingabeaufforderungszeichen `NEXT` ein:

       TEST DIS XSTAT

   Der Bildschirm List Statement Execution Statistics erscheint (Beispiel):

       11:39:10              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON        - List Statement Execution Statistics -     Object
                                                                                   All
       Co Object   Library  Type        DBID   FNR Obj.Called Exec Exec   %  Total No.
          *_______ *_______                           n Times able uted     Executions
       __ DEBUG2P  DEBUG    Program       10    32          1    8    8 100          8
       __ DEBUG2N  DEBUG    Subprogram    10    32          1    8    8 100          8
       __ DEBUG3N  DEBUG    Subprogram    10    32          1    2    2 100          2
       __ DEBUG4N  DEBUG    Subprogram    10    32          1   10    7  70          7

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help        Exit  Last        Flip  -     +                       Canc

   Der Bildschirm zeigt eine Liste. Diese enthält die Anzahl der Aufrufe (`Obj. Called n Times`), die Anzahl der ausführbaren Statements (`Exec(ecut)able`), die Anzahl der ausgeführten Statements (`Executed`), den Prozentsatz der ausgeführten Statements im Verhältnis zur Gesamtzahl der ausführbaren Statements (`%`) und die Gesamtzahl der ausgeführten Statements (`Total No. Executions`).

4. Geben Sie in der Spalte Co neben `DEBUG4N` Folgendes ein:

       DS

   Folgender Statistik-Bildschirm wird angezeigt (Beispiel):

       12:11:19              ***** NATURAL TEST UTILITIES *****             2007-09-06
       Test Mode ON             - Display Statement Lines -            Object DEBUG4N

       Line Source                                                              Count
       0010 ** SUBPROGRAM 'DEBUG4N': CALCULATES SPECIAL SALARY INCREASE
       0020 ************************************************************
       0030 DEFINE DATA
       0040 PARAMETER
       0050 1 SALARY (P7.2)
       0060 END-DEFINE
       0070 DECIDE FOR FIRST CONDITION                                              1
       0080   WHEN SALARY < 50000                                                   1
       0090     SALARY := SALARY + 1800                                  not executed
       0100   WHEN SALARY < 70000                                                   1
       0110     SALARY := SALARY + 1200                                  not executed
       0120   WHEN SALARY < 90000                                                   1
       0130     SALARY := SALARY + 600                                   not executed
       0140   WHEN NONE                                                             1
       0150     SALARY := SALARY + 300                                              1

       Command ===>

       Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
             Help        Exit  Last        Flip        +                       Canc

   Der Bildschirm zeigt an, wie oft ein Statement ausgeführt wurde und welche ausführbaren Statements nicht bearbeitet wurden.

## Weitere Hinweise zur Benutzung des Debuggers

Dieser Abschnitt enthält zusätzliche Hinweise zur Benutzung des Debuggers.

- Zeitstempel von Objekten

- Breakpoints und Watchpoints speichern

- Debug-Hauptmenü (Main Menu) für Verwaltungsfunktionen

- Hilfe zu Kommandos in Maintenance-Bildschirmen

- Während der Programmunterbrechung verfügbare Funktionen

- Next-Option für zusätzliche Kommandos während der Programmunterbrechung

- Große Variablen und Arrays anzeigen

- Debugger-Statistikberichte drucken

- Debugger im Batch-Modus benutzen

### Zeitstempel von Objekten

Ein katalogisiertes Objekt, das nicht genau mit dem Source-Objekt übereinstimmt, kann zu Fehlern bei der Fehlersuche führen. Wenn Sie sicherstellen wollen, dass Source-Objekt und katalogisiertes Objekt übereinstimmen, speichern und katalogisieren Sie sie mit dem Systemkommando `STOW`.

Weitere Informationen siehe Voraussetzungen für den Betrieb.

### Breakpoints und Watchpoints speichern

Sie können die in der aktuellen Sitzung gesetzten Breakpoints und Watchpoints als Debug-Umgebung speichern und diese Umgebung zur Verwendung in einer zukünftigen Sitzung laden. Dies ist hilfreich, wenn Sie eine Anwendung wiederholt mit denselben Debug-Einträgen testen wollen.

Weitere Informationen siehe Abschnitt Debug Environment Maintenance (Verwaltung der Debug-Umgebung).

### Debug-Hauptmenü (Main Menu) für Verwaltungsfunktionen

Alle Verwaltungsfunktionen des Debuggers, wie z. B. das Setzen eines Breakpoint oder das Erstellen einer Statistik, können entweder mit einem Direktkommando oder mit den Verwaltungsfunktionen im Hauptmenü (Debug Main Menu) ausgeführt werden. Um das Hauptmenü aufzurufen, haben Sie folgende Eingabemöglichkeiten:

- `TEST` an einer Eingabeaufforderung.

- `MENU` in der Kommandozeile eines Debugger-Bildschirms.

- `M` im Feld Code im Fenster Debug Break.

### Hilfe zu Kommandos in Maintenance-Bildschirmen

Sie können sich eine Liste der in einem Debugger-Maintenance-Bildschirm zur Verfügung stehenden Direktkommandos anzeigen lassen, indem Sie PF1 (Help) drücken oder in der Kommandozeile ein Fragezeichen (?) eingeben.

In einem Debugger-Maintenance-Bildschirm mit Listeneinträgen stehen außerdem Zeilenkommandos zur Verfügung, die Sie benutzen können, um einen Eintrag zu bearbeiten. Die Eingabe eines Zeilenkommandos erfolgt neben dem betreffenden Eintrag in der Spalte Co. Sie können in dieser Spalte ein Fragezeichen (?) eingeben, um eine Liste der gültigen Zeilenkommandos angezeigt zu bekommen.

### Während der Programmunterbrechung verfügbare Funktionen

Dieser Abschnitt enthält eine Liste der wichtigsten, während der Programmunterbrechung verfügbaren Funktionen. Sie können sie entweder im Fenster Debug Break oder in der Kommandozeile eines Debugger-Maintenance-Bildschirms ausführen.

Code im Debug Break-Fenster | Alternatives Direktkommando | Funktion
--- | --- | ---
`G` | `GO` | Fortsetzung der Programmausführung, bis das nächste Debug-Ereignis auftritt.
`L` | `LIST BREAK` | Auflistung der Objekt-Source bei der Statement-Zeile, in der das Debug-Ereignis auftritt.
`N` | `NEXT` | Ausführung des nächsten Break-Kommandos, wenn es für einen Breakpoint oder Watchpoint angegeben wurde. Siehe auch Next-Option für zusätzliche Kommandos während der Programmunterbrechung.
`R` | `RUN` | Ausschalten des Test-Modus und Fortsetzen der Programmausführung.
`S` | `STEP` | Zeilenweise Verarbeitung der ausführbaren Statements.
`V` | `DIS VAR` | Anzeige einer Liste der Variablen, die für das unterbrochene Objekt definiert sind.

### Next-Option für zusätzliche Kommandos während der Programmunterbrechung

Wenn Sie einen Breakpoint oder Watchpoint anzeigen oder ändern, werden Sie feststellen, dass an jeden von ihnen das Debugger-Kommando `BREAK` angehängt ist. Dieses Kommando ruft das Debug-Break-Fenster auf und darf nicht entfernt werden. Sie können jedoch zusätzliche Debugger-Kommandos angeben, die während der Programmunterbrechung nach dem `BREAK`-Kommando ausgeführt werden sollen. Ein zusätzlicher Befehl wird ausgeführt, wenn Sie entweder das Kommando `NEXT` in der Kommandozeile oder den Funktionscode `N` im Debug Break-Fenster eingeben.

Sie können die Debugger-Kommandos, wie im folgenden Beispiel gezeigt, im Feld Commands des entsprechenden Breakpoint- oder Watchpoint-Maintenance-Bildschirm eingeben:

    11:38:55              ***** NATURAL TEST UTILITIES *****             2007-09-06
    Test Mode ON                - Modify Breakpoint -               Object

    Spy number ..............   1
    Initial state ........... A (A = Active, I = Inactive)
    Breakpoint name ......... DEBUG1P0170_   DBID/FNR ....... 10/32
    Object name ............. DEBUG1P_       Library ........ DEBUG
    Line number ............. 0170
    Label ................... ________________________________
    Skips before execution .. ____0
    Max number executions ... ____0

    Commands ... BREAK_______________________________________________________
                 STACK_______________________________________________________
                 DIS VAR BONUS_______________________________________________
                 ____________________________________________________________
                 ____________________________________________________________
                 ____________________________________________________________

    Command ===>

    Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
          Help        Exit  Last  Save  Flip                                Canc

Im obigen Beispiel weist das Kommando `STACK` den Debugger an, den Natural Stack zu untersuchen. Das Kommando `DIS VAR BONUS` weist den Debugger an, die angegebene Variable anzuzeigen. Dies ist z. B. hilfreich, wenn Sie in einer Schleife einen Breakpoint setzen und immer nur den Wert einer bestimmten Variablen sehen wollen. Sie müssen dann nicht wiederholt das Kommando `DIS VAR` eingeben.

Weitere Informationen siehe Beschreibung des Feldes Commands in den Abschnitten Felder und Spalten in Breakpoint-Bildschirmen und Felder und Spalten in Watchpoint-Bildschirmen.

### Große Variablen und Arrays anzeigen

Der Bildschirm Display Variable zeigt alle Definitionen einer Variablen und zeigt ihren Inhalt in alphanumerischem oder hexadezimalem Format. Informationen zu Anzeigemöglichkeiten bei großen Variablen, deren Inhalt über den aktuellen Bildschirm hinausgeht, oder bei Variablen mit Array-Definitionen siehe Abschnitt Variable anzeigen - einzeln.

### Debugger-Statistikberichte drucken

Sie können die vom Debugger erstellten Statistikberichte drucken oder auf einen PC herunterladen.

Weitere Informationen siehe Objekte drucken im Abschnitt Call Statistics Maintenance (Statistiken über gerufene Objekte) und Statements drucken im Abschnitt Statement Execution Statistics Maintenance.

### Debugger im Batch-Modus benutzen

Der Debugger ist hauptsächlich für die interaktive Bedienung im Online-Modus ausgelegt. Zwar können Sie prinzipiell alle Debugger-Funktionen im Batch-Modus ausführen, die Verarbeitung von Online-Vorgängen im Batch-Modus (z.B. der Gebrauch von PF-Tasten) kann aber eine komplexe Batch-Programmierung erfordern. Es gibt jedoch Debugger-Funktionen, bei denen Batch-Verarbeitung eine komfortable Alternative darstellt. Eine Möglichkeit ist zum Beispiel das Sammeln und Drucken von Statistikdaten über eine Anwendung, siehe Abschnitt Beispiel für das Erstellen und Drucken von Statistiken im Batch-Modus im Abschnitt Batch-Verarbeitung.

## Quellcode-Beispiele

Dieser Abschnitt enthält den Quellcode der Beispiel-Programme und -Subprogramme, die in den Sitzungen 1 bis 5 benötigt werden.

#### Programm `DEBUG1P`

    ** PROGRAM 'DEBUG1P: CALLS 'DEBUG1N' FOR SALARY AND BONUS CALCULATION
    **********************************************************************
    DEFINE DATA
    LOCAL
    1 EMPLOYEE    (A42)
    1 REDEFINE EMPLOYEE
      2 NAME      (A20)
      2 NUMCHILD  (N2)
      2 ENTRYDATE (D)
      2 SALARY    (P7.2)
      2 BONUS     (P7.2)
    END-DEFINE
    NAME      := 'MEIER'
    NUMCHILD  := 2
    ENTRYDATE := D'1989-01-01'
    * SALARY  := 99000
    CALLNAT 'DEBUG1N' NAME NUMCHILD ENTRYDATE SALARY BONUS
    WRITE 'EMPLOYEE RECEIVES:'   SALARY
    WRITE '    PLUS BONUS OF:'   BONUS
    END

#### Subprogramm `DEBUG1N`

    ** SUBPROGRAM 'DEBUG1N': CALCULATES BONUS AND SALARY INCREASE
    ************************************************************************
    DEFINE DATA
    PARAMETER
    1 EMPLOYEE
      2 NAME      (A20)
      2 NUMCHILD  (N2)
      2 ENTRYDATE (D)
      2 SALARY    (P7.2)
      2 BONUS     (P7.2)
    LOCAL
    1 TARGETDATE  (D)    INIT <D'2009-01-01'>
    1 DIFFERENCE  (P3.2)
    1 PERCENT     (P2.2) INIT <3.5>
    END-DEFINE
    DIFFERENCE := (TARGETDATE - ENTRYDATE) / 365
    IF DIFFERENCE GE 10        /* BONUS FOR YEARS IN COMPANY
      BONUS := SALARY * PERCENT / 100
    END-IF
    SALARY := SALARY + 1800    /* SALARY PLUS ANNUAL INCREASE
    END

#### Programm `DEBUG2P`

    ** PROGRAM 'DEBUG2P': CALLS 'DEBUG2N'FOR SALARY AND BONUS CALCULATION
    ************************************************************************
    DEFINE DATA
    LOCAL
    1 EMPLOYEE    (A42)
    1 REDEFINE EMPLOYEE
      2 NAME      (A20)
      2 NUMCHILD  (N2)
      2 ENTRYDATE (D)
      2 SALARY    (P7.2)
      2 BONUS     (P7.2)
    END-DEFINE
    NAME      := 'MEIER'
    NUMCHILD  := 2
    ENTRYDATE := D'1989-01-01'
    SALARY    := 99000
    CALLNAT 'DEBUG2N' NAME NUMCHILD ENTRYDATE SALARY BONUS
    WRITE 'EMPLOYEE RECEIVES:'   SALARY
    WRITE '    PLUS BONUS OF:'   BONUS
    END

#### Subprogramm `DEBUG2N`

    ** SUBPROGRAM DEBUG2N: CALLS 'DEBUG3N' AND 'DEBUG4N'FOR SPECIAL RATES
    ************************************************************************
    DEFINE DATA
    PARAMETER
    1 EMPLOYEE
      2 NAME      (A20)
      2 NUMCHILD  (N2)
      2 ENTRYDATE (D)
      2 SALARY    (P7.2)
      2 BONUS     (P7.2)
    LOCAL
    1 TARGETDATE  (D)    INIT <D'2009-01-01'>
    1 DIFFERENCE  (P3.2)
    1 PERCENT     (P2.2) INIT <3.5>
    END-DEFINE
    DIFFERENCE := (TARGETDATE - ENTRYDATE) / 365
    IF DIFFERENCE GE 10        /* BONUS FOR YEARS IN COMPANY
      BONUS := SALARY * PERCENT / 100
    END-IF
    IF NUMCHILD > 0
      CALLNAT 'DEBUG3N' NUMCHILD BONUS     /* SPECIAL BONUS
    END-IF
    CALLNAT 'DEBUG4N' SALARY               /* SPECIAL SALARY INCREASE
    END

#### Subprogramm `DEBUG3N`

    ** SUBPROGRAM 'DEBUG3N': CALCULATES SPECIAL BONUS
    ************************************************************************
    DEFINE DATA
    PARAMETER
    1 NUMCHILD (N2)
    1 BONUS    (P7.2)
    END-DEFINE
    BONUS := BONUS + NUMCHILD * 50
    END

#### Subprogramm `DEBUG4N`

    ** SUBPROGRAM 'DEBUG4N': CALCULATES SPECIAL SALARY INCREASE
    ************************************************************************
    DEFINE DATA
    PARAMETER
    1 SALARY (P7.2)
    END-DEFINE
    DECIDE FOR FIRST CONDITION
      WHEN SALARY < 50000
        SALARY := SALARY + 1800
      WHEN SALARY < 70000
        SALARY := SALARY + 1200
      WHEN SALARY < 90000
        SALARY := SALARY + 600
      WHEN NONE
        SALARY := SALARY + 300
    END-DECIDE
    END

### On this page

- Voraussetzungen
- Grundlagen des Debugging
- Sitzung 1 - Analyse eines Natural-Fehlers
- Sitzung 2 - Einen Breakpoint benutzen
- Sitzung 3 - Einen Watchpoint benutzen
- Sitzung 4 - Verfolgen des logischen Ablaufs von Programmen
- Sitzung 5 - Verwendung von Statistiken über die Programmausführung
- Weitere Hinweise zur Benutzung des Debuggers
- Quellcode-Beispiele