Home | History | Annotate | Download | only in hotspot_jni
      1 #!/usr/sbin/dtrace -Zs
      2 
      3 /*
      4  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  *   - Redistributions of source code must retain the above copyright
     11  *     notice, this list of conditions and the following disclaimer.
     12  *
     13  *   - Redistributions in binary form must reproduce the above copyright
     14  *     notice, this list of conditions and the following disclaimer in the
     15  *     documentation and/or other materials provided with the distribution.
     16  *
     17  *   - Neither the name of Oracle nor the names of its
     18  *     contributors may be used to endorse or promote products derived
     19  *     from this software without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     22  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     23  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     25  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     28  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     29  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     30  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 /*
     35 */
     36 
     37 /*
     38  * Usage:
     39  *    1. CriticalSection.d -c "java ..."
     40  *    2. CriticalSection.d -p JAVA_PID
     41  *
     42  * The script inspect a JNI application for Critical Section violations.
     43  *
     44  * Critical section is the space between calls to JNI methods:
     45  *   - GetPrimitiveArrayCritical and ReleasePrimitiveArrayCritical; or
     46  *   - GetStringCritical and ReleaseStringCritical.
     47  *
     48  * Inside a critical section, native code must not call other JNI functions,
     49  * or any system call that may cause the current thread to block and wait
     50  * for another Java thread. (For example, the current thread must not call
     51  * read on a stream being written by another Java thread.)
     52  *
     53  */
     54 
     55 #pragma D option quiet
     56 #pragma D option destructive
     57 #pragma D option defaultargs
     58 #pragma D option bufsize=16m
     59 #pragma D option aggrate=100ms
     60 
     61 
     62 self int in_critical_section;
     63 self string critical_section_name;
     64 
     65 int CRITICAL_SECTION_VIOLATION_CNT;
     66 
     67 :::BEGIN
     68 {
     69     SAMPLE_NAME = "critical section violation checks";
     70 
     71     printf("BEGIN %s\n", SAMPLE_NAME);
     72 }
     73 
     74 /*
     75  *   Multiple pairs of GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical,
     76  *   GetStringCritical/ReleaseStringCritical may be nested
     77  */
     78 hotspot_jni$target:::*_entry
     79 /self->in_critical_section > 0 &&
     80   probename != "GetPrimitiveArrayCritical_entry" &&
     81   probename != "GetStringCritical_entry" &&
     82   probename != "ReleasePrimitiveArrayCritical_entry" &&
     83   probename != "ReleaseStringCritical_entry" &&
     84   probename != "GetPrimitiveArrayCritical_return" &&
     85   probename != "GetStringCritical_return" &&
     86   probename != "ReleasePrimitiveArrayCritical_return" &&
     87   probename != "ReleaseStringCritical_return"/
     88 {
     89     printf("\nJNI call %s made from JNI critical region '%s'\n",
     90         probename, self->critical_section_name);
     91 
     92     printf("Jstack:\n");
     93     jstack(50, 500);
     94 
     95     CRITICAL_SECTION_VIOLATION_CNT ++;
     96 }
     97 
     98 syscall:::entry
     99 /pid == $target && self->in_critical_section > 0/
    100 {
    101     printf("\nSystem call %s made in JNI critical region '%s'\n",
    102         probefunc, self->critical_section_name);
    103 
    104     printf("Jstack:\n");
    105     jstack(50, 500);
    106 
    107     CRITICAL_SECTION_VIOLATION_CNT ++;
    108 }
    109 
    110 hotspot_jni$target:::ReleasePrimitiveArrayCritical_entry,
    111 hotspot_jni$target:::ReleaseStringCritical_entry
    112 /self->in_critical_section > 0/
    113 {
    114     self->in_critical_section --;
    115 }
    116 
    117 hotspot_jni$target:::GetPrimitiveArrayCritical_return
    118 {
    119     self->in_critical_section ++;
    120     self->critical_section_name = "GetPrimitiveArrayCritical";
    121 }
    122 
    123 hotspot_jni$target:::GetStringCritical_return
    124 {
    125     self->in_critical_section ++;
    126     self->critical_section_name = "GetStringCritical";
    127 }
    128 
    129 
    130 :::END
    131 {
    132     printf("%d critical section violations have been discovered\n",
    133         CRITICAL_SECTION_VIOLATION_CNT);
    134 
    135     printf("\nEND of %s\n", SAMPLE_NAME);
    136 }
    137