Académique Documents
Professionnel Documents
Culture Documents
The ABAP debugger is a powerful tool helping to examine your ABAP code at runtime.
Besides the common and basic features, such as stepping through your code and inspect the values of your
variables, field symbols, and references, it provides helpful features that can simplify and shorten your
debugging sessions. Not all of these features might be known to everyone.
In this article I am going to demonstrate my personal favouritesDebugging Techniques
System Debugging
System programs are typically provided by SAP itself and you should not classify your own programs as such.
System code is considered relatively technical and not containing any business logic. As a consequence,
developers focusing on business logic commonly do not need/want to debug this. However, from time to time
your debugging session might end up at a system program.
In order to dive into system code using the ABAP debugger you have to activate system debugging beforehand.
Choose the menu entry System Debugging On/Off in the settings menu.
Activating system debugging allows you to access source code you are typically not able to see and, therefore,
can help investigating issues. On the other hand, you need to deal with a growing call stack as all system
programs are visible too. Usually the system code is executed in the background without your notice.
Update Debugging
Whenever you deal with transactions or reports that utilize asynchronous update tasks (e.g. to persist business
data), you might encounter error messages occuring from the executed code inside the update task. Such
errors appear usually in the SAP GUI telling you “Update was terminated”.
In order to examine what is going wrong, you can activate update debugging. If update debugging is turned on,
the ABAP debugger opens once the update task is being executed and allows you to inspect the program flow.
Consider the change of a cost center as example. We open transaction KS02, select a demo cost center, and
open its master data. Let us adjust the description. Before we click Save, we enter “/h” in the transaction code
input field on the top left corner and press Return. The green success message “Debugging switched on” is
displayed at the bottom.
After clicking Save, the debugger opens showing the PAI/PBO modules of the current ABAP program. In order
to activate update debugging, we open the debugger settings following the menu path Settings -> Change
Debugger Profile/Settings. In this dialog we activate Update Debugging and confirm.
Pressing F8 skips the current debugger session. The ABAP server continues processing the current ABAP
program which prepares and hands over the update tasks to the update processing. Once they are executed,
the debugger opens once again.
Coming back to the cost center change example, we end up inside the function module
KOSTL_WRITE_DOCUMENT. According to its source code, it takes care calculating the change documents
with regards to this cost center master data change.
In the most cases, multiple update tasks are coming into play for one business process (changing a cost center
is relatively easy, though). Let us figure out how we can find all of them at runtime.
Looking at the call stack, we can see the form routine VB_V2_NORMAL.
Before we can navigate into this code, we have to activate system debugging (see chapter above).
Inside this form routine we can see that the internal table VBMOD_TABL contains all function modules to be
processed.
Using update debugging you are able to spot bugs inside function modules executed in update task. Even if you
do not encounter any bugs, it might be interesting to see what happens under the hood.
Conditional Breakpoints
Assume you are debugging some code containing a loop whereas you are interested in debugging a certain
cycle (e.g. the fifth loop cycle). Making the debugger stop in this exact cycle is easy using conditional
breakpoints.
Consider the following sample program.
REPORT zmd_cond_brkpnt_01.
DO 50 TIMES.
ADD 1 TO lv_foo.
ENDDO.
Classification of Breakpoints
In the official documentation we can find terms such as static breakpoints, special dynamic breakpoints, external
breakpoints, debugger breakpoints. While investigating the meaning of these terms I found that they are
addressing different properties of breakpoints, such as their life time or the way you create them.
Therefore, I was curious and have created a classification of breakpoint times according to the following
categories:
Life Time
Way of Creation
Can be User-Agnostic
Processing Mode
Conditionally Considered
Activated
Life Time
Breakpoints exist for a certain time, that is once their life time has passed they are gone and cannot be used
anymore. The possible life times are:
Generally all breakpoints can be deleted manually, i.e. their life time can be shortened on purpose.
Way of Creation
There is several ways how to create a breakpoint:
Can be User-Agnostic
A breakpoint can be valid for a certain user name or not.
If so, the breakpoint is considered once the respective user executes the code line. This applies to all
breakpoints unlike Static Breakpoints defined with BREAK-POINT.
If not, the debugger stops at every execution regardless of the current user. This applies to Static Breakpoints
defined with BREAK-POINT.
Processing Mode
There is breakpoints that stop at dialog processing only, such as Debugger Breakpoints.
in contrast, e.g. External Breakpoints are used to debug processing of remote calls such as RFC or ICF
processing.
Conditionally Considered
The consideration of a breakpoint may depend of a given condition expressed as logical condition. For instance,
a variable has to have a defined value and, therefore, the debugger only stops if the condition is fulfilled. Such
breakpoints are referred to as Conditional Breakpoints.
Activated
Apart from their existence breakpoints can be active or inactive.
In case you do not need a breakpoint being considered in your debugging session, you can deactivate it. You
can turn it on again once you want to use it.
In this dialog we can choose between inspecting variables of object attributes. We can also specify the
respective ABAP program.
After creating this watchpoint and pressing F8 in our sample program, we get notified that the watchpoint has
been reached.
Debugger Scripting
Debugger Scripting is a powerful mechanism to automate processes that occur often, are time-consuming and
are conducted by hand.
Assume that you want to skip authorization checks by manipulating the sy-subrc value.
Disclaimer: Only do so if it is harmless, that is you must not abuse this feature. Tell you admin if you are
authorized to use it and you are working in a field with sensitive data or processes.
You can open the tab Script in the debugger and there you will find a local class implementation. Besides the
methods prologue, init and end you can add you own logic in the method script. On the left-hand side you can
decide when the script shall be triggered. For instance, et every debug step or after once a watchpoint is
reached.
Happy Debugging
The New ABAP Debugger was first released by SAP with NetWeaver04. As of release NetWeaver 7.0 it
fully replaces in the scope of its functionality the “old-fashioned” Classic ABAP Debugger. During the
last SAP TechEds I learned that more and more people use the New ABAP Debugger (that is a great
news!) but still many are not aware of some of its useful features. The purpose of this blog is to point
you to these features so that you can make the most of the New ABAP Debugger.
System Debugging: if you have problems that involve system programs (such as a function that can’t
be accessed in the debugger), turn on this setting (or use menu Settings->System debugging On/Off ”
or the command /hs in the debugger command field). You can declare a program as a system program
by setting Status to “System Program” in its attributes in the ABAP Editor (SE38) (check the
radiobutton Attributes and press Change button).
Update Debugging: turn on this setting if you need to analyze asynchronous updates, which are
functions that are called as follows: CALL FUNCTION ‘…’ IN UPDATE TASK. These functions are
executed asynchronously in a special update work process (after the next COMMIT WORK statement).
The debugger can’t follow them since it is attached to a single process. Set a breakpoint in the function
that is called IN UPDATE TASK, start debugging, turn on this setting, and the debugger will reach the
breakpoint in your update function.
TRFC (In Background Task): Block Sending: turn on this setting if you need to analyze transactional
Remote Function Calls (TRFC), which are called as follows: CALL FUNCTION ‘…’ IN BACKGROUND
TASK. These functions are called asynchronously, along with other TRFC functions of this logical unit of
work (LUW), after the next COMMIT WORK statement. The debugger can’t follow them since it is
attached to a single process. When you turn on this setting, these TRFC functions are stored in the
system for debugging instead of being sent. Use the TRFC Monitor (transaction SM58) to analyze the
unprocessed LUWs and select Edit->Debug LUW to debug them.
Close debugger After ‘Continue’ (F8) and Roll Area End: usually after you press Continue (F8) in
the debugger session, the debugger session remains available but inactive when the program is
finished. If you switch on this setting, then the debugger will be closed automatically after
pressing Continue (F8), when the roll area (internal session) is ended.
Always Create Exception Obj.: turn on this setting if you need to analyze exception objects (if you
catch ABAP exceptions in your program via the CATCH CX_MY_EXCEPTION without specifying a
reference variable to which the exception object can be assigned). You can then examine the created
exception objects in the debugger via Display Exception Obj. magnifier button.
How to handover a debugger problem – Use Debugger Variants
Imagine that you have had to reproduce and troubleshoot a problem in a rather complicated environment. You
have finally found the function module which doesn’t work properly under certain conditions. You may need to
hand over this debugging session for further analysis to a colleague who has expert knowledge of this function
module.
In order to ensure that your colleague can reproduce the problem, you must create a very detailed description:
the source lines at which to set breakpoints, the debugger settings that must be active, and so on. This is time
consuming and there is still a chance that you might forget critical information. In such situations, use a
debugger variant (menu Debugger->Debugger Session->Save) to store your debugger session. You can
choose which parts to store: current layout (customized desktops), debugger settings, options and breakpoints.
Then you can save the variant either in the database or in a local file and send it per email to your colleague.
Afterwards your colleague can load the saved variant from a file or the database after starting a debugging
session (menu Debugger->Debugger Session->Load). All settings and breakpoints will become active
immediately. Of course he can choose which components of the variant to load: layout, settings, options,
breakpoints, or all of them.
How to display all loaded programs and global variables – Use the
Loaded Programs Tool
A double-click on the variable name in the source code leads to the Variable Fast Display Tool where you get
information about variable: type, value, etc. On the Locals tab you get all parameters (including parameter kind)
and local variables of the current function module, on the Globals tab, you can display all global variables of the
current program. But sometimes this local and global information is not enough; you maybe need to display all
currently loaded programs and their global variables as well. For this purpose, use the Loaded Programs Tool
(button New Tool, Special Tools->Loaded Programs).
Loaded Programs shows you two tabs. On the Loaded Programs tab you see the attributes of all loaded
programs and their program groups. On the Global Data tab you get global variables of each global program
just by double-clicking the program in the navigation tree.
How to test a function module in the debugger and pass parameters
Imagine you want to test a function module in the test framework of the Function Builder (transaction SE37) in
the debugger, and you need to pass as a parameter a big internal table with many entries. It would be very time
consuming to enter the input data for such a table manually in SE37. But you don’t have to do this. If you access
the function module from the debugger, then you can download its parameters to the SE37 test framework.
Select the parameter and use the right mouse button context menu Save Parameters as Test Data (SE37).
Please consider that this download is restricted to the data types which are allowed in the SE37 test framework:
you cannot download objects, nested internal tables or data references. After that just open the function module
in a separate SE37 window and run it in the test framework. You can access your downloaded data in SE37
via Test Data Directory button.
Helpful hints for analyzing variables
Use the Data Explorer to view deep nested objects With the Objects Tool (Objects desktop) you can
examine object properties including visibility, inheritance, references to the object (where-used list ).
You can double-click on attributes in order to navigate to the subcomponents of a class. But if you have
to analyze deep nested objects, then the Data Explorer Tool is the better choice. The Data Explorer lets
you drill down into nested objects, structures, and references without losing context of the upper levels.
Use Text Translation to display large hex strings and the XML Browser to display XML data.
It is very time consuming to analyze the content of a variable that contains 2000 bytes of hex code.
Therefore, the detail view (Detail Display desktop) for simple types and strings allows you to translate hex
strings into readable text using the appropriate code page (field View , choose Text Translation). For binary
XML data, there is the XML viewer (field View , choose XML Browser).