--------- Debugging --------- .. toctree:: Debugging with GNATbench In Workbench ===================================== Within a GNATbench for Workbench session, debugging is supported via Workbench and the Workbench debugger. The screenshots in this section use the project "sdc.gpr" from the GPS tutorial. That project and its associated code can be found under the GNAT installation in the directory share/examples/gps/tutorial. Other Resources --------------- You can find more information about the debug facilities available under Workbench in the Wind River Workbench User's Guide. Preparing To Debug ================== Before you begin to debug your project, make sure your project has built properly and you can see the target objects in the Project Navigator. You may need to refresh your view of the file system by right-clicking on the directory you are using for your objects and selecting "Refresh". Enabling Ada Debugging Options ------------------------------ You must set an environment variable to enable viewing the values of certain Ada variables. Specifically, set DFW\_ENABLE\_ADA\_SYMBOL\_SEARCH to 1. You need only set this environment variable once, as long as it does not become undefined later. Connect To A Target ------------------- To debug your application, you must first establish a connection to the target system. This is done in Workbench via the "Remote Systems" view in the lower left hand corner of the display. If your target is not already visible in Workbench, you must click on the "New Connection" icon in the Remote Systems view's toolbar and configure an appropriate target connection. Next, select the target and then press the "connect" icon in the Remote Systems toolbar to establish a connection to your newly configured target. In the following figure we are establishing a connection to the pre-configured "vxsim" target. .. image:: images/cross_debug_new_connection.png :align: center :alt: cross\_debug\_new\_connection After these steps, the connection should be established and you should see something like the following in the view: .. image:: images/cross_debug_connect.png :align: center :alt: Here in the Remote Systems view, a connection has been established to "vxsim0", a target simulator running a VxWorks kernel. Creating A Debug Launch Configuration ===================================== Workbench allows you to maintain configuration options and preferences from debug session to session via the "debug configuration" mechanism. To debugging under Workbench you must create such a configuration. To create a debug launch configuration you must invoke the appropriate dialog. There are a number of ways to do so. For example, the contextual menu for project nodes in the explorer is tailored for the kind of project selected. With a DKM project, you can right-click on the project node and select "Debug VxWorks Kernel Task". .. image:: images/contextual_menu_debug_kernel_task.png :align: center :alt: contextual\_menu\_debug\_kernel\_task.png Alternatively, you could select "Debug Configurations..." from under the "Run" menu or select it via the toolbar "Debug" button. The project node contextual menu approach may be the most convenient because it will fill in some of the required fields automatically. In any case, the debug configuration manager dialog will appear: .. image:: images/cross_debug_dialog_page.png :align: center :alt: In this case we are debugging a kernel task, so double click on "VxWorks Kernel Task". This will bring up a tabbed dialog allowing you to configure your session. Initially there will be no entry point so that will be reflected in the configuration name: .. image:: images/cross_debug_new_kernel_config.png :align: center :alt: Note that the previously configured and connected "vxsim0" has been selected for the launch context. The error indicates that the missing "Entry Point" is not yet specified. This is the Ada main program, unless you want to debug the library units' elaboration. You can either manually enter the main program name or browse for it. *It is always necessary to specify the name of the procedure you expect to be called at program startup.* Note that when using Workbench 3.3.2, 3.3.2.1, and 3.3.2.2, the entry point for an Ada application is the debug symbol ada_main__
, rather than simply the main subprogram name (in lowercase) as for previous versions. This applies to the ''entry point'' value specified for a Workbench application or debug launcher, and to uses of the entry point in the host shell. It does not apply to the target shell. WRS has corrected this issue in Workbench 3.3.3. (See Wind River defect WIND00355069 for details.) A patch is available on their online support site for the versions mentioned above: https://support.windriver.com/olsPortal/faces/maintenance/downloadDetails.jspx?contentId=039960 Its name is "Workbench 3.2.2.2 Patch 00350276 for Windows Hosts''. The main procedure name in our example is "sdc". The following figure shows the dialog that is invoked when the "Browse" button is pressed. We have entered "sd" to filter out the rest of the names. .. image:: images/cross_debug_select_entry_point_dialog.png :align: center :alt: cross\_debug\_select\_entry\_point\_dialog For many applications these settings will suffice. However, you can also apply additional settings and switches. For example, it may be necessary to increase the amount of stack specified for your application. You can do that here in the "Advanced" panel. You can also select the way you want tasks to behave when breakpoints are hit via the "Target Mode" control. .. image:: images/cross_debug_dialog_advanced_panel.png :align: center :alt: cross\_debug\_dialog\_advanced\_panel You will likely find it useful to select the "Break on Entry" option for the "Debug" panel. Likewise, having the debugger automatically attach to tasks is convenient for multitasking applications. In the screen shot below, a typical debug configuration has been configured: .. image:: images/cross_debug_configure.png :align: center :alt: Launching A Debug Session ========================= Once you have created a debug configuration, you can launch a debug session from the Debug dialog by clicking "Debug". Workbench will first ensure your application is up-to-date by building it, unless you disable that behavior. The controlling preference is in the "Run/Debug" category, under the "Launching" page. .. image:: images/build_before_launch_preference.png :align: center :alt: build\_before\_launch\_preference The debugger will stop at the first part of the main program (at the elaboration of the declarative part, if any) so you will see something like the figure below. Note the presence of the file "sdc.out" now loaded onto the target in the Remote Systems view. .. image:: images/cross_debug_debugging.png :align: center :alt: launching a debug session Setting Breakpoints =================== You can easily create breakpoints in the source editor by double-clicking in the gray column on the left hand side of the editor window. A blue dot will appear in that column, next to the source line. In this context, you may find it useful to add line-numbers to the source view by selecting Window -> Preferences, expanding the node General -> Editors -> Text Editors and selecting "Show line numbers." Note that you can create breakpoints before beginning your debug session. The other primary way to set breakpoints is with the Breakpoint view. In the following, that view is shown below the Debug view. .. image:: images/cross_debug_controls.png :align: center :alt: 1 You can also set breakpoints by right-clicking on the space to the left of the source line and using the resulting contextual menu. .. image:: images/cross_debug_contextual_bp.png :align: center :alt: 1 Troubleshooting =============== Regardless of the technique used, the debugger may fail to set the breakpoint, complaining that the source cannot be found. In that case you will see something like the following error dialog. (Your specific source file names will be different): .. image:: images/breakpoint_path_not_mapped.png :align: center :alt: breakpoint\_path\_not\_mapped In that case, follow these steps to address the issue. First, open the launch configuration dialog used to launch the debugger on this code. In the following figure we click on the down-arrow next to the Debug symbol on the icon bar and select "Debug Configurations..." to invoke the dialog box that shows all existing configurations: .. image:: images/open_existing_debug_launch_config.png :align: center :alt: open\_existing\_debug\_launch\_config Note that you should not click on the project's launch configuration name directly from the Debug icon bar menu because that will simply launch the debugger with that configuration. We want to edit the configuration here, so we must invoke the configurations dialog. If multiple launch configurations exist you may need to select the configuration corresponding to your specific project. (In the figures for this example there is only one launch configuration, named "adamain" after the name of the entry point.) With your project selected, click on the "Source" tab located at the top of the dialog so that page will come to the front: .. image:: images/debug_launch_config_source_tab.png :align: center :alt: debug\_launch\_config\_source\_tab Click the "Add..." button, and in the resulting dialog box, select "Project" as shown in the following figure: .. image:: images/debug_launch_config_add_button.png :align: center :alt: debug\_launch\_config\_add\_button Press OK. Another dialog box will appear, allowing you to select the specific project to add. Select the project that contains the source file(s) within which you want to set breakpoints: .. image:: images/debug_launch_config_select_project.png :align: center :alt: debug\_launch\_config\_select\_project Press OK. The specified project will now appear within the launch configuration's Source Lookup Path: .. image:: images/config_with_project_in_source.png :align: center :alt: config\_with\_project\_in\_source Press Debug if you want to launch the debugger immediately, or Close if you intend to launch it later. The above need only be done once per launch configuration, not each time that configuration is used. You can also these steps prior to ever using the launch configuration the first time, but typically these steps will not be necessary. Controlling Program Execution ============================= In the "Device Debug" perspective the upper right-hand corner contains the "Debug" view. From this view you may view between debugging sessions, threads, and up and down the stack. The tool bar in the window provides buttons for running, halting, and stepping your application. Beneath this view is the breakpoint view. From this view you may review, enable and disable breakpoints as necessary. .. image:: images/cross_debug_controls.png :align: center :alt: 1 Examining Data ============== The Workbench debugger provides a tabbed dialog presenting various views for inspecting local variables, watchpoints, and registers. These tabs provide a variety of different tools for exploring information about the state of your halted application. **Note that you must halt the application's execution before you can examine the values of objects.** .. image:: images/cross_debug_data_views.png :align: center :alt: 1 **Special Note** In this version of the Workbench debugger, the names of Ada objects *declared within packages* must be entered in a particular format for the debugger to recognize them and display their values. Objects declared in other declarative parts do not have this issue. Currently, these objects are displayed in the Expressions view. Specifically, any dots in the package name must be replaced by two consecutive underscores and all lowercase letters must be used. For example, a variable named Alpha declared in package Ownship would be referenced as "Ownship.Alpha" within Ada source code. Within the debugger data views, the variable must be referred to as "ownship\_\_alpha" for the name to be recognized. Wind River is working to remove this restriction. For convenience, you can simply right-click on these objects in the source editor and select the "Add Watch Expression..." option. The encoded name of the selected entity will be displayed automatically in a dialog window. After clicking on OK, you will see the corresponding expression has been added to the Expression view. From there, you will be able to browse the content of your object in that view. In addition, you must set an environment variable to enable viewing the values of Ada variables with these names. Specifically, set DFW\_ENABLE\_ADA\_SYMBOL\_SEARCH to 1. You need only set this environment variable once, as long as it does not become undefined later. Note that Workbench provides additional optional views through the Window -> Show View menu item. Debugging Ada Tasks =================== It is possible to debug a multitasking Ada application because Ada tasks map directly to VxWorks tasks. All the VxWorks task-oriented debugging facilities apply. The following example uses the "Dining Philosophers" sample from the GNAT distribution. That example project can be found under the compiler installation in the directory share/examples/gnat/simple\_project/. After opening the project in GNATbench, place a breakpoint at line 53 of the file "phil.adb". That will stop any task of that type (all philosophers in this case) whenever it hits that line. Then create a new debug configuration and launch it. Immediately after launching you should see something similar to the screenshot below: .. image:: images/cross_debug_tasking.png :align: center :alt: debugging with tasks. Notice that no tasks appear in the Debug view. You must "attach" to kernel tasks before they will appear there. Once attached you can then see them and control them. The first step in attaching the tasks is to select them in the "Kernel Tasks" tree in the Remote Systems view, as shown below. You select all five philosopher tasks, ignoring (arbitrarily) the "maitre\_d" task. .. image:: images/cross_debug_tasks_to_attach.png :align: center :alt: debugging with tasks to attach You then right-click on any one of them to invoke the contextual menu and select the "Attach to Kernel Tasks (Tasks Mode)" menu entry: .. image:: images/cross_debug_attach_tasks_menu.png :align: center :alt: debugging with task attach menu As a result, the selected application-defined kernel tasks now appear in the debugger view (each has hit the breakpoint we set earlier even though their state is "running" from the operating system point of view): .. image:: images/cross_debug_tasks_after_attach.png :align: center :alt: debugging with tasks after attaching You can now apply all the controls provided. For example, after suspending each task you can show their stacks and navigate the source code by stepping up and down the stack frames. Note that you can now see that each has stopped on the breakpoint. .. image:: images/cross_debug_tasks_at_breakpoint.png :align: center :alt: debugging with tasks at BP Ending A Debug Session ====================== To finish your debug session, either allow your application to run to completion or halt it using the square red button in the debug tool bar. You can then right-click on the "Debug" icon in the top right hand of the display and click close to close the Debug perspective. Preparing To Debug VxWorks 653 Integration Projects =================================================== Debugging a VxWorks 653 project uses the same Workbench interfaces and facilities, but is sufficiently different from debugging other forms of VxWorks that a dedicated discussion is appropriate. The overall approach to debugging 653 systems consists of three steps: * Step 1: Build your module in debug mode. * Step 2: Run your system on the target. * Step 3: Attach the debugger to a task. These steps are not specific to applications written in Ada. Please see the Wind River documentation, specifically the "Debug" section of the "Wind River Workbench By Example (VxWorks 653 Version)" user guide and related pages, located under "Wind River Documentation > Guides > Host Tools". Section 6.6, "Using the Debugger" is especially applicable. Note that Step 1 requires prior completion of the "Creating and Building a VxWorks 653 Integration Project" tutorial also provided in this GNATbench User Guide. Step 1: Build your module in debug mode. ---------------------------------------- Use the "Advanced Device Development" perspective. Complete the "Creating and Building a VxWorks 653 Integration Project" tutorial provided in the GNATbench User Guide. Upon completion you must have created and successfully built a system containing a MOS, a POS, and two application partitions, all contained within an integration project. The steps below describe how to debug any such system but are written in terms of that concrete project. Debugging must be enabled when building a system that you wish to debug. The Ada project files in the tutorial are already set up appropriately for debugging so no changes are required. Step 2: Run your system on the target. -------------------------------------- Change to the "Device Debug" perspective. In the Terminal view, configure the terminal communication settings so that it specifies a serial port (e.g., COM1) used to connect the target board to the host computer. This can be accomplished via the Settings icon next to the Disconnect icon. .. image:: images/653_new_terminal_icon_settings.png :align: center :alt: The default values (9600 baud, 8 bits, et cetera) likely suffice. Specify the COM port you plugged the cable into on your host machine. .. image:: images/653_new_terminal_connection_dialog.png :align: center :alt: The exact serial port values can be determined by examining the "target.nr" file located in the target BSP directory. Assuming the default installation directory and a wrSbc750gx board, the file would be located here: C:\WindRiver\vxworks653-2.3.0.1\target\config\wrSbc750gx\target.nr Press OK. Using the green Connect icon in the Terminal view, connect the terminal instance to the board. .. image:: images/653_terminal_connect_icon_terminal_view.png :align: center :alt: Next, open the FTP Server application via the Wind River menu at the host operating system interface. (If you have not already done so, create the FTP user account referenced by the board startup software.) .. image:: images/653_start_ftp_server_menu.png :align: center :alt: Turn on the board (apply power). You should see boot output from the board in the connected terminal. Await complete loading of the integration project "boot.txt" file. Note that, as described below, the tutorial's application partitions will not execute yet. .. image:: images/653_boot_text_in_terminal.png :align: center :alt: In the Remote Systems view, select the target server connection corresponding to the board. (Create the target server connection if not previously created.) Use the green Connect icon to connect the selected target server to the board. .. image:: images/653_connect_target_icon_remote_sys_view.png :align: center :alt: Await completion of the connection step. Once connected to the board, the connection will appear something like the following: .. image:: images/653_new_target_connection_remote_sys_view.png :align: center :alt: With the target connection still selected in the Remove Systems view, open a host shell for that target. This can be accomplished using the "->i" icon in the icon bar at the top of Workbench itself. (You can also use the Target menu to open a host shell.) .. image:: images/653_new_host_shell_icon.png :align: center :alt: You should then see output in the shell, with the name of the MOS project as the prompt ("[coreOS] ->" in this tutorial). .. image:: images/653_new_host_shell_opened.png :align: center :alt: You are now ready to either run or debug the tutorial system. Initially, the tutorial application partitions do not execute because the active schedule does not allocate any time to them. This is by design, so that you can set up debugging if desired. See the text in the Concluding Points at the end of this document for details of setting up such a schedule. If you simply want to run the system instead of debugging it, enter "arincSchedSet 1" (without the quotes) at the host shell prompt. This will apply a different schedule that allocates time to the application partitions. Output will then appear in the connected terminal instance in the Terminal view. Alternatively, if you want to debug the system, follow the steps below before changing the schedule in the host shell. Step 3: Attach the debugger to a task. -------------------------------------- We will debug the receiver partition that acquires and displays integer values from the sender partition. These steps correspond to the subsection "Attaching the Debugger to a Partition Task" in the Wind River document cited earlier. In the Remote Systems view, select the connection for your target and expand the target connection "protection domains" section so that you can see the "receiver," "sender," and "vxSyslib" partitions. Expand the "receiver" partition. Under that partition, expand the "Protection domain tasks" section. You will see a single task there, named "tReceiver," in the suspended state. .. image:: images/653_receiver_protection_domain_task_in_tgt_connection.png :align: center :alt: Right-click on the "tReceiver" task and choose the "Debug -> Attach to tReceiver" menu entry. .. image:: images/653_debug_attach_to_treceiver_menu.png :align: center :alt: Doing so will create a new "Attach Target Context" debug launch configuration for the "tReceiver" task, automatically, the first time you debug the system. In subsequent debugging sessions, however, the Launch Configuration Selection dialog will be displayed, in case you want to change it. Assuming the launch configuration is still correct, simply ensure "Update and launch the selected launch configuration" is selected and press OK. In the Debug view you will see the new Attach Target Context showing the suspended "tReceiver" task. .. image:: images/653_treceiver_in_debug_view.png :align: center :alt: Using the Project Explorer view, expand the "receiver" project (nested within the Integration project), to show the "src" folder. Expand that folder and open the "tf_receiver.adb" file. This file contains the package body that declares the "Receiver_Process" task body. .. image:: images/653_receiver_source_in_proj_explorer.png :align: center :alt: Set a breakpoint on an arbitrary line or lines in the task body. For example, set a breakpoint on the line that prints the values (the call to Put on line 59, or thereabouts). You can also set breakpoints on those parts of the task body elaboration that involve actual execution, such as the declaration of the constant Maximum_Debug_Strength_Length (line 17). In the host shell, enter "arincSchedSet 1" (without the quotes) at the prompt to enable application partition execution. The earliest breakpoint set in the task will be hit and the host shell will reflect the breakpoint being reached. .. image:: images/653_host_shell_at_breakpoint.png :align: center :alt: The editor containing the source will show the line at which the debugger has suspended, due to the breakpoint being hit. .. image:: images/653_source_editor_at_elab_breakpoint.png :align: center :alt: The Debug view will show the receiver task suspended at the breakpoint. .. image:: images/653_debug_view_at_elab_breakpoint.png :align: center :alt: You can use the debugger as usual, for example to step, view values of variables, and so on. .. image:: images/653_variables_view_at_breakpoint.png :align: center :alt: If we disable the breakpoints and let the application partitions execute, we see the expected output in the terminal. Concluding Points ----------------- You should have a partition schedule set up beforehand, so that those application partitions to be debugged do not start executing the moment the system image is downloaded to the target. Schedules are defined in the "module.xml" file. In the tutorial this file appears as follows: .. image:: images/653_module_xml_showing_schedules.png :align: center :alt: For a discussion of setting up schedules, see section 5.8.2 "VxWorks 653 Application Projects" in the "Wind River Workbench By Example (VxWorks 653 Version)" user guide, located under "Wind River Documentation > Guides > Build > VxWorks 653 Partition OS Projects".