Man Page tha.1




NAME

     tha - GUI for analyzing a Thread Analyzer experiment


SYNOPSIS

     tha args


DESCRIPTION

     The tha(1)	command	invokes	a GUI for analyzing  the  various
     Thread Analyzer experiments collected by the Collector using
     the collect(1)  command.	The  GUI  is  a	 version  of  the
     Analyzer  customized  for	examining Thread Analyzer experi-
     ments.

     The Collector gathers Thread Analyzer information to  create
     a	thread-analyzer	experiment during the execution	of a pro-
     cess. The tha  command  reads  in	such  an  experiment  and
     displays  any  errors detected.  The current Thread Analyzer
     supports data-race	detection and  deadlock	 detection.   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)  software	for  running  the  analyzer.  The
	       default path is taken first by examining	 environ-
	       ment variables for a path to the	JVM, in	the order
	       JDK_HOME, and then JAVA_PATH. If	neither	 environ-
	       ment  variable  is  set,	the default path is where
	       the Java[TM] 2 Platform,	Standard Edition technol-
	       ogy  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  argu-
	       ments 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 contains 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 con-
     trolled by	a rtabs	directive in a .er.rc file.  The  Experi-
     ments  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 neither is available,  only	 the  Experiments
     tab will be visible.

     The Races Tab
	  The Races tab	is shown if data-race data 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:

	  (1) A	unique id that identifies the data-race

	  (2) One or more virtual  addresses  (Vaddr)  associated
	  with	the data-race.	If the data-race occurs	on multi-
	  ple virtual addresses, then "(Multiple  Addresses)"  is
	  shown	instead	of a single address.

	  (3) The two accesses by two different	threads	that con-
	  stitute  the	data-race.   For each access, the type of
	  the access (Read or Write) is	shown,	as  well  as  the
	  function,  offset,  and  line	number in the source code
	  where	the access occurred.

	  (4) 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:

	  (1)  A unique	id that	identifies the deadlock

	  (2) The type of the deadlock (potential or actual)

	  (3)  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	 context   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 loca-
	  tions	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,
	  percentages may not sum to exactly 100%.

	  The metrics that are shown can be changed using the Set
	  Data	Presentation  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 messages from	the tha	session.

	  For more information about the Experiments  tab,  refer
	  to the analyzer(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 information 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:

	  (1) The data-race or trace id

	  (2) The virtual address  (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.

	  In addition, for each	of the	two  accesses,	the  Race
	  Details tab shows the	following:

	  o Whether the	data-race access is read or write

	  o 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 pro-
     cess  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 control 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 multi-threaded process.
     Data-race detection  works	 on  multi-threaded  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 stati-
	  cally	linked in the program 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 com-
	  piled	with optimization flag -O[n] (n>=0) using Solaris
	  Studio 12 Update 1 compilers or later	 versions,  on	a
	  machine  with	Solaris	10 update 5 or higher (or OpenSo-
	  laris	version	snv_70 or higher). On older Solaris  ver-
	  sions,  try the -xbinopt=prepare compiler option (SPARC
	  only).

	  For both source-level	and binary-level instrumentation,
	  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 data-races.

     Step 2: Create a data-race-detection experiment

	  Use the collect command with the -r race  flag  to  run
	  the application and create a data-race-detection exper-
	  iment	during the execution of	the process.

	  Data-race-detection data collected consists of pairs of
	  data-accesses	  that	constitute  a  race.   Data-race-
	  detection data is converted 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 (command-line).

	  Both the tha and the analyzer	commands  present  a  GUI
	  interface;  the  former  presents  a	simplified set of
	  default  tabs,  but  is  otherwise  identical	 to   the
	  analyzer.   The  er_print  utility,  on the other hand,
	  presents a command-line interface.


DEADLOCK DETECTION

     Deadlock describes	a condition where two or more threads are
     blocked  (hung)  forever,	waiting	for each other.	There are
     many causes of deadlocks; these  include  erroneous  program
     logic,  inappropriate  use	of synchronizations 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	 applica-
     tions.   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	deadlock  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 pro-
     gram, 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 deadlocks that are detected	during the execution of	a
     multi-threaded process. Deadlock detection	works  on  multi-
     threaded  applications  written  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 (command-line).

	  Both the tha and the analyzer	commands  present  a  GUI
	  interface;  the  former  presents  a	simplified set of
	  default  tabs,  but  is  otherwise  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 report-
     ing 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 current 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	visible	 (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,  sorting,	 and  for  specifying compiler commentary
     options and highlighting thresholds for source and	disassem-
     bly  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  control  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 Presentation	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 subse-
     quent 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 ALSO

     analyzer(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),	tha(1),	the Thread Analyzer User's Guide, and the
     Performance Analyzer manual.