Debugging ABAP code in background processing is a common requirement. How developers usually approch this task is by coding time delay or dead loop to take control of the process in trx. SM50 and debug it. There is no easy and graceful way to activate or deactivate such “break-point” in production environment.

Checkpoint Group provide flexibilty and ease of activation and deactivation of break-points using trx. SAAB. For example, break-point can be activation per specific user and will not affect other users.

SAAB.jpg

If you execute ABAP program online execution will stop at activated break-point.

Debugger1.jpg

The same break-point will not interrupt execution in background processing. There is a way to use the same Checkpint Group to interrupt ABAP processing in both dialog and background processing. What it takes is to code activatable break-point using ZCL_AAB=>BREAK_POINT custom class method.

Z_DEMO.jpg

ZCL_AAB=>BREAK_POINT method checks if activatable break-point exists (calling ZCL_AAB=>EXISTS method) and active (calling ZCL_AAB=>IS_BREAK_POINT_ACTIVE method). If break point exists and active then in dialog processing execution is interrupted using BREAK-POINT statement, othersize is background processing excution is delayed for 60 seconds (calling ZCL_AAB=>TIME_DELAY method).

class ZCL_AAB definition
 
public
  final
 
create public .

*”* public components of class ZCL_AAB
*”* do not include other source files here!!!
public section.

  class-methods BREAK_POINT
   
importing
      !IV_AAB_ID
type AAB_ID_NAME .
protected section.
*”* protected components of class ZCL_AAB
*”* do not include other source files here!!!
private section.
*”* private components of class ZCL_AAB
*”* do not include other source files here!!!

  class-methods EXISTS
   
importing
      !IV_AAB_ID
type AAB_ID_NAME
    returning
     
value(RT_EXISTS) type CHAR1 .
 
class-methods IS_BREAK_POINT_ACTIVE
   
importing
      !IV_AAB_ID
type AAB_ID_NAME
    returning
     
value(RT_BREAK_POINT_IS_ACTIVE) type CHAR1 .
 
class-methods TIME_DELAY .
ENDCLASS.

CLASS ZCL_AAB IMPLEMENTATION.

* <SIGNATURE>—————————————————–+
* | Static Public Method ZCL_AAB=>BREAK_POINT
* +————————————————————–+
* | [—>] IV_AAB_ID                      TYPE        AAB_ID_NAME
* +—————————————————</SIGNATURE>
METHOD break_point.
DATA: w_text TYPE string.

  IF exists( iv_aab_id ) = SPACE.
   
CONCATENATE ‘Checkpoint Group’ iv_aab_id ‘does not exist’
     
INTO w_text SEPARATED BY SPACE.
   
MESSAGE w_text TYPE ‘I’.
   
EXIT.
 
ENDIF.

  IF is_break_point_active( iv_aab_id ) = ‘X’.
   
IF cl_gui_alv_grid=>offline( ) IS INITIAL.
*     Foreground
     
BREAK-POINT.
   
ELSE.
*     Background
      time_delay
( ).
   
ENDIF.
 
ENDIF.

ENDMETHOD.

* <SIGNATURE>—————————————————+
* | Static Private Method ZCL_AAB=>EXISTS
* +————————————————————-+
* | [—>] IV_AAB_ID                      TYPE        AAB_ID_NAME
* | [<-()] RT_EXISTS                      TYPE        CHAR1
* +————————————————–</SIGNATURE>
METHOD exists.
DATA: w_aab_id TYPE  aab_id_name.

  SELECT SINGLE name
 
INTO w_aab_id
 
FROM aab_id_prop
 
WHERE name = iv_aab_id.
 
CASE sysubrc.
 
WHEN 0.
    rt_exists
= ‘X’.
 
WHEN OTHERS.
   
CLEAR rt_exists.
 
ENDCASE.

ENDMETHOD.

* <SIGNATURE>—————————————————+
* | Static Private Method ZCL_AAB=>IS_BREAK_POINT_ACTIVE
* +————————————————————-+
* | [—>] IV_AAB_ID                      TYPE        AAB_ID_NAME
* | [<-()] RT_BREAK_POINT_IS_ACTIVE       TYPE        CHAR1
* +————————————————–</SIGNATURE>
METHOD is_break_point_active.
DATA: wa_aab_id_act TYPE aab_id_act,
      wt_aab_id_act
TYPE aab_id_act_tab.
DATA w_bit_value TYPE i.
FIELD-SYMBOLS <mode_x> TYPE x.
CONSTANTS: c_breakpoint TYPE i VALUE 8.

  SELECT * FROM aab_id_act INTO TABLE wt_aab_id_act
 
WHERE name       = iv_aab_id
   
AND is_program = SPACE.
*
 
LOOP AT wt_aab_id_act INTO wa_aab_id_act
                       
WHERE username = SPACE
                          
OR username = syuname.
   
ASSIGN wa_aab_id_actactmode TO <mode_x> CASTING.
   
GET BIT c_breakpoint OF <mode_x> INTO w_bit_value.
   
IF NOT w_bit_value IS INITIAL.
      rt_break_point_is_active
= ‘X’.
     
EXIT.
   
ENDIF.
 
ENDLOOP.

ENDMETHOD.

