blob: 221b45c4137206b671211c545f560cffd3dd5b19 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001#!/usr/sbin/dtrace -Zs
2
3/*
4 * Copyright 2006 Sun Microsystems, Inc. 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 Sun Microsystems 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_slow.d -c "java ..."
40 * 2. CriticalSection_slow.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
62self int in_critical_section;
63self string critical_section_name;
64
65self char *str_ptr;
66self string class_name;
67self string method_name;
68self string signature;
69
70self int indent;
71self int JAVA_STACK_DEEP;
72
73int CRITICAL_SECTION_VIOLATION_CNT;
74
75:::BEGIN
76{
77 SAMPLE_NAME = "critical section violation checks";
78
79 printf("BEGIN %s\n", SAMPLE_NAME);
80}
81
82hotspot$target:::*
83/!self->JAVA_STACK_DEEP/
84{
85 self->JAVA_STACK_DEEP = 0;
86}
87
88
89hotspot$target:::method-return
90/self->JAVA_STACK_DEEP > 0/
91{
92 self->JAVA_STACK_DEEP --;
93}
94
95hotspot$target:::method-entry
96{
97 self->JAVA_STACK_DEEP ++;
98
99 self->str_ptr = (char*) copyin(arg1, arg2+1);
100 self->str_ptr[arg2] = '\0';
101 self->method_name = strjoin( (string) self->str_ptr, ":");
102
103 self->str_ptr = (char*) copyin(arg3, arg4+1);
104 self->str_ptr[arg4] = '\0';
105 self->method_name = strjoin(self->method_name, (string) self->str_ptr);
106 self->method_name = strjoin(self->method_name, ":");
107
108 self->str_ptr = (char*) copyin(arg5, arg6+1);
109 self->str_ptr[arg6] = '\0';
110 self->method_name = strjoin(self->method_name, (string) self->str_ptr);
111
112 self->JAVA_STACK[self->JAVA_STACK_DEEP] = self->method_name;
113
114/* printf("%-10u%*s%s\n",
115 * curcpu->cpu_id, self->indent, "", self->method_name);
116 */
117}
118
119
120/*
121 * Multiple pairs of GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical,
122 * GetStringCritical/ReleaseStringCritical may be nested
123 */
124hotspot_jni$target:::*_entry
125/self->in_critical_section > 0 &&
126 probename != "GetPrimitiveArrayCritical_entry" &&
127 probename != "GetStringCritical_entry" &&
128 probename != "ReleasePrimitiveArrayCritical_entry" &&
129 probename != "ReleaseStringCritical_entry" &&
130 probename != "GetPrimitiveArrayCritical_return" &&
131 probename != "GetStringCritical_return" &&
132 probename != "ReleasePrimitiveArrayCritical_return" &&
133 probename != "ReleaseStringCritical_return"/
134{
135 printf("JNI call %s made from JNI critical region '%s' from %s\n",
136 probename, self->critical_section_name,
137 self->JAVA_STACK[self->JAVA_STACK_DEEP]);
138
139 CRITICAL_SECTION_VIOLATION_CNT ++;
140}
141
142syscall:::entry
143/pid == $target && self->in_critical_section > 0/
144{
145 printf("system call %s made in JNI critical region '%s' from %s\n",
146 probefunc, self->critical_section_name,
147 self->JAVA_STACK[self->JAVA_STACK_DEEP]);
148
149 CRITICAL_SECTION_VIOLATION_CNT ++;
150}
151
152hotspot_jni$target:::ReleasePrimitiveArrayCritical_entry,
153hotspot_jni$target:::ReleaseStringCritical_entry
154/self->in_critical_section > 0/
155{
156 self->in_critical_section --;
157}
158
159hotspot_jni$target:::GetPrimitiveArrayCritical_return
160{
161 self->in_critical_section ++;
162 self->critical_section_name = "GetPrimitiveArrayCritical";
163}
164
165hotspot_jni$target:::GetStringCritical_return
166{
167 self->in_critical_section ++;
168 self->critical_section_name = "GetStringCritical";
169}
170
171
172:::END
173{
174 printf("%d critical section violations have been discovered\n",
175 CRITICAL_SECTION_VIOLATION_CNT);
176
177 printf("\nEND of %s\n", SAMPLE_NAME);
178}