Debugging an ABAP Program

Objectives
After completing this lesson, you will be able to:

After completing this lesson, you will be able to:

  • Enter debugging mode
  • Control the execution of code
  • Analyze the content of data objects

Entering Debugging Mode

Watch this video to understand the need for debugging.

Starting the Debugger

To debug an ABAP program, you set a breakpoint then run the program normally. When the program reaches the breakpoint, the system interrupts it and opens the ABAP Debug perspective in ADT. You can then execute each subsequent statement individually to see what effect it has on the program. You can also inspect the contents of all of the variables in the program to see if any of the values are unexpected.

To set or remove a breakpoint, right-click the left margin of the editor and choose Toggle Breakpoint. As an alternative you can double-click the left margin. Note that the program has to be activated before you can set breakpoints.

Breakpoints are user-specific and are persistent - they remain active even after you have logged off from ADT and back on again. To prevent the debugger from starting at a breakpoint you must either delete the breakpoint (using the Toggle Breakpoint function) or deactivate it using the corresponding function in the context menu.

Note
Depending on your personalization settings, ADT will ask for confirmation, first, before automatically opening the debug perspective.

The Debug Perspective in ADT

When you debug an ABAP program using ABAP Development Tools, you use the Debug perspective. This is a customized version of the standard Eclipse Debug perspective, and it contains views and functions that are particularly important for debugging.

How To Start The Debugger

Controlling the Execution Of Code

Some Navigation Functions

Once you started debugging, use the navigation functions to control the execution of the code.

Some important navigation functions are shown here.

Special Breakpoints

You learned that you can create and manage breakpoints by clicking on the left margin of the ABAP editor view. This also works with the ABAP editor view in the Debug perspective.

In addition, you can switch to the Breakpoints view and manage your breakpoints there.

In the Breakpoints view you can also create special breakpoints:

Statement Breakpoint

A statement breakpoint is not attached to a specific line of code but to a specific ABAP statement. A statement breakpoint on statement CLEAR, for example, causes the program to stop in the debugger whenever a CLEAR statement is executed - no matter where this statement is located.

To create a statement breakpoint, open the dropdown list from the toolbar of the Breakpoints view and choose Add Statement Breakpoint … .

Exception Breakpoint

An exception breakpoint is attached to a specific exception. It causes the program to stop in the debugger whenever this particular exception is raised - no matter if this exception is handled by the program or causes a runtime error. To create an exception breakpoint, open the dropdown list from the toolbar of the Breakpoints view and choose Add Exception Breakpoint … .

Conditional Breakpoints

You turn a breakpoint into a conditional breakpoint by adding a condition. If program execution hits a conditional breakpoint, the program only stops in the debugger, if the condition is fulfilled. If, for example, a breakpoint is located between DO and ENDDO it will cause the program to stop in the debugger in every iteration. But if you add a condition sy-index > 20 the debugger will ignore this breakpoint during the first 20 iterations and only stop in the following iterations.

To add a condition to a breakpoint, choose it in the list of breakpoints and enter the condition in field Condition. Press Enter to save the breakpoint with the condition.

Watchpoints

If an unexpected value of a variable is causing you problems, you can track its value during the course of the program using a watchpoint.

Watch this video to see how.

How To Control The Execution Of Code

Analyzing The Contents Of Data Objects

Display Content of Data Objects

Watch this video to learn how to display the content of data objects in the debugger.

Display Content of Internal Tables

Watch this video to learn how to display the content of internal tables.

Changing the Values of Variable

Depending on your authorizations, you can change the value of variables during debugging.

For simple variables, locate the variable in the Variables view, right-click on it and choose Change Value ….

To change the content of an internal table, we have to distinguish between changing the value of an existing row and adding or deleting of a rows.

As shown in the figure, the following functions are available when you right-click in the ABAP internal table view:

Change Value …
Choose Change Value …. to change the content of an existing row.
Insert Row …
Choose Insert Row …. to add a new row. You can decide whether you want to append the new row or insert it at the chose position.
Delete Selected Rows …
Choose Delete Selected Rows … to remove the rows you selected before you right-clicked. To select a row, left-click it. To select more than one row, hold down the Ctrl key or the Shift key when you left-click additional rows.
Delete Rows …
Choose Delete Rows …to remove a larger range of rows, or even all rows. You are asked for the number of the start row and the end row you want to delete.

How To Analyze The Contents Of Data Objects

Debug an ABAP Program

In this exercise, you analyze a program using the ABAP debugger.

Prerequisites

Task 1: Preparation

Before you can start debugging you have to create the program and copy the source code.

