You copied the Doc URL to your clipboard.

13 Using and writing plugins

Plugins are a quick and easy way to preload a library into your application and define some breakpoints and tracepoints during its use. They consist of an XML file which instructs DDT what to do and where to set breakpoints or tracepoints.

Examples are MPI correctness checking libraries, or you could also define a library that is preloaded with your application that could perform your own monitoring of the application. It also enables a message to be displayed to the user when breakpoints are hit, displaying, for example, an error message where the message is provided by the library in a variable.

13.1 Supported plugins

Arm DDT supports plugins for two MPI correctness-checking libraries:

Arm DDT comes with two plugins for the GNU and LLVM compiler sanitizers.

  • Address Sanitizer:

    The Address Sanitizer (also known as ASan) is a memory error detector for C/C++ code. It can be used to find various memory-related issues including use after free, buffer overflows, and use after return.

    To enable the Address Sanitizer:

    1. Compile your application whilst passing the -fsanitize=address compiler option to your compiler.
    2. Enable the Address Sanitizer plugin within Arm DDT. For more information on how to enable plugin withing Arm DDT , please refer to the 13.3 Using a plugin section.

    When compiling with GNU 7 you must disable leak detection due to a conflict with ptrace and this aspect of the plugin. To disable leak detection, either:

    1. Add the following piece of code into your application:
      
      extern "C" int __lsan_is_turned_off() { return 1; }
                
                
      
    2. Set the LSAN_OPTIONS environment variable at runtime, using:
      
      LSAN_OPTIONS=detect_leaks=0
                
                
      

    Note

    ASan is not compatible with Arm DDT's memory debugging.

  • Thread Sanitizer:

    The Thread Sanitizer (also known as TSan) is a data race detector for C/C++ code. A data race occurs when two different threads attempt to write to the same memory at the same time.

    To enable the Thread Sanitizer:

    1. Compile your application whilst passing the -fsanitize=thread compiler option to your compiler.
    2. Enable the Thread Sanitizer plugin within Arm DDT. For more information on how to enable plugin within Arm DDT , please refer to the 13.3 Using a plugin section.

    Note

    TSan is not compatible with Arm DDT's memory debugging.

13.2 Installing a plugin

To install a plugin, locate the XML Arm DDT plugin file provided by your application vendor and copy it to:


   {arm-forge installation directory}/plugins/
                                                                                       
                                                                                       

It will then appear in Arm DDT's list of available plugins on the DDT-Run dialog.

Each plugin takes the form of an XML file in this directory. These files are usually provided by third-party vendors to enable their application to integrate with Arm DDT. A plugin for the Intel Message Checker (part of the Intel Trace Analyser and Collector) is included with the DDT distribution.

13.3 Using a plugin

To activate a plugin in Arm DDT, simply click on the checkbox next to it in the window, then run your application. Plugins may automatically perform one or more of the following actions:

  • Load a particular dynamic library into your program
  • Pause your program and show a message when a certain event such as a warning or error occurs
  • Start extra, optionally hidden MPI processes. See the Writing Plugins section for more details on this.
  • Set tracepoints which log the variables during an execution.

If Arm DDT says it cannot load one of the plugins you have selected, check that the application is correctly installed, and that the paths inside the XML plugin file match the installation path of the application. Example Plugin: MPI History Library

Arm DDT's plugin directory contains a small set of files that make a plugin to log MPI communication.

  • Makefile - Builds the library and the configuration file for the plugin.
  • README.wrapper - Details the installation, usage and limitations
  • wrapper-config - Used to create the plugin XML config file, used by DDT to preload the library and set tracepoints which will log the correct variables.
  • wrapper-source - Used to automatically generate the source code for the library which will wrap the original MPI calls.

The plugin is designed to wrap around many of the core MPI functions and seamlessly intercept calls to log information which is then displayed in Arm DDT. It is targeted at MPI implementations which use dynamic linking, as this can be supported without relinking the debugged application.

Static MPI implementations can be made to work also, but this is outside the scope of this version.

This package must be compiled before first use, in order to be compatible with your MPI version. It will not appear in Arm DDT's GUI until this is done.

To install as a non-root user in your local ~/.allinea/plugins directory, type the following command:


   make local

To install as root in the DDT plugins directory, type the following command:


   make

Once you have run the above, start Arm DDT and to enable the plugin, click the Details… button to expand the Plugins section of the Run window. Select History v1.0, and start your job as normal. DDT will take care of preloading the library and setting default tracepoints.

This plugin records call counts, total sent byte counts, and the arguments used in MPI function calls. Function calls and arguments are displayed (in blue) in the Input/Output panel.

The function counts are available in the form of a variable:

_MPIHistoryCount_{function}

The sent bytes counters are accumulated for most functions, but specifically they are not added for the vector operations such as MPI_Gatherv.

These count variables within the processes are available for use within Arm DDT, in components such as the cross-process comparison window, enabling a check that, for example, the count of MPI_Barriers is consistent, or primitive MPI bytes sent profiling information to be discovered.

The library does not record the received bytes, as most MPI receive calls in isolation only contain a maximum number of bytes allowed, rather than bytes received. The MPI status is logged, the SOURCE tag therein enables the sending process to be identified.

There is no per-communicator logging in this version.

This version is for demonstration purposes for the tracepoints and plugin features. It could generate excessive logged information, or cause your application to run slowly if it is a heavy communicator.

This library can be easily extended, or its logging can be reduced, by removing the tracepoints from the generated history.xml file (stored in ALLINEA_FORGE_PATH or ~/.allinea/plugins). This would make execution considerably faster, but still retain the byte and function counts for the MPI functions.

13.4 Writing a plugin

Writing a plugin for Arm DDT is described here. An XML plugin file is required that is structured similar to the following example:


   <plugin name="Sample v1.0" description="A sample plugin that demonstrates DDT's plugin interface."> 
<preload name="samplelib1" />
<preload name="samplelib2" />
<environment name="SUPPRESS_LOG" value="1" />
<environment name="ANOTHER_VAR" value="some value" />
<breakpoint location="sample_log" action="log" message_variable="message" />
<breakpoint location="sample_err" action="message_box" message_variable="message" />
<extra_control_process hide="last" />
</plugin>

Only the surrounding plugin tag is required. All the other tags are entirely optional.

A complete description of each tag appears in the following table.

Note

If you are interested in providing a plugin for DDT as part of your application bundle, Arm can provide you with any assistance you need to get up and running. Contact Arm support at Arm support for more information.

13.5 Plugin reference

Tag Attribute

Description

plugin name

The plugin's unique name. This should include the application/library the plugin is for, and its version. This is shown in the DDT-Run dialog.

plugin description

A short snippet of text to describe the purpose of the plugin/application to the user. This is also shown in the DDT-Run dialog.

preload name

Instructs DDT to preload a shared library of this name into the user's application. The shared library must be locatable using LD_LIBRARY_PATH, or the OS will not be able to load it.

environment name

Instructs DDT to set a particular environment variable before running the user's application.

environment value

The value that this environment variable should be set to.

breakpoint location

Instructs DDT to add a breakpoint at this location in the code. The location may be in a preloaded shared library (see above). Typically this will be a function name, or a fully-qualified C++ namespace and class name. C++ class members must include their signature and be enclosed in single quotes, for example, 'MyNamespace::DebugServer:: breakpointOnError(char*)'

breakpoint action

Only message_box is supported in this release. Other settings will cause DDT to stop at the breakpoint but take no action.

breakpoint message_variable

A char* or const char* variable that contains a message to be shown to the user. DDT will group identical messages from different processes together before displaying them to the user in a message box.

extra_control_process hide

Instructs Arm DDT to start one more MPI process than the user requested. The optional hide attribute can be first or last, and will cause Arm DDT to hide the first or last process in MPI_COMM_WORLD from the user. This process will be allowed to execute whenever at least one other MPI process is executing, and messages or breakpoints (see above) occurring in this process will appear to come from all processes at once. This is only necessary for tools such as Marmot that use an extra MPI process to perform various runtime checks on the rest of the MPI program.

tracepoint location

See breakpoint location.

tracepoint variables

A comma-separated list of variables to log on every passing of the tracepoint location.

Was this page helpful? Yes No