<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#CCCCCC" text="#000000">
    <div class="moz-cite-prefix">On 7/18/12 11:41 AM,
      <a class="moz-txt-link-abbreviated" href="mailto:serguei.spitsyn@oracle.com">serguei.spitsyn@oracle.com</a> wrote:<br>
    </div>
    <blockquote cite="mid:5007035E.8070602@oracle.com" type="cite">
      <meta content="text/html; charset=ISO-8859-1"
        http-equiv="Content-Type">
      <div class="moz-cite-prefix">On 7/18/12 10:23 AM, Mark Wielaard
        wrote:<br>
      </div>
      <blockquote
        cite="mid:20120718172306.GA4153@toonder.wildebeest.org"
        type="cite">
        <pre wrap="">On Wed, Jul 18, 2012 at 10:10:43AM -0700, <a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:serguei.spitsyn@oracle.com">serguei.spitsyn@oracle.com</a> wrote:
</pre>
        <blockquote type="cite">
          <pre wrap="">This work includes investigation to find proper linux machine,
installation of the systemTap, building and testing, and so,
needs some engineering resources.
</pre>
        </blockquote>
        <pre wrap="">I can do that, the patch has already been included in various
distros so it shouldn't be a problem. Just let me know what you
need.

</pre>
        <blockquote type="cite">
          <pre wrap="">Also, it needs a new unit test and submitting a CCC request.
You only can help by providing a test for the patch.
</pre>
        </blockquote>
        <pre wrap="">Sure, I was looking for existing dtrace tests to see if I can
match them. Do you have a good example I can follow?

Thanks,