Steps

  1. Create a new global class ZCL_##_DEBUG, where ## is your group number. Ensure that the class implements the interface IF_OO_ADT_CLASSRUN.

    1. Choose FileNewABAP Class.

    2. Enter the name of your package in the Package field. In the Name field, enter the name ZCL_##_CDS, where ## is your group number. Enter a description.

    3. In the Interfaces group box, choose Add.

    4. Enter IF_OO_ADT_CLASSRUN. When the interface appears in the hit list, double-click it to add it to the class definition.

    5. Choose Next.

    6. Select your transport request and choose Finish.

  2. Copy the following code between METHOD if_oo_adt_classrun~main. and ENDMETHOD. on the Global Class tab:

    Code snippet
    
    * Declarations
    **********************************************************************
        " Types
        TYPES t_amount     TYPE p LENGTH 8 DECIMALS 2.
        TYPES t_percentage TYPE p LENGTH 2 DECIMALS 1.
    
        " Input for the calculation
        CONSTANTS loan_total        TYPE t_amount     VALUE '50000.00'.
        CONSTANTS interest_rate     TYPE t_percentage VALUE '2.0'.
        CONSTANTS payment_month     TYPE t_amount     VALUE '1000.00'.
        CONSTANTS spec_repay_year   TYPE t_amount     VALUE '10000.00'.  " Extra payment per year
        CONSTANTS spec_repay_mode   TYPE c LENGTH 1   VALUE 'Q'.         "'A' Annual, 'H' every half year, 'Q' 'every Quarter
    
        " Output
        DATA repayment_plan TYPE TABLE OF string.
    
        " Helper Variables
        DATA loan_remaining         TYPE t_amount.
        DATA interest_month         TYPE t_amount.
        DATA repayment_month        TYPE t_amount.
        DATA interest_total         TYPE t_amount.
        DATA special_repayment      TYPE t_amount.
    
        DATA months_counter         TYPE i.
        DATA months_btw_spec_pay    TYPE i.
    
    
    * Processing
    **********************************************************************
    
        " Initializations
        loan_remaining = loan_total.
    
        CASE spec_repay_mode.
          WHEN 'A'.
            months_btw_spec_pay = 12.
            special_repayment   = spec_repay_year.
          WHEN 'H'.
            months_btw_spec_pay = 6.
            special_repayment   = spec_repay_year / 2.
          WHEN 'Q'.
            months_btw_spec_pay = 3.
            special_repayment   = spec_repay_year / 4.
          WHEN OTHERS.
            out->write( 'Invalid extra payment mode'  ).
            EXIT.
        ENDCASE.
    
        " Calculations
        DO.
    
          IF loan_remaining <= 0.
            EXIT.
          ENDIF.
    
          DO months_btw_spec_pay TIMES.
    
            months_counter = months_counter + 1.
    
            " calculate interest and back payment for current month
            interest_month    = loan_remaining *  ( interest_rate / 100 ) / 12 .
            repayment_month   = payment_month - interest_month.
    
            " add monthly interest to total interest
            interest_total = interest_total + interest_month.
    
            " deduct repayment
            loan_remaining = loan_remaining - repayment_month.
    
            " add payment to repayment plan
            APPEND |Month {  months_counter } - Interest: { interest_month } Remaining loan: { loan_remaining } |
                TO repayment_plan.
    
            IF loan_remaining < 0.
              EXIT.
            ENDIF.
          ENDDO.
    
          IF loan_remaining < 0.
            EXIT.
          ENDIF.
    
          " deduct the special repayment (n times a year, spec_repay_year over the year )
          loan_remaining = loan_remaining - special_repayment.
    
          "add special repayment to repayment plan
          APPEND |Special repayment of { special_repayment }! Remaining loan { loan_remaining } |
              TO repayment_plan.
        ENDDO.
    
    * Output
    **********************************************************************
    
        out->write( |Starting value of loan:   { loan_total        }| ).
        out->write( |Monthly payment:          { payment_month     }| ).
        out->write( |Special repayment         { special_repayment } every { months_btw_spec_pay } months. | ).
    
        out->write( |-----------------------Result-----------------------| ).
        out->write( |Total repayment after { months_counter DIV 12 } years and { months_counter MOD 12 } months. | ).
        out->write( |Total interest paid: { interest_total } | ).
    
        "Repayment Plan
        out->write(
                    name = `Repayment Plan:`
                    data = repayment_plan
                  ).
    
    Copy code
    1. On the Global Class tab, insert the source code between METHOD if_oo_adt_classrun~main. and ENDMETHOD..

  3. Activate and test the class.

    1. Press Ctrl + F3 to activate the class.

    2. Press F9 to run the class.

  4. Check the output in the Console view.

    1. Check the Console view that should have opened as a new tab below the editor view.

    2. If the Console view is not visible, open it by choosing WindowShow viewOther. Double-click Console in the hit list.

