Skip Navigation Links | |
Exit Print View | |
![]() |
Oracle Solaris Studio 12.3: Thread Analyzer User's Guide Oracle Solaris Studio 12.3 Information Library |
1. What is the Thread Analyzer and What Does It Do?
1.1 Getting Started With the Thread Analyzer
1.2 The Thread Analyzer Usage Model
1.2.1 Usage Model for Detecting Data Races
1.2.1.1 Instrument the Code for Data Race Detection
1.2.1.2 Create an Experiment on the Instrumented Application
1.2.1.3 Examine the Experiment for Data Races
1.2.2 Usage Model for Detecting Deadlocks
1.2.2.1 Create an Experiment for Detecting Deadlocks
The following steps show the process by which you can troubleshoot your multithreaded program with the Thread Analyzer.
Instrument the program, if doing data race detection.
Create a data-race-detection or deadlock-detection experiment.
Examine the experiment result and establish whether or not the multithreaded programming conflicts revealed by the Thread Analyzer are legitimate bugs or benign phenomena.
Fix the legitimate bugs and create additional experiments (step 2 above) with varied factors such as different input data, a different number of threads, varied loop schedules or even different hardware. This repetition helps locate non-deterministic problems.
Steps 1 through 3 above are described in the following sections.
You must perform three steps to detect data races:
Instrument the code to enable data race detection
Create an experiment on the instrumented code
Examine the experiment for data races
To enable data race detection in an application, the code must first be instrumented to monitor memory accesses at runtime. You can instrument your code at the application source-level during compilation, or at the application binary-level by running an additional tool on the binary.
Source-level instrumentation is done by the compiler when you use a special option. You can also specify the optimization level and other compiler options to use. Source-level instrumentation can result in faster runtime since the compiler can do some analysis and instrument fewer memory accesses.
Binary-level instrumentation is useful when the source code is not available. You might also use binary instrumentation if you have the source code, but cannot compile shared libraries that are used by the application. Binary instrumentation using the discover tool instruments the binary as well as all shared libraries as they are opened.
To instrument at the source level, compile the source code with the special compiler option:
-xinstrument=datarace
With this compiler option, the code generated by the compiler will be instrumented for data race detection.
The -g compiler option should also be used when building application binaries. This option causes extra data to be generated which allows the Thread Analyzer to display source code and line number information when reporting data races.
To instrument at the binary level, you must use the discover tool. If the binary is named a.out, you can create an instrumented binary a.outi by executing:
discover -i datarace -o a.outi a.out
The discover tool automatically instruments all shared libraries as they are opened, whether they are statically linked in the program or opened dynamically by dlopen(). By default, instrumented copies of libraries are cached in the directory $HOME/SUNW_Bit_Cache.
Some useful discover command line options are shown below. See the discover(1) man page for details.
Output the instrumented binary to the specified file name
Do not instrument the specified library
Do not instrument any libraries
Change the cache directory to dir
For instrumenting a program's binary code to detect data races, the discover tool requires the input binary to be compiled under the following conditions:
Operating system version must be at least Oracle Solaris 10 Update 5 or Oracle Solaris 11.
Compiler must be from a release no earlier than Oracle Solaris Studio 12 Update 1.
One of the compiler optimization flags (-xO1, -xO2, -xO3, -xO4, -xO5) must be used.
The -g compiler option should also be used to enable the Thread Analyzer to display source code and line number information when reporting data races.
You might also be able to use the discover tool on an earlier Solaris version running on a SPARC-based system if the binary was compiled with the compiler option -xbinopt=prepare. See the cc(1), CC(1), or f95(1) man pages for information about this compiler option.
To create a data-race-detection experiment, use the collect command with the -r race flag to run the application and collect experiment data during the execution of the process. When you use the -r race option, the collected data includes pairs of data accesses that constitute a race.
You can examine the data-race-detection experiment with the tha command, which starts the Thread Analyzer graphical user interface. You can also use the er_print command-line interface.
Two steps are involved in detecting deadlocks:
Create a deadlock detection experiment.
Examine the experiment for deadlocks.
To create a deadlock-detection experiment, use the collect command with the -r deadlock flag to run the application and collect experiment data during the execution of the process. When you use the -r deadlock option, the collected data includes lock holds and lock requests that form a circular chain.
You can examine the deadlock-detection experiment with the tha command, which starts the Thread Analyzer graphical user interface. You can also use the er_print command-line interface.
If you want to detect data races and deadlocks at the same time, follow the three steps in 1.2.1 Usage Model for Detecting Data Races for detecting data races, but use the collect command with the -r race,deadlock flag to run the application. The experiment will contain both race-detection and deadlock-detection data.