tha(1)tha(1)NAMEtha - GUI for analyzing a Thread Analyzer experiment
SYNOPSIStha [ options ] [ thread-analyzer-experiment ]
DESCRIPTION
The tha(1) command invokes a GUI for analyzing the various Thread Ana‐
lyzer experiments collected by the Collector using the collect(1) com‐
mand. The GUI is a version of the Performance Analyzer customized for
examining Thread Analyzer experiments.
The Collector gathers thread analysis information to create a Thread
Analyzer experiment during the execution of a process. The tha command
reads in such an experiment and displays any errors detected. The cur‐
rent Thread Analyzer supports data race detection and deadlock detec‐
tion. For further information on those, see the sections "DATA RACE
DETECTION" and "DEADLOCK DETECTION" below.
A command-line version of the tha command is available as the
er_print(1) utility.
To start tha, type the following on the command line:
tha [thread-analyzer-experiment]
Both the tha command and the analyzer(1) command can be used to read a
Thread Analyzer experiment. The tha command has the same functionality
and features as the analyzer command, but shows a simplified set of
default tabs that pertain to Thread Analyzer experiments.
OPTIONS
Option Meaning
-j | --jdkhome jvmpath
Specify the path to the Java[TM] virtual machine (JVM) soft‐
ware for running the analyzer. The default path is taken
first by examining environment variables for a path to the
JVM, in the order JDK_HOME, and then JAVA_PATH. If neither
environment variable is set, the default path is where the
Java[TM] 2 Platform, Standard Edition technology was
installed with the Oracle Solaris Studio release, and if it
was not installed, as set in the user's PATH. (The terms
"Java virtual machine" and "JVM" mean a virtual machine for
the Java(TM) platform.)
-J jvm-option
Specify JVM(TM) software options.
-f | --fontsize size
Specify the font size to be used in the analyzer.
-v | --verbose
Print version information and Java runtime arguments before
starting.
-V | --version
Print version information and exit.
-? | -h| --help
Print usage information and exit.
THA WINDOW -- LEFT HAND TABS
The tha window has a menu bar, a tool bar, and a split pane that con‐
tains tabs for the various displays.
The left-hand pane contains tabs for the principal displays. The tabs
that are actually present in the pane are controlled by a rtabs direc‐
tive in a .er.rc file. The Experiments tab is always shown. The Races
tab will be shown if data race data is in one or more of the loaded
experiments. The Deadlocks tab will be shown if deadlock data is in
one or more of the loaded experiments. The Dual Source tab will be
shown if either the Races or Deadlocks tabs are shown.
By default, the Races tab is selected, if available. If it is not
available, the Deadlocks tab is selected, if it is available. If nei‐
ther is available, only the Experiments tab will be visible.
The Races Tab
The Races tab is shown if data for data races is in one or more of
the experiments loaded. The tab presents the list of data races
detected in the application. By default, the first data race in
the list of data races is selected.
For each data race, the following information is shown:
· A unique id that identifies the data race
· One or more virtual addresses (Vaddr) associated with the data
race. If the data race occurs on multiple virtual addresses,
then "(Multiple Addresses)" is shown instead of a single
address.
· The two accesses by two different threads that constitute the
data race. For each access, the type of the access (Read or
Write) is shown, as well as the function, offset, and line num‐
ber in the source code where the access occurred.
· The total number of traces associated with the data race. The
individual traces can be displayed by clicking on the button to
the left of the "Total Traces" label.
Each trace refers to the pair of thread callstacks at the time
the two data race accesses occurred. When a trace is selected,
the two callstacks will be displayed in the Race Details tab in
the right-hand pane of the tha window (see below). The frame at
the top of the callstack for the first access is selected by
default.
The Deadlocks Tab
The Deadlocks tab is shown if deadlock data is in one or more of
the experiments loaded. The tab presents the list of deadlocks
detected in the application. By default the first deadlock in the
list of deadlocks is selected.
For each deadlock, the following information is shown:
· A unique id that identifies the deadlock
· The type of the deadlock (potential or actual)
· The total number of threads involved in the deadlock.
The context of each thread can be displayed by clicking on the
button to the left of the "Total Threads" label. Each thread con‐
text shows the two operations corresponding to holding a first
lock and deadlocking attempting to acquire a second lock.
When a thread context is selected, the two callstacks where the
lock hold and lock request took place will be displayed in the
Deadlock Details tab in the right-hand pane of the tha window (see
below).
The Dual Source Tab
The Dual Source tab is shown if either data race or deadlock data
is in one or more of the experiments loaded. The Dual Source tab
shows the two source locations pertaining to the selected data
race or deadlock.
For a selected data race, the Dual Source tab shows the source
locations for the two accesses of the data race selected, as shown
in the Race Details tab. For a selected deadlock, the Dual Source
tab shows the two operations corresponding to holding a first lock
and deadlocking attempting to acquire a second lock by the thread
selected, as shown in the Deadlock Details tab.
The source line where the access occurred will appear highlighted.
If the source code was compiled with -g, then compiler commentary
may appear interleaved in the source code.
To the left of each source line, metrics that relate to that
source line are shown. For data races, the default metric shown is
the Exclusive Race Accesses metric; this metric gives a count of
the number of times a data race access was reported on that line.
For deadlocks, the default metric shown is the Exclusive Deadlocks
metric; this metric gives a count of the number of times a lock
hold or lock request operation, which was involved in a deadlock,
was reported on that line.
Exclusive metrics relate to the source line at which they appear
only. Inclusive metrics relate to the source line at which they
appear and to any functions that have been called from that source
line. Count metrics are shown as an integer count. Percentages
are shown to a precision of 0.01%. Because of rounding, percent‐
ages may not sum to exactly 100%.
The metrics that are shown can be changed using the Set Data Pre‐
sentation dialog box (see "Selecting the Data Presentation
Options" below).
To reorder the columns of metrics in the source display, drag the
column header to the place you want it to appear.
The Experiments Tab
The Experiments tab is divided into two panels. The top panel
shows a tree that contains nodes for the load objects in the
experiment loaded. The bottom panel lists error and warning mes‐
sages from the tha session.
For more information about the Experiments tab, refer to the ana‐
lyzer(1) man page.
THA WINDOW -- RIGHT HAND TABS
The right-hand pane of the tha window contains tabs for displaying
additional information about a data race. The Summary tab is always
shown. The Race Details tab is shown if the Races tab is shown; the
Deadlock Details tab is shown if the Deadlocks tab is shown.
The Summary Tab
The Summary tab shows summary information about a data race
selected from the Races tab. This information includes the object
file name, source file name, and PC (program counter) address.
The Race Details Tab
The Race Details tab is selected whenever the Races tab is raised,
and a selection made from the Races tab. It shows detailed infor‐
mation about a data race or trace selected from the Races tab.
The Race Details tab is divided into two panes. The upper pane
shows information about the first access of a selected data race
or trace (Access 1). The lower pane shows information about the
second access of a selected data race or trace (Access 2).
When a data race or a trace is selected from the Races tab, the
Race Details tab shows the following:
· The data race or trace id
· The virtual address (Vaddr) associated with the data race. If
the data race occurs on multiple virtual addresses, then "(Mul‐
tiple Addresses)" is shown instead of a single address.
In addition, for each of the two accesses, the Race Details tab
shows the following:
· Whether the data race access is read or write
· If a data race from the Races tab is selected, then the Race
Details tab shows the leaf PC of the thread when the data race
access occurred. If, on the other hand, a trace from the Races
tab is selected, then the Race Details tab shows the callstack
of the thread when the data race access occurred. By default,
the frame at the top of the callstack is selected.
The Deadlock Details Tab
The Deadlock Details tab is selected whenever the Deadlocks tab is
raised, and a selection made from the Deadlocks Tab. It shows
detailed information about a thread context selected from the
Deadlocks tab.
For each thread context selected, the deadlock id, deadlock type,
and thread id are shown. In addition, for each of the two lock
operations involved, the type of lock operation (lock being held
or lock being requested) and the callstacks of the thread are
shown. By default, the frame at the top of each callstack is
selected.
DATA RACE DETECTION
A data race occurs when two or more threads in a single process access
the same memory location concurrently, at least one of the accesses is
for writing, and the threads are not using any exclusive locks to con‐
trol their accesses to that memory. In such situations, the order of
accesses is non-deterministic, and the computation may give different
results depending on that order. Some data races may be benign (for
example, when the memory access is used for a busy-wait), but many data
races are bugs in the program.
Data-race-detection experiments record data races that are detected
during the execution of a multithreaded process. Data race detection
works on multithreaded applications written using POSIX thread APIs,
Solaris thread APIs, OpenMP, or a mix of the above.
There are three steps involved in detecting data races:
Step 1: Instrument the code
To enable data race detection in an application, the code must
first be instrumented to monitor memory accesses at runtime. The
instrumentation can be done at the application source-level or
binary-level.
If doing source-level instrumentation, the source code of the
application should be compiled with the special compiler option:
-xinstrument=datarace
With this compiler option, the code generated by the compiler will
be instrumented for data race detection.
If doing binary-level instrumentation, the application binary
should be instrumented using the Discover tool which is invoked by
the discover(1) command. If the binary is named a.out, then an
instrumented binary a.outi can be generated 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 pro‐
gram or opened dynamically by dlopen(). You can use the discover
command line option -N to ignore certain libraries, or use the
discover command line option -T to ignore all libraries.
To use the Discover tool, the input binary must be compiled with
optimization flag -O[n] (n>=0) using Solaris Studio 12 Update 1
compilers or later versions, on a machine with Oracle Solaris 10
update 5 or higher, or Oracle Solaris 11. On older Solaris ver‐
sions, try the -xbinopt=prepare compiler option (SPARC only).
For both source-level and binary-level instrumentation, it is rec‐
ommended that the -g compiler option be used when building appli‐
cation binaries. This will allow tha to display source code and
line number information when reporting data races.
Step 2: Create a data-race-detection experiment
Use the collect command with the -r race flag to run the applica‐
tion and create a data-race-detection experiment during the execu‐
tion of the process.
Data-race-detection data collected consists of pairs of data-
accesses that constitute a race. Data-race-detection data is con‐
verted into the "Race Accesses" metric.
See collect(1) man page for more information.
Step 3: Examine the data-race-detection experiment
A data-race-detection experiment can be examined with either the
tha or analyzer command (GUI), or with the er_print utility (com‐
mand-line).
Both the tha and the analyzer commands present a GUI interface;
the former presents a simplified set of default tabs, but is oth‐
erwise identical to the analyzer. The er_print utility, on the
other hand, presents a command-line interface.
Note: The Thread Analyzer may report false positive data races if it
does not recognize user-defined synchronizations in the application.
The Thread Analyzer runtime library, libtha.so, provides an API that
can be used to notify the Thread Analyzer about user-defined synchro‐
nizations and reduce the number of false positives reported. See
libtha(3) man page for more information.
DEADLOCK DETECTION
Deadlock describes a condition where two or more threads are blocked
(hung) forever, waiting for each other. There are many causes of dead‐
locks; these include erroneous program logic, inappropriate use of syn‐
chronizations and barriers, and so on.
The Thread Analyzer detects deadlocks that are caused by inappropriate
use of mutual exclusion locks. This kind of deadlock is commonly
encountered in multi-threaded applications. Suppose we have a process
with two or more threads. A deadlock caused by inappropriate use of
mutual exclusion locks occurs when the following three conditions hold:
(1) Threads already holding locks request new locks,
(2) The requests are made concurrently, and
(3) Two or more threads form a circular chain where each thread waits
for a lock that the next thread in the chain holds.
Here is an example of a deadlock condition:
Thread 1: holds lock A, requests lock B
Thread 2: holds lock B, requests lock A
A deadlock in a particular run of the program can be a potential dead‐
lock or an actual deadlock. A potential deadlock is a deadlock that did
not actually occur in the run of the program, but can occur in other
runs of the program, depending on the scheduling of threads and the
timings of requests for locks by the threads. An actual deadlock is a
deadlock that actually occurred in the run of the program. An actual
deadlock causes the threads involved to hang, but may or may not cause
the whole process to hang.
Deadlock-detection experiments record both potential and actual dead‐
locks that are detected during the execution of a multi-threaded
process. Deadlock detection works on multi-threaded applications writ‐
ten using POSIX thread APIs, Solaris thread APIs, OpenMP, or a mix of
the above.
There are two steps involved in detecting deadlocks:
Step 1: Create a deadlock-detection experiment
Use the collect command with the -r deadlock flag to run the
application and create a deadlock-detection experiment during the
execution of the process.
Deadlock-detection data collected consists of lock holds and lock
requests that form a circular chain. Deadlock-detection data is
converted into the "Deadlocks" metric.
See collect(1) man page for more information.
Step 2: Examine the deadlock-detection experiment
A deadlock-detection experiment can be examined with either the
tha or analyzer command (GUI), or with the er_print utility (com‐
mand-line).
Both the tha and the analyzer commands present a GUI interface;
the former presents a simplified set of default tabs, but is oth‐
erwise identical to the analyzer. The er_print utility, on the
other hand, presents a command-line interface.
It is recommended that the -g compiler option be used when building
application binaries. This will allow tha to display source code and
line number information when reporting deadlocks.
SELECTING DATA PRESENTATION OPTIONS
You can control the presentation of data from the Set Data Presentation
dialog box. To open this dialog box, click on the Set Data Presentation
button in the tool bar, or choose Set Data Presentation from the View
menu.
The Set Data Presentation dialog box has a tabbed pane with seven tabs.
Refer to the analyzer(1) man page for more information.
DEFAULTS
The Thread Analyzer processes directives from a .er.rc file in the cur‐
rent directory, if present; from a .er.rc file in the user's home
directory, if present; and from a system er.rc file installed with the
product.
These .er.rc files can contain default settings for which tabs are vis‐
ible (rtabs), when the Thread Analyzer is brought up. The tabs are
named by the er_print command for the corresponding report, except for
the Experiments Tab, named headers, the Timeline Tab, named timeline,
the Dual Source Tab, named dsrc, and the Source/Disassembly tab, named
srcdis.
The .er.rc files can also contain default settings for metrics, sort‐
ing, and for specifying compiler commentary options and highlighting
thresholds for source and disassembly output. The files also specify a
path for C++ name demangling for other compilers, as well as default
settings for the Timeline tab, and for name formatting, and setting
View Mode (viewmode).
The .er.rc files can also contain a setting, en_desc {on|off} to con‐
trol whether or not descendant experiments are selected and read when
the founder experiment is read.
The .er.rc files can also contain directives to control the search path
for source and object files. In the Thread Analyzer, an .er.rc file
can be saved by clicking on the Save button in the Set Data Presenta‐
tion dialog box, which you can open from the View menu. Saving an
.er.rc file from the Set Data Presentation dialog box not only affects
subsequent invocations of the Thread Analyzer, but also the er_print
utility and er_src utility. See the description of these directives
and files, and their processing, in the er_print(1) man page.
The Thread Analyzer puts a message into its Errors/Warning logs areas
naming the user .er.rc files it processed, including any processing
message generated when any tab is loaded.
SEE ALSOanalyzer(1), collect(1), discover(1), er_archive(1), er_cp(1),
er_export(1), er_mv(1), er_print(1), er_rm(1), er_src(1), libtha(3),
tha(1), the Thread Analyzer User's Guide, and the Performance Analyzer
manual.
October 2011 tha(1)