Task 2: Analyze the Starting Values

Enter the debugger at the first executable statement in method if_oo_adt_classrun~main( ) and analyze the values of some variable and constant data objects.

Steps

  1. Set a breakpoint at the first statement that does not define a type or declare a data object.

    Hint
    TYPES defines a data type, CONSTANTS declares a constant data object, DATA declares a variable data object.
    1. Double-click the left-hand margin of the editor next to the line  loan_remaining = loan_total.to set a break point.

  2. Run the class as a console app and enter the debugger.

    1. Press F9 to run the class.

    2. If you are asked whether you want to switch to the Debug perspective, mark Remember my decision and choose OK.

  3. Display the value of data object loan_remaining and loan_total in the Variables view.

    1. In the current code line (the one with a green background) double-click loan_remaining.

    2. In the same code line, double-click loan_total.

Task 3: Control Program Execution

Set break points and watch points. Execute single steps or resume execution until the next break point or watch point is reached. Supervise the value changes of the data objects.

Steps

  1. Execute a single step to debug the value assignment in the current line.

    1. In the toolbar, choose Step Into (F5) or press F5.

    2. Check that the the value of loan_remaining changed from 0..00to 5000.00.

  2. Display the content of data object spec_repay_mode. Then execute another single step to see which WHEN branch of the CASE - control structure is executed.

    1. In the next code line, double-click spec_repay_mode.

    2. Press F5 to see that the program jumps to code line WHEN 'Q'..

  3. Set a watch point for variable loan_remaining and resume program execution. Where does the program execution stop again?

    1. In the Variables view, right-click on LOAN_REMAINING and choose Set Watchpoint.

    2. In the toolbar, choose Resume (F8) or press F8.

    3. Program execution stops immediately after code line loan_remaining = loan_remaining - repayment_month., also to be precise, in the next code line with executable code.

  4. Display the content of data object repayment_plan. Then execute another single step to see how it is filled with the APPEND statement.

    Note
    Because repayment_plan is an internal table, it not only displays in the Variables view but also in the ABAP Internal Table (Debugger) view below the editor.
    1. Double-click on repayment_plan at the end of the APPEND statement.

    2. Press F5 to see how repayment_plan is filled with a first row.

  5. Inspect the string template in the APPEND statement and relate it to the resulting first row in internal table repayment_plan. Display the content of the data objects that appear in the embedded expressions.

    1. Double-click the data objects that appear between the curly brackets to display their contents.

  6. Resume program execution for a few times. Whenever execution reaches one of the watch points, analyze the value of loan_remaining and new rows are added to repayment_plan.

    1. Press F8 to resume program execution.

    2. Analyze the data objects in the Variables view and the ABAP Internal Table (Debugger) view.

  7. After a while, set a statement break point for all EXIT statements and delete the two watch points.

    1. Navigate to the Breakpoints view.

      Hint
      You find the Breakpoints view next to the Variables view.
    2. In the toolbar of the Breakpoints view, expand the dropdown button on the very left and choose Add Statement Breakpoint ....

    3. On the dialog window that appears, enter EXIT as search string, click on the value EXIT in the hitlist, and choose OK.

    4. In the Breakpoints view, right-click the watchpoint LOAN_REMAINING and choose Remove.

    5. In the Breakpoints view, right-click the watchpoint REPAYMENT_PLAN and choose Remove.

  8. Resume program execution until you reach the first EXIT statement. Deactivate the statement breakpoint for the EXIT statement. Then execute single steps until you reach the output part of the program.

    1. Press F8 to resume program execution.

    2. Switch to the Breakpoints view and deselect the line that says EXIT [Statement].

    3. Press F5 until you reach the first code line that starts with out->write(.

  9. Open the Console view. Execute the remaining program and pursue the output on the console view.

    Do not press F5 to debug the output. Use F6 instead.
    Note
    As you will learn later in the course out->write( ... ) is not an ABAP statement but a reusable code block that consists of many ABAP statements. By pressing F5 you Step Into this code to analyze it in detail. With F6 you Step Over the code block, treating it like a single statement.
    1. Press F6 several times until you reach the end of the application.

    2. Analyze the addition output on the Console view and compare it to the string template in the previous code line.

  10. When the application is terminated, do not forget to switch back to the ABAP perspective

    1. Choose ABAP on the very right of the Eclipse toolbar.

Log in to track your progress & complete quizzes