Mark
</pre>
      </blockquote>
      <br>
      Normally a dtrace test needs 4 parts:<br>
      &nbsp; java test program, d-script, shell script and README<br>
      <br>
      All automated dtrace tests usually depend on the SQE testbase
      environment: <br>
      &nbsp;&nbsp; .cfg file, testbase libraries and testbase build system<br>
      <br>
      So that, I do not have a simple standalone test for the HotSpot
      probes.<br>
      But I can provide an example (just make a correction on this kind
      of dependency).<br>
      <br>
      The test ThreadLifecycle001 includes ThreadLifecycle.d, <br>
    </blockquote>
    <br>
    Need to complete the sentence above:<br>
    &nbsp; The test ThreadLifecycle001 includes ThreadLifecycle.d,
    ThreadLifecycle001.cfg,<br>
    &nbsp; ThreadLifecycle001.java, ThreadLifecycle001.pl and
    ThreadLifecycle001.README<br>
    <br>
    <br>
    Thanks,<br>
    Serguei<br>
    <br>
    <blockquote cite="mid:5007035E.8070602@oracle.com" type="cite"> <br>
      <br>
      Please, see below and let me know if you have any questions.<br>
      I can send you more examples if needed.<br>
      <br>
      Thanks,<br>
      Serguei<br>
      <br>
      <br>
      % cat ThreadLifecycle.d<br>
      <br>
      #!/usr/sbin/dtrace -Zs<br>
      <br>
      #pragma D option quiet<br>
      #pragma D option destructive<br>
      <br>
      /* %W% %G%<br>
      &nbsp;* Copyright %G% Sun Microsystems, Inc.<br>
      &nbsp;*/<br>
      <br>
      /*<br>
      &nbsp;* The script trace hotspot:::thread-start and
      hotspot:::thread-stop events.<br>
      &nbsp;*/<br>
      <br>
      self char *str_ptr;<br>
      self string thread_name;<br>
      <br>
      :::BEGIN {<br>
      &nbsp;&nbsp;&nbsp; TEST_NAME = "Thread lifecycle";<br>
      &nbsp;&nbsp;&nbsp; TEST_PASS = 1;<br>
      <br>
      &nbsp;&nbsp;&nbsp; EXIT_CODE_PASS = 0;<br>
      &nbsp;&nbsp;&nbsp; EXIT_CODE_FAIL = 1;<br>
      <br>
      &nbsp;&nbsp;&nbsp; printf("BEGIN %s probes testing\n\n", TEST_NAME);<br>
      }<br>
      <br>
      /*<br>
      &nbsp;* hotspot:::thread-start, hotspot:::thread-stop probe arguments:<br>
      &nbsp;*&nbsp; arg0: char*,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thread name passed as UTF8 string<br>
      &nbsp;*&nbsp; arg1: uintptr_t,&nbsp;&nbsp;&nbsp; thread name length<br>
      &nbsp;*&nbsp; arg2: uintptr_t,&nbsp;&nbsp;&nbsp; Java thread id<br>
      &nbsp;*&nbsp; arg3: uintptr_t,&nbsp;&nbsp;&nbsp; native/OS thread id<br>
      &nbsp;*&nbsp; arg4: uintptr_t,&nbsp;&nbsp;&nbsp; is a daemon or not<br>
      &nbsp;*/<br>
      <br>
      /* Check is_daemon is correct */<br>
      hotspot$target:::thread-start,<br>
      hotspot$target:::thread-stop<br>
      / arg4 &gt; 1 /<br>
      {<br>
      &nbsp;&nbsp;&nbsp; TEST_PASS = 0;<br>
      <br>
      &nbsp;&nbsp;&nbsp; printf("FAIL: wrong is_daemon=%u is passed in %s\n",<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arg4, probename);<br>
      }<br>
      <br>
      hotspot$target:::thread-start<br>
      {<br>
      &nbsp;&nbsp;&nbsp; THREAD_START_CNT ++;<br>
      }<br>
      <br>
      hotspot$target:::thread-stop<br>
      {<br>
      &nbsp;&nbsp;&nbsp; THREAD_STOP_CNT ++;<br>
      }<br>
      <br>
      hotspot$target:::thread-start,<br>
      hotspot$target:::thread-stop<br>
      {<br>
      &nbsp;&nbsp;&nbsp; /* Yes, we copy for one byte more from user space. This is
      temporal solution till support for<br>
      &nbsp;&nbsp;&nbsp;&nbsp; * not-null terminated strings will be donein DTRACE<br>
      &nbsp;&nbsp;&nbsp;&nbsp; */<br>
      &nbsp;&nbsp;&nbsp; self-&gt;str_ptr = (char*) copyin(arg0, arg1+1);<br>
      &nbsp;&nbsp;&nbsp; self-&gt;str_ptr[arg1] = '\0'; <br>
      &nbsp;&nbsp;&nbsp; self-&gt;thread_name = (string) self-&gt;str_ptr;<br>
      <br>
      &nbsp;&nbsp;&nbsp; printf("\nPROBE ARGS: %s:\n", probename);<br>
      &nbsp;&nbsp;&nbsp; printf("PROBE ARGS:&nbsp;&nbsp; arg0=%p (thread name pointer)\n", arg0);<br>
      &nbsp;&nbsp;&nbsp; printf("PROBE ARGS:&nbsp;&nbsp; arg1=%u (thread name length)\n", arg1);<br>
      &nbsp;&nbsp;&nbsp; printf("PROBE ARGS:&nbsp;&nbsp; arg2=%u (Java thread id)\n", arg2);<br>
      &nbsp;&nbsp;&nbsp; printf("PROBE ARGS:&nbsp;&nbsp; arg3=%u (native/OS id)\n", arg3);<br>
      &nbsp;&nbsp;&nbsp; printf("PROBE ARGS:&nbsp;&nbsp; arg4=%u (is daemon)\n", arg4);<br>
      <br>
      &nbsp;&nbsp;&nbsp; /* this output will be used by Perl script */<br>
      &nbsp;&nbsp;&nbsp; printf("%s: id=%u, is_daemon=%u, name=%s\n",<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; probename, arg2, arg4, self-&gt;thread_name);<br>
      }<br>
      <br>
      /* check exit status of traced java process */<br>
      syscall::rexit:entry<br>
      /pid == $target &amp;&amp; arg0 != 0 &amp;&amp; arg0 != 95 /<br>
      {<br>
      &nbsp;&nbsp;&nbsp; printf("\n");<br>
      &nbsp;&nbsp;&nbsp; printf("ERROR: java process failed with status=%d\n", arg0);<br>
      &nbsp;&nbsp;&nbsp; TEST_PASS = 0;<br>
      }<br>
      <br>
      syscall::rexit:entry<br>
      /pid == $target &amp;&amp; !THREAD_START_CNT/<br>
      {<br>
      &nbsp;&nbsp;&nbsp; printf("ERROR: no 'thread-start' probes were fired\n");<br>
      &nbsp;&nbsp;&nbsp; TEST_PASS = 0;<br>
      }<br>
      <br>
      syscall::rexit:entry<br>
      /pid == $target &amp;&amp; !THREAD_STOP_CNT/<br>
      {<br>
      &nbsp;&nbsp;&nbsp; printf("ERROR: no 'thread-stop' probes were fired\n");<br>
      &nbsp;&nbsp;&nbsp; TEST_PASS = 0;<br>
      }<br>
      <br>
      syscall::rexit:entry<br>
      /pid == $target &amp;&amp; !TEST_PASS/<br>
      {<br>
      &nbsp;&nbsp;&nbsp; printf("FAIL\n");<br>
      &nbsp;&nbsp;&nbsp; exit(EXIT_CODE_FAIL);<br>
      }<br>
      <br>
      syscall::rexit:entry<br>
      /pid == $target &amp;&amp; TEST_PASS/<br>
      {<br>
      &nbsp;&nbsp;&nbsp; printf("PASS\n");<br>
      &nbsp;&nbsp;&nbsp; exit(EXIT_CODE_PASS);<br>
      }<br>
      <br>
      :::END {<br>
      &nbsp;&nbsp;&nbsp; printf("\nEND %s tracing\n", TEST_NAME);<br>
      }<br>
      <br>
      <br>
      sspitsyn@hsdev-10 more *.* | cat<br>
      ::::::::::::::<br>
      ThreadLifecycle001.cfg<br>
      ::::::::::::::<br>
      # %W% %G%<br>
      # Copyright %G% Sun Microsystems, Inc.<br>
      <br>
      <br>
DSCRIPT=${TESTBASE}/src/dtrace/share/dscripts/hotspot/ThreadLifecycle.d<br>
      <br>
EXECUTE_CLASS=dtrace.hotspot.ThreadLifecycle.ThreadLifecycle001.ThreadLifecycle001<br>
      <br>
      export DSCRIPT<br>
      export JAVA<br>
      export JAVA_OPTS<br>
      export TESTDIR<br>
      export TEST_ARGS<br>
      export EXECUTE_CLASS<br>
      export TESTBASE<br>
      export TESTARGS<br>
      <br>
DTRACE_RESULTS_ANALYZER_SCRIPT=${TESTBASE}/src/dtrace/hotspot/ThreadLifecycle/ThreadLifecycle001/ThreadLifecycle001.pl<br>
      export DTRACE_RESULTS_ANALYZER_SCRIPT<br>
      <br>
      TONGA_EXECUTE=$PERL ${TESTBASE}/src/dtrace/share/run_dtrace.pl <br>
      <br>
      <br>
      ::::::::::::::<br>
      ThreadLifecycle001.java<br>
      ::::::::::::::<br>
      /* %W% %G%<br>
      &nbsp;* Copyright %G% Sun Microsystems, Inc.<br>
      &nbsp;*/<br>
      <br>
      package dtrace.hotspot.ThreadLifecycle.ThreadLifecycle001;<br>
      <br>
      import java.lang.*;<br>
      <br>
      class NewThread extends Thread<br>
      {<br>
      &nbsp;&nbsp;&nbsp; volatile private boolean stop = false;<br>
      &nbsp;&nbsp;&nbsp; private boolean started = false;<br>
      <br>
      &nbsp;&nbsp;&nbsp; public NewThread(ThreadGroup group, String name)<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(group, name);<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; public void run()<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(this) { started = true; }<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (!stop)<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=0; i&lt;100; i++);<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      <br>
      &nbsp;&nbsp;&nbsp; synchronized public boolean isStarted()<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return started;<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; public void terminate()<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stop = true;<br>
      &nbsp;&nbsp;&nbsp; }<br>
      }<br>
      <br>
      <br>
      public class ThreadLifecycle001<br>
      {<br>
      &nbsp;&nbsp;&nbsp; public static void main(String[] args)<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("ThreadLifecycle001 test");<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // create and start NewThread<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ThreadGroup newGroup = new ThreadGroup("newGroup");<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewThread newThread = new NewThread(newGroup,
      "NewThread");<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newThread.start();<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ThreadGroup parentGroup =
      Thread.currentThread().getThreadGroup();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (parentGroup == null)<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (parentGroup.getParent() != null)<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parentGroup = parentGroup.getParent();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // wait if newThread is not yet started<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (!newThread.isStarted())<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; 100; i++);<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listThreads(parentGroup);<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newThread.terminate();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newThread.join();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(InterruptedException ex) {}<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; static void listThreads(ThreadGroup currentGroup)<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int threadCount = currentGroup.activeCount();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread listOfThreads[] = new Thread[threadCount];<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentGroup.enumerate(listOfThreads, true);<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; threadCount; i++)<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Thread: id=" + listOfThreads[i].getId() +<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ", is_daemon=" + (listOfThreads[i].isDaemon() ?
      "1" : "0") +<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ", name=" + listOfThreads[i].getName() +<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ", groupName=" +
      listOfThreads[i].getThreadGroup().getName() );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; }<br>
      }<br>
      <br>
      <br>
      ::::::::::::::<br>
      ThreadLifecycle001.pl<br>
      ::::::::::::::<br>
      # %W% %G%<br>
      # Copyright %G% Sun Microsystems, Inc.<br>
      #<br>
      # Implement analyze_dtrace_results_proc function for
      ThreadLifecycle001 test.<br>
      #<br>
      <br>
      sub analyze_dtrace_results_proc($$$)<br>
      {<br>
      &nbsp;&nbsp;&nbsp; my ($dtrace_log_filename, $java_log_filename, $args) = @_;<br>
      <br>
      &nbsp;&nbsp;&nbsp; my $test_fail = 0;<br>
      &nbsp;&nbsp;&nbsp; my %java_threads = ();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # threads started according to
      Java log file<br>
      &nbsp;&nbsp;&nbsp; my %dtrace_start_threads = ();&nbsp; # threads started according to
      hotspot:::thread-start probes<br>
      &nbsp;&nbsp;&nbsp; my %dtrace_stop_threads = ();&nbsp; # threads started according to
      hotspot:::thread-start probes<br>
      &nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp; if ( &amp;read_java_log($java_log_filename, \%java_threads) ||<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;read_dtrace_log($dtrace_log_filename,
      \%dtrace_start_threads, \%dtrace_stop_threads) )<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; # Check that all probes have been fired<br>
      &nbsp;&nbsp;&nbsp; foreach (keys %java_threads)<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unless (exists $dtrace_start_threads{$_}) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print STDOUT "ERROR: no 'thread-start' probe was fired
      for thread: $_\n";<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $test_fail = 1;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unless (exists $dtrace_stop_threads{$_}) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print STDOUT "ERROR: no 'thread-stop' probe was fired
      for thread: $_\n";<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $test_fail = 1;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; # check that 'thread-start' probes have been fired exactly 1
      time for each thread<br>
      &nbsp;&nbsp;&nbsp; foreach (keys %dtrace_start_threads) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($dtrace_start_threads{$_} &gt; 1) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print STDOUT "ERROR: 'thread-start' probe for '$_'
      fired " .<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $dtrace_start_threads{$_} . " (&gt;1) times\n";<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $test_fail = 1;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; # check that 'thread-stop' probes have been fired exactly 1
      time for each thread<br>
      &nbsp;&nbsp;&nbsp; foreach (keys %dtrace_stop_threads) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($dtrace_stop_threads{$_} &gt; 1) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print STDOUT "ERROR: 'thread-stop' probe for '$_'
      fired " .<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $dtrace_stop_threads{$_} . " (&gt;1) times\n";<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $test_fail = 1;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; return $test_fail;<br>
      }<br>
      <br>
      sub read_java_log($$)<br>
      {<br>
      &nbsp;&nbsp;&nbsp; my ($java_log_filename, $java_threads) = @_;<br>
      <br>
      &nbsp;&nbsp;&nbsp; unless (open(IN, "&lt;$java_log_filename")) <br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print STDOUT "Failed to read $java_log_filename: $!\n";<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; while(my $str = &lt;IN&gt;)<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $str =~ s/\r*\n//;<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($str =~ s/^Thread: //) <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # thread group name is not passed in dtrace probes, so
      delete it<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $str =~ s/, groupName=.*$//;<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $java_threads-&gt;{$str} ++;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp; close(IN);<br>
      &nbsp;&nbsp;&nbsp; return 0;<br>
      }<br>
      <br>
      sub read_dtrace_log($$$)<br>
      {<br>
      &nbsp;&nbsp;&nbsp; my ($dtrace_log_filename, $dtrace_start_threads,
      $dtrace_stop_threads) = @_;<br>
      <br>
      &nbsp;&nbsp;&nbsp; unless (open(IN, "&lt;$dtrace_log_filename")) <br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print STDOUT "Failed to read $java_log_filename: $!\n";<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp; my $probe_name;<br>
      &nbsp;&nbsp;&nbsp; while(my $str = &lt;IN&gt;)<br>
      &nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $str =~ s/\r*\n//;<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($str =~ s/^thread-start: //)<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $dtrace_start_threads-&gt;{$str} ++;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elsif ($str =~ s/^thread-stop: //)<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $dtrace_stop_threads-&gt;{$str} ++;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp; close(IN);<br>
      &nbsp;&nbsp;&nbsp; return 0;<br>
      }<br>
      <br>
      1;<br>
      <br>
      ::::::::::::::<br>
      ThreadLifecycle001.README<br>
      ::::::::::::::<br>
      %W% %G%<br>
      Copyright %G% Sun Microsystems, Inc.<br>
      <br>
      DESCRIPTION<br>
      <br>
      &nbsp;&nbsp;&nbsp; The test exercise hotspot:::thread-start and
      hotspot:::thread-stop Dtrace probes functionality.<br>
      <br>
      &nbsp;&nbsp;&nbsp; The test do:<br>
      &nbsp;&nbsp;&nbsp; - run ThreadLifecycle001 java programm which dumps information
      abould<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; all running threads in VM.<br>
      &nbsp;&nbsp;&nbsp; - check if:<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - for each Java thread thread-start and thread-stop probes
      are fired the same time<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - input probe's arguments are passed correctly<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (attempt to print them doesn't cause the error)<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - no any Dtrace errors are thrown<br>
      <br>
      COMMENTS<br>
      <br>
      AUTHOR<br>
      &nbsp;. . .<br>
      <br>
      <br>
      <br>
      <br>
    </blockquote>
    <br>
    <br>
  </body>
</html>