* <SIGNATURE>———————————————+
* | Static Private Method ZCL_AAB=>TIME_DELAY
* +——————————————————-+
* +——————————————–</SIGNATURE>
METHOD time_delay.
DATA: w_time_curr TYPE tims,
      w_time_end  
TYPE tims.
DATA: w_timestamp TYPE timestampl.

  GET TIME STAMP FIELD w_timestamp.
 
CONVERT TIME STAMP w_timestamp TIME ZONE syzonlo
 
INTO TIME w_time_curr.
  w_time_end
= w_time_curr  + 60.
 
WHILE w_time_curr < w_time_end.
   
GET TIME STAMP FIELD w_timestamp.
   
CONVERT TIME STAMP w_timestamp TIME ZONE syzonlo
   
INTO TIME w_time_curr.
 
ENDWHILE.

ENDMETHOD.
ENDCLASS.

Lets see it in action. First run the program in background and take over control of the program in trx. SM50

SM50.jpg
Then once in debugger session, interrupt WHILE loop setting W_TIME_CURR at least 60 seconds in the future. For simplicity just set it to 235959 and click on Return (F7) button

Debugger.jpg

Press Return (F7) on next screen

Debugger2.jpg

Voilà you are in Z_DEMO program

Debugger3.jpg

Lets see how the break-point works in dialog processing. Run the program and execution is interrupted at BREAK-POINT statement, press Return (F7) button

Debugger4.jpg

Voilà you are in Z_DEMO program.

Debugger3.jpg

To report this post you need to login first.

9 Comments

You must be Logged on to comment or reply to a post.

  1. Sougata Chatterjee

    Hello,

    I had a similar requirement recently and this is how I built it.

    Create Check Point Group:

    /wp-content/uploads/2015/06/image001_714981.png

    Create a local Activation variant for the Check Point Group created above by assigning the Check Point Group to this variant:

    /wp-content/uploads/2015/06/image002_714982.png

    Now my Check Point Group looks like this:

    /wp-content/uploads/2015/06/image003_714990.png

    Below is my application – I trigger the “Debug Delay” in method RUN( ).

    REPORT zfi_bank_stmt_upload.

    INCLUDE:

      lbtchdef,

      zfi_inc_bank_stmt_upload.

    AT SELECTION-SCREEN OUTPUT.

      lcl_application=>pbo( ).

    AT SELECTION-SCREEN ON VALUE-REQUEST FOR pa_path.

      lcl_application=>pai( ).

    START-OF-SELECTION.

      lcl_application=>run( ).

    Below is the code for method RUN( ).

    METHOD run.

    * for foreground debug

      BREAK-POINT ID z_cpg_fi_ebs_upload.

    * to support background debug at the time of troubleshooting

      lcl_application=>support_debug( ).

    ………….

    ……………

    ENDMETHOD.

    Below is the code for method SUPPORT_DEBUG( ).

       METHOD support_debug.

          assert( ).

          TRY.

              DATA(lt_settings) =

                      cl_aab_activation=>get_instance( )->read_settings(

                      EXPORTING

                        scope_range = VALUE #( ( sign     = |I|    option   = |EQ|

                                                 low-type = |ACID| low-name = lc_cp_group ) )

                        user_range  = VALUE #( ( sign     = |I|    option   = |EQ|

                                                 low      = sy-uname ) ) ).

              IF lt_settings IS INITIAL.

                RETURN.

              ELSE.

                CHECK line_exists( lt_settings[ mode-breakpoint = abap_true ] ).

                WAIT UP TO 20 SECONDS.

              ENDIF.

            CATCH cx_aab_activationsettings                           ##NO_HANDLER.

          ENDTRY.

        ENDMETHOD.

    METHOD assert.

         BREAK-POINT ID z_cpg_fi_ebs_upload CONDITION sy-batch IS NOT INITIAL.

    ENDMETHOD.

    Cheers,

    Sougata.

    (0) 
    1. Uladzislau Pralat Post author

      Hi Sougata,

      thank you for sharing. Your code will work except for situation when checkpoint is activated globally for all users. You need to pass second entry in user_range parameter for empty user.

      Regards, Uladzislau

      (0) 
      1. Sougata Chatterjee

        It is controlled via the Local Activation Variant to avoid changing source code. Simply add the user to the local variant by choosing “Activation Per User” on the toolbar. It is for troubleshooting purposes for IT support, its not meant for every user anyway.

        /wp-content/uploads/2015/06/image001_719510.png

        (0) 
        1. Uladzislau Pralat Post author

          Checkpoint activation for all users is a standard feature of trx. SAAB.
          Users will expect this feature to work for all kind of breakpoints including
          breakpoints for background processing. It is just a good programming style to keep trx. SAAB behavior consistent

          (0) 
    2. Suhas Saha

                  CHECK line_exists( lt_settings[ mode-breakpoint = abap_true ] ).

                  WAIT UP TO 20 SECONDS.

      Just to be clear, we still have to go to SM50 and do the actual “debugging”. Sorry for the stupid question.

      In programs, which are supposed to run in BG mode, i use the LOG-POINT normally.

      BR,

      Suhas

      (0) 
  2. Prasenjit Bist

    I use the SAAB features a lot a real life saver. Last 11 months i have been in a really stupid support project and i saved myself from harassment using these tools a lot many times.

    So thanks SAP 🙂

    (0) 

Leave a Reply