How to write and debug multithreaded C/C++ application on a remote target

A multithreaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread defines a separate path of execution.

This document describes How to write and debug multithreaded C/C++ applications on a remote target.

To create and debug the multithreaded C Project in TimeStorm

  1. Open your multithreaded C/C++ Project. If you want to create a new multithreaded project, go to Create a C Project using the sample multithread C program section below.
  2. Add a multithread flag to the project
  3. Build Project
  4. Set up Debug configuration for a remote target
  5. Debug multithreaded application

1. Open your multithreaded C/C++ Project:

Open your multithread c/c++ project using project explorer (we are using a C/C++ project created using the Multithread C Program) as shown below.

2. Add a multithread flag to the project

Make sure you are in the C/C++ perspective (Window → Perspective → Open Perspective → Other → C/C++) in TimeStorm.

Right-click your Project, and select properties.

Expand C/C++ Build > Settings, and select the Tool Settings tab.

Select Miscellaneous under GCC C/C++ Linker, append '-pthread' to the already existing flags as shown below.

3. Build project:

Right-click your project, and select Build Project as shown below.

3. Set up Debug configuration for a remote target:

A Debug Configuration is a collection of settings that are required to download and debug an application. The debug configuration is persistent and can be launched multiple times to debug the application.

To debug the application on the remote target, you have to create a debug configuration. To create a debug configuration, right-click on the project and click on ‘Debug As > Remote C/C++ application’. This will open the Debug configurations dialog as shown below.

Note that an entry is created under TimeStorm C/C++ remote category with the project name appended with the Active build configuration, and other values are filled in with the default values that should work.

The Debug configuration entries are categories in different tabs on the right-hand panel and are explained below.

To Debug the application, mostly you have to just select the remote target on the target tab and click the Debug button.

Main Tab:

In the Main tab shown below, you can change the C/C++application by searching the project. You can change the project too if you want to use this configuration for a different project.

Arguments tab:

In the Arguments tab shown below, you can specify the arguments to be passed to the application program. The remote working directory is set as ‘.’, which means that the directory specified in the target definition is used as the working directory.

The command to be executed is filled in. Uncheck ‘Use default command’ to change this value. Keep in mind the directory structure on your target when constructing this command. For example, if you have copied your application file to a directory named /apps but you want to execute it from a working directory named /home/test, you must include the path to your application in your command.

For example: ../../apps/my_app

Environment tab

In the ‘Environment’ tab shown below, you can set environment variables for the target.

The panel shown above contains the following buttons:

ADD — Click the ‘Add’ button to create a new entry, and the ‘New Environment Variable’ dialog will appear, as shown below. Click the ‘Variables’ button to select the variables that you want to use. Then, click ‘OK’ twice.

Select — Click the ‘Select‘ button to import environment variables from the host file system.

Edit — To change an entry, select it from the list, and click the ‘Edit’ button.

Remove — To delete an entry, select it from the list, and click the ‘Remove’ button.

Debugger:

To change the debugger settings, click on the Debugger tab as shown below.

This tab contains the following options:

Stop on startup at — Select this checkbox if you want execution to pause when your application starts. (This option is selected by default.)

Specify the function name at which the execution should pause.

Debugger Options — This section of the panel includes three tabs:

  1. Main tab
  2. Shared Libraries tab
  3. GDB Server Settings tab

1. Main:

This tab includes the following fields:

GDB Debugger — This field is filled in with the gdb from the SDK used with the Active Build Configuration to build the project. Set ‘Debug’ as the Active Build Configuration to be sure that the correct gdb is filled in.

GDB command file — This field allows you to specify a .gdb-command file using the Browse button. The debugger will execute the commands specified in this file.

2. Shared Libraries:

The Shared Libraries tab shown below includes the following options:

Directories — This field specifies any additional directories for the debugger to search to find shared libraries (with debugging symbols). By default the debugger will automatically search the paths specified in the project's build settings (see option below). Use the ‘Add’ button if you want to add other paths. Use the ‘Up’ and ‘Down’ buttons to move through the list of directories. Use the ‘Remove’ button to delete a path.

Load shared library symbols automatically — Select this checkbox if you want these library symbols to be displayed as loaded in the ‘Shared Libraries’ view and if you want the debugger to hit any breakpoints in the shared library project. (This option is selected by default.)

3. GDB Server Settings:

This tab includes the following fields:

GDB Server Path — This field is filled in with the gdb server path as gdbserver. You can modify it as per your preferences.

Port Number — This field is filled in with the gdb server port as ‘2345’. You can modify it as per your preferences.

GDB Server Options — This field is optional. Any additional GDB server options can be added here.

Remote Timeout (seconds) — GDB Server Timeout can set here in seconds which is optional.

Source tab

The Source tab shown below, shows the location of the source files for the project.

Source Lookup Path — This field shows the project being run, as well as any projects that it References.

Add — You can add arbitrary source file locations by using the Add button. These locations are searched after the generic locations, from the top to the bottom item in order.

Edit, Remove, Up, Down — The other buttons to the right of the list allow you to edit, remove, or reorder the list items, and to restore the default information.

Search for duplicate source files on the path — Selecting this checkbox causes TimeStorm to notify the user if it is unable to determine which source file corresponds to an executing binary file. For example, if you have two source files with the same filename in different directories of the search path, TimeStorm is unable to determine which file is related to the binary file with that name. If this checkbox is selected, TimeStorm displays a message and asks the user to select which file to use. This checkbox is not selected by default.

Target tab:

The Target tab shown below, allows you to select the hardware target used when you run the application.

In the Target tab, use the drop-down list to select a hardware target that you have already created. If you have not yet created a hardware target or want to change the settings for an existing target, click ‘Manage targets’ to open the Hardware Targets management utility.

Download Files tab:

In the ‘Download Files’ tab shown below, you can select the files that TimeStorm transfers to your target. The application that has to be downloaded is already listed. You can use this panel to download additional files to your target, along with your application.

The application specified in the File field is listed as [Target Program]. This is the application that will be debugged. You can change where it is downloaded by selecting it and clicking Edit. If the program links in shared libraries, then these libraries will be downloaded to the target as well and the Files field is listed as [Target Program and Libraries]. These libraries will be downloaded to the same location as the target program. To download the program and libraries to separate locations, remove the default entry and re-add each as a separate entry.

Upload files to the target check-box option: This option is used to copy the files to target by unchecking the ‘Upload files to the target’ check-box configuration won’t copy the files to the remote target.

In case, if you want to transfer only a few files (not all the files in the project to the remote target) then check [Upload files to the target] and remove default settings (project) by clicking on the remove button in the Download Files tab. Then add files which you want to upload to the remote target by clicking on the Add files button in the Download Files tab.

This panel contains the following buttons:

Add File – Use the ‘Add File’ button to specify additional files to transfer, along with the application. These files are transferred every time you transfer the application file.

Edit – To change where the application (or any other file in this list) is installed, select it and click ‘Edit’ to change its destination directory.

Remove – To eliminate a file from the items to download, select it in the list and click the ‘Remove’ button.

Download Now – The ‘Download Now’ button copies files immediately, without running the application.

Restore Default – The ‘Restore Default’ button resets the panel to its initial state (download only the application and its libraries).

NOTE: Downloaded files overwrite any identically named files on the target without giving a warning. TimeStorm will not create destination directories on the target, so be sure to create them before launching the configuration.

Common tab:

The ‘Common’ tab shown below, sets options for sharing this run configuration among multiple projects.

The options with the Common tab include:

Local File — By default, debug configurations are saved with the workspace state files, so they can only be used with projects in the current workspace. (This setting corresponds to the ‘Local file’ radio button on this panel.) However, you can make the configuration available for use in other workspaces by choosing the ‘Shared file’ radio button.

Shared File — When you select this option, the debug configuration is saved as a .launch file that can be imported into another TimeStorm workspace. Optionally, you can specify a different location for the file so that it is more easily accessible to multiple projects.

Display in Favorites Menu — You can select whether to include this Debug configuration on the main ‘Debug’ menus. For example, if you select the ‘Debug’ checkbox, the Debug configuration always appears in the ‘Debug History’ submenu.

You can choose to include the debug configuration in either menu, both menus, or neither menu.

5. Debug multithreaded application

After modifying the debugger settings, click on the Debug button to start debugging. TimeStorm will connect to the target, download the application, start the gdbserver and prompt you to switch to Debug perspective. Debug perspective is a layout of various views like stack, variables and breakpoints management that help you in debugging. Select the ‘Remember my decision’ checkbox and click on the yes button. The debug perspective will open as shown below and the debugger waits at the breakpoint you have set in the code or the ‘stop at function’ you entered in the debugger tab.

You can use the buttons circled in the figure above to step in, step out, pause and terminate the debug session.

Stepping commands: The TimeStorm Platform helps developers debug by providing buttons in the toolbar and key binding shortcuts to control program execution.

Adding a breakpoint:

You can add a breakpoint at a line in your source code, by opening the file in the editor and double clicking in the vertical grey bar in the source editor next to the line where you would like to add the breakpoint as shown below.

Please refer to https://wiki.eclipse.org/CDT/User/FAQ#What_is_the_difference_between_Non-stop_and_All-stop_multi-threaded_debugging.3F for debugging multithreaded applications.

Create a C Project using the sample multithread C program

To create a Multithreaded project, open the ‘New Project’ wizard by choosing File → New → Project from the main menu OR click the ‘New’ button and use the drop-down menu to the right of the button to choose ‘Project’ as shown below.

Expand C/C++, choose a C Project, and click Next. The new C Wizard as shown below can be used to create several different types of projects, including ‘Executable’ and ‘Shared and Static Library’.

Project page

  1. Enter a Project Name.
  2. Under the ‘Project Type’ heading, expand Executable, and select the initial source code (MultiThread C Program) you would want in the project.
  3. Under the Toolchains heading select the TimeStorm Cross-Compile Toolchain.
  4. Click ‘Next’ to bring up the ‘Basic Settings’ as shown below.

    Basic settings page

    On this page, set the basic properties of the project like Author, Copyright notice, Greeting message and Source (where the project source files are to be stored within the project).

    Click ‘Next’ to bring up the ‘Select Configurations’ as shown below.

    Select build configuration page

    Build Configuration is a set of pre-defined compiler and linker settings that are used to build a project.

    By default, TimeStorm creates three Build Configurations for new projects:

    Debug — This setting performs no code optimization and attaches complete debugging information. These settings are designed to make debugging as easy as possible.

    Release — This setting has the highest compiler code optimization settings. The output will not include any debugging symbols. Code compiled with this configuration is ready for production use.

    GnuProfiler — This setting builds the software with debugging information as well as code to collect profiling information via GNU gprof.

    You can change the build configuration settings before creating the project by clicking the ‘Advanced Settings…’ button. You can also change these settings after creating the project.

    Click Next to continue.

    Select SDK page:

    The Select SDK page show below allows you to choose the SDK you want to use with the project. Select the SDK Type and then choose the SDK.

    Click Finish to create and exit the wizard. The new project is created and displayed in the Project Explorer view as shown below.

    After creating the Multithread Project, follow the above steps (Step2: Add multithread flag to the project, Step3: Build Project, Step4: Set up Debug configuration for a Remote target, Step5:Debug multithreaded application) to debug the project.