Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
uladzislau_pralat
Contributor

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.

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

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.

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 sy-subrc.
 
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 = sy-uname.
   
ASSIGN wa_aab_id_act-actmode 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 sy-zonlo
 
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 sy-zonlo
   
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


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

Press Return (F7) on next screen

Voilà you are in Z_DEMO program

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

Voilà you are in Z_DEMO program.

9 Comments