JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Oracle Solaris Studio 12.3: Thread Analyzer User's Guide     Oracle Solaris Studio 12.3 Information Library
search filter icon
search icon

Document Information

Preface

1.  What is the Thread Analyzer and What Does It Do?

2.  The Data Race Tutorial

2.1 Data Race Tutorial Source Files

2.1.1 Getting the Data Race Tutorial Source Files

2.1.2 Source Code for prime_omp.c

2.1.3 Source Code for prime_pthr.c

2.1.3.1 Effect of Data Races in prime_omp.c and prime_pthr.c

2.2 How to Use the Thread Analyzer to Find Data Races

2.2.1 Instrument the Code

2.2.1.1 To Instrument Source Code

2.2.1.2 To Instrument Binary Code

2.2.2 Create a Data Race Detection Experiment

2.2.3 Examine the Data Race Detection Experiment

2.2.3.1 Using Thread Analyzer to View the Data Race Experiment

2.2.3.2 Using er_print to View the Data Race Experiment

2.3 Understanding the Experiment Results

2.3.1 Data Races in prime_omp.c

2.3.2 Data Races in prime_pthr.c

2.3.3 Call Stack Traces of Data Races

2.4 Diagnosing the Cause of a Data Race

2.4.1 Check Whether or Not the Data Race is a False Positive

2.4.2 Check Whether or Not the Data Race is Benign

2.4.3 Fix the Bug, Not the Data Race

2.4.3.1 Fixing Bugs in prime_omp.c

2.4.3.2 Fixing Bugs in prime_pthr.c

2.5 False Positives

2.5.1 User-Defined Synchronizations

2.5.2 Memory That is Recycled by Different Threads

2.6 Benign Data Races

2.6.1 A Program for Finding Primes

2.6.2 A Program that Verifies Array-Value Types

2.6.3 A Program Using Double-Checked Locking

3.  The Deadlock Tutorial

A.  APIs Recognized by the Thread Analyzer

B.  Useful Tips

2.2 How to Use the Thread Analyzer to Find Data Races

The Thread Analyzer follows the same “collect-analyze” model that the Oracle Solaris Studio Performance Analyzer uses.

There are three steps involved in using the Thread Analyzer:

  1. 2.2.1 Instrument the Code

  2. 2.2.2 Create a Data Race Detection Experiment

  3. 2.2.3 Examine the Data Race Detection Experiment

2.2.1 Instrument the Code

In order to enable data race detection in a program, the code must first be instrumented to monitor memory accesses at runtime. The instrumentation can be done on application source code, or on application binaries that have been compiled with certain Oracle compiler optimization flags. The tutorial shows how to use both methods of instrumenting the programs.

2.2.1.1 To Instrument Source Code

To instrument the source code, you must compile the application with the special compiler option -xinstrument=datarace. This option instructs the compiler to instrument the generated code for data race detection.

Add the -xinstrument=datarace compiler option to the existing set of options you use to compile your program.


Note - Be sure to also specify the -g option when you compile your program with -xinstrument=datarace to generate additional information to enable the Analyzer's full capabilities. Do not specify a high level of optimization when compiling your program for race detection. Compile an OpenMP program with -xopenmp=noopt. The information reported, such as line numbers and call stacks, may be incorrect when a high optimization level is used.


You can use the following commands for instrumenting the source code for the tutorial:

% cc -xinstrument=datarace -g -xopenmp=noopt -o prime_omp_inst prime_omp.c -lm
% cc -xinstrument=datarace -g -o prime_pthr_inst prime_pthr.c -lm

Notice that in the example, the output file is specified with _inst at the end so that you can tell that the binary is the instrumented binary. This is not required.

2.2.1.2 To Instrument Binary Code

To instrument a program's binary code instead of the source code, you need to use the discover tool, which is included in Oracle Solaris Studio and is documented in the discover(1) man page and Oracle Solaris Studio 12.3: Discover and Uncover User’s Guide.

See Binary-level Instrumentation for more information about requirements for binary instrumentation.

For the tutorial examples, type the following command to compile the code with optimization level 3 to create binaries that can be used by discover.

% cc -xopenmp=noopt -g -o prime_omp_opt prime_omp.c -lm
% cc -g -O3 -o prime_pthr_opt prime_pthr.c -lm

Then run discover on the prime_omp_opt and prime_pthr_opt optimized binaries that you created:

% discover -i datarace -o prime_omp_disc prime_omp_opt
% discover -i datarace -o prime_pthr_disc prime_pthr_opt

These commands create instrumented binaries, prime_omp_disc and prime_pthr_disc that you can use with collect to create experiments that you can examine with the Thread Analyzer.

2.2.2 Create a Data Race Detection Experiment

Use the collect command with the -r race flag to run the program and create a data race detection experiment during the execution of the process. For OpenMP programs, make sure that the number of threads used is larger than one. In the tutorial samples, four threads are used.

To create experiments from the binaries that you created by instrumenting the source code:

% collect -r race -o prime_omp_inst.er prime_omp_inst
% collect -r race -o prime_pthr_inst.er prime_pthr_inst

To create experiments from the binaries that you created by using the discover tool:

% collect -r race -o prime_omp_disc.er prime_omp_disc
% collect -r race -o prime_pthr_disc.er prime_pthr_disc

To increase the likelihood of detecting data races, it is recommended that you create several data race detection experiments using collect with the -r race flag. Use a different number of threads and different input data for each experiment.

For example, in prime_omp.c, the number of threads is set by the following line:

#define THREADS 4

The number of threads can be changed by changing 4 in the above to some other integer larger than 1, for example 8.

The following line in prime_omp.c limits the program to look for prime numbers between 2 and 3000:

#define N 3000

You can provide different input data by changing the value of N to make the program do more or less work.

2.2.3 Examine the Data Race Detection Experiment

You can examine a data race detection experiment with the Thread Analyzer, the Performance Analyzer, or the er_print utility. Both the Thread Analyzer and the Performance Analyzer present a GUI interface; the Thread Analyzer presents a simplified set of default tabs, but is otherwise identical to the Performance Analyzer.

2.2.3.1 Using Thread Analyzer to View the Data Race Experiment

To start the Thread Analyzer, type the following command:

% tha

The Thread Analyzer GUI has a menu bar, a tool bar, and a split pane that contains tabs for the various displays.

On the left-hand pane, the following three tabs are shown by default:

On the right-hand pane of the Thread Analyzer display, the following two tabs are shown:

2.2.3.2 Using er_print to View the Data Race Experiment

The er_print utility presents a command-line interface. You can use the er_print utility in an interactive session and specify sub-commands during the session. You can also use command-line options to specify sub-commands non-interactively.

The following sub-commands are useful for examining races with the er_print utility:

Refer to the collect(1), tha(1), analyzer(1), and er_print(1) man pages for more information.