author | goetz |
Thu, 21 Nov 2013 18:29:34 -0800 | |
changeset 22852 | 1063026e8cee |
parent 14698 | 9294fcf94c46 |
child 24967 | 582420f5ab6c |
permissions | -rw-r--r-- |
2 | 1 |
/* |
14698
9294fcf94c46
7200297: agent code does not handle multiple boot library path elements correctly
dholmes
parents:
14342
diff
changeset
|
2 |
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
|
5 |
* modification, are permitted provided that the following conditions |
|
6 |
* are met: |
|
7 |
* |
|
8 |
* - Redistributions of source code must retain the above copyright |
|
9 |
* notice, this list of conditions and the following disclaimer. |
|
10 |
* |
|
11 |
* - Redistributions in binary form must reproduce the above copyright |
|
12 |
* notice, this list of conditions and the following disclaimer in the |
|
13 |
* documentation and/or other materials provided with the distribution. |
|
14 |
* |
|
5506 | 15 |
* - Neither the name of Oracle nor the names of its |
2 | 16 |
* contributors may be used to endorse or promote products derived |
17 |
* from this software without specific prior written permission. |
|
18 |
* |
|
19 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
|
20 |
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
|
21 |
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
22 |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
|
23 |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
24 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
25 |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
26 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|
27 |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|
28 |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
29 |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
30 |
*/ |
|
31 |
||
10292
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
32 |
/* |
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
33 |
* This source code is provided to illustrate the usage of a given feature |
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
34 |
* or technique and has been deliberately simplified. Additional steps |
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
35 |
* required for a production-quality application, such as security checks, |
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
36 |
* input validation and proper error handling, might not be present in |
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
37 |
* this sample code. |
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
38 |
*/ |
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
39 |
|
ed7db6a12c2a
7067811: Update demo/sample code to state it should not be used for production
nloodin
parents:
5506
diff
changeset
|
40 |
|
2 | 41 |
/* Primary hprof #include file, should be included by most if not |
42 |
* all hprof source files. Gives access to the global data structure |
|
43 |
* and all global macros, and everything declared in the #include |
|
44 |
* files of each of the source files. |
|
45 |
*/ |
|
46 |
||
47 |
#ifndef HPROF_H |
|
48 |
#define HPROF_H |
|
49 |
||
50 |
/* Standard C functions used throughout. */ |
|
51 |
||
52 |
#include <stdio.h> |
|
53 |
#include <stdlib.h> |
|
54 |
#include <ctype.h> |
|
55 |
#include <string.h> |
|
56 |
#include <stddef.h> |
|
57 |
#include <stdarg.h> |
|
58 |
#include <limits.h> |
|
59 |
#include <time.h> |
|
60 |
#include <errno.h> |
|
61 |
||
62 |
/* General JVM/Java functions, types and macros. */ |
|
63 |
||
64 |
#include <sys/types.h> |
|
65 |
#include "jni.h" |
|
66 |
#include "jvmti.h" |
|
67 |
#include "classfile_constants.h" |
|
14698
9294fcf94c46
7200297: agent code does not handle multiple boot library path elements correctly
dholmes
parents:
14342
diff
changeset
|
68 |
#include "jvm_md.h" |
2 | 69 |
|
70 |
#ifndef SKIP_NPT |
|
71 |
#include "npt.h" /* To get NptEnv for doing character conversions */ |
|
72 |
#endif |
|
73 |
||
74 |
/* Macros to extract the upper and lower 32 bits of a jlong */ |
|
75 |
||
76 |
#define jlong_high(a) ((jint)((a)>>32)) |
|
77 |
#define jlong_low(a) ((jint)(a)) |
|
78 |
#define jlong_to_jint(a) ((jint)(a)) |
|
79 |
#define jint_to_jlong(a) ((jlong)(a)) |
|
80 |
||
81 |
#define jlong_add(a, b) ((a) + (b)) |
|
82 |
||
83 |
||
84 |
/* The type used to contain a generic 32bit "serial number". */ |
|
85 |
||
86 |
typedef unsigned SerialNumber; |
|
87 |
||
88 |
/* How the options get to OnLoad: */ |
|
89 |
||
90 |
#define AGENTNAME "hprof" |
|
91 |
#define XRUN "-Xrun" AGENTNAME |
|
92 |
#define AGENTLIB "-agentlib:" AGENTNAME |
|
93 |
||
94 |
/* Name of prelude file, found at runtime relative to java binary location */ |
|
95 |
||
96 |
#define PRELUDE_FILE "jvm.hprof.txt" |
|
97 |
||
98 |
/* File I/O buffer size to be used with any file i/o operation */ |
|
99 |
||
100 |
#define FILE_IO_BUFFER_SIZE (1024*64) |
|
101 |
||
102 |
/* Machine dependent functions. */ |
|
103 |
||
104 |
#include "hprof_md.h" |
|
105 |
||
106 |
/* Table index types */ |
|
107 |
||
108 |
typedef unsigned TableIndex; |
|
109 |
typedef TableIndex ClassIndex; |
|
110 |
typedef TableIndex FrameIndex; |
|
111 |
typedef TableIndex IoNameIndex; |
|
112 |
typedef TableIndex MonitorIndex; |
|
113 |
typedef TableIndex ObjectIndex; |
|
114 |
typedef TableIndex LoaderIndex; |
|
115 |
typedef TableIndex RefIndex; |
|
116 |
typedef TableIndex SiteIndex; |
|
117 |
typedef TableIndex StringIndex; |
|
118 |
typedef TableIndex TlsIndex; |
|
119 |
typedef TableIndex TraceIndex; |
|
120 |
||
121 |
/* Index for method tables in classes */ |
|
122 |
||
123 |
typedef int MethodIndex; |
|
124 |
||
125 |
/* The different kinds of class status bits. */ |
|
126 |
||
127 |
enum ClassStatus { |
|
128 |
CLASS_PREPARED = 0x00000001, |
|
129 |
CLASS_LOADED = 0x00000002, |
|
130 |
CLASS_UNLOADED = 0x00000004, |
|
131 |
CLASS_SPECIAL = 0x00000008, |
|
132 |
CLASS_IN_LOAD_LIST = 0x00000010, |
|
133 |
CLASS_SYSTEM = 0x00000020, |
|
134 |
CLASS_DUMPED = 0x00000040 |
|
135 |
}; |
|
136 |
typedef jint ClassStatus; |
|
137 |
||
138 |
/* The different kind of objects we track with heap=dump */ |
|
139 |
||
140 |
typedef unsigned char ObjectKind; |
|
141 |
enum { |
|
142 |
OBJECT_NORMAL = 1, |
|
143 |
OBJECT_CLASS = 2, |
|
144 |
OBJECT_SYSTEM = 3, |
|
145 |
OBJECT_HPROF = 4, |
|
146 |
OBJECT_LOADER = 5 |
|
147 |
}; |
|
148 |
||
149 |
/* Used by site_write() when writing out the heap=sites data. */ |
|
150 |
||
151 |
enum { |
|
152 |
SITE_DUMP_INCREMENTAL = 0x01, |
|
153 |
SITE_SORT_BY_ALLOC = 0x02, |
|
154 |
SITE_FORCE_GC = 0x04 |
|
155 |
}; |
|
156 |
||
157 |
/* Used to hold information about a field, and potentially a value too. */ |
|
158 |
||
159 |
typedef struct FieldInfo { |
|
160 |
ClassIndex cnum; |
|
161 |
StringIndex name_index; |
|
162 |
StringIndex sig_index; |
|
163 |
unsigned short modifiers; |
|
164 |
unsigned char primType; |
|
165 |
unsigned char primSize; |
|
166 |
} FieldInfo; |
|
167 |
||
168 |
/* Used to hold information about a constant pool entry value for a class. */ |
|
169 |
||
170 |
typedef struct ConstantPoolValue { |
|
171 |
unsigned constant_pool_index; |
|
172 |
StringIndex sig_index; |
|
173 |
jvalue value; |
|
174 |
} ConstantPoolValue; |
|
175 |
||
176 |
/* All machine independent functions */ |
|
177 |
||
178 |
#include "hprof_error.h" |
|
179 |
#include "hprof_util.h" |
|
180 |
#include "hprof_blocks.h" |
|
181 |
#include "hprof_stack.h" |
|
182 |
#include "hprof_init.h" |
|
183 |
#include "hprof_table.h" |
|
184 |
#include "hprof_string.h" |
|
185 |
#include "hprof_class.h" |
|
186 |
#include "hprof_tracker.h" |
|
187 |
#include "hprof_frame.h" |
|
188 |
#include "hprof_monitor.h" |
|
189 |
#include "hprof_trace.h" |
|
190 |
#include "hprof_site.h" |
|
191 |
#include "hprof_event.h" |
|
192 |
#include "hprof_reference.h" |
|
193 |
#include "hprof_object.h" |
|
194 |
#include "hprof_loader.h" |
|
195 |
#include "hprof_tls.h" |
|
196 |
#include "hprof_check.h" |
|
197 |
#include "hprof_io.h" |
|
198 |
#include "hprof_listener.h" |
|
199 |
#include "hprof_cpu.h" |
|
200 |
#include "hprof_tag.h" |
|
201 |
||
202 |
/* Global data structure */ |
|
203 |
||
204 |
struct LineTable; |
|
205 |
||
206 |
typedef struct { |
|
207 |
||
208 |
jvmtiEnv *jvmti; /* JVMTI env for this session */ |
|
209 |
JavaVM *jvm; /* JavaVM* for this session */ |
|
210 |
#ifndef SKIP_NPT |
|
211 |
NptEnv *npt; /* NptEnv* for this session, see npt.h */ |
|
212 |
#endif |
|
213 |
jint cachedJvmtiVersion; /* JVMTI version number */ |
|
214 |
||
215 |
char *header; /* "JAVA PROFILE 1.0.[12]" */ |
|
216 |
jboolean segmented; /* JNI_TRUE if 1.0.2 */ |
|
217 |
jlong maxHeapSegment; |
|
218 |
jlong maxMemory; |
|
219 |
||
220 |
/* Option settings */ |
|
221 |
char * options; /* option string copy */ |
|
222 |
char * utf8_output_filename;/* file=filename */ |
|
223 |
int net_port; /* net=hostname:port */ |
|
224 |
char * net_hostname; /* net=hostname:port */ |
|
225 |
char output_format; /* format=a|b */ |
|
226 |
int max_trace_depth; /* depth=max_trace_depth */ |
|
227 |
int prof_trace_depth; /* max_trace_depth or 2 (old) */ |
|
228 |
int sample_interval; /* interval=sample_interval (ms) */ |
|
229 |
double cutoff_point; /* cutoff=cutoff_point */ |
|
230 |
jboolean cpu_sampling; /* cpu=samples|y */ |
|
231 |
jboolean cpu_timing; /* cpu=times */ |
|
232 |
jboolean old_timing_format; /* cpu=old (old) output format */ |
|
233 |
jboolean heap_dump; /* heap=dump|all */ |
|
234 |
jboolean alloc_sites; /* heap=sites|all */ |
|
235 |
jboolean thread_in_traces; /* thread=y|n */ |
|
236 |
jboolean lineno_in_traces; /* lineno=y|n */ |
|
237 |
jboolean dump_on_exit; /* doe=y|n */ |
|
238 |
jboolean micro_state_accounting; /* msa=y|n */ |
|
239 |
jboolean force_output; /* force=y|n */ |
|
240 |
jboolean monitor_tracing; /* monitor=y|n */ |
|
241 |
jboolean gc_okay; /* gc_okay=y|n (Not used) */ |
|
242 |
||
243 |
unsigned logflags; /* logflags=bitmask */ |
|
244 |
||
245 |
#define DEBUGFLAG_UNPREPARED_CLASSES 0x001 |
|
246 |
unsigned debugflags; /* debugflags=bitmask */ |
|
247 |
||
248 |
jboolean coredump; /* coredump=y|n */ |
|
249 |
jboolean errorexit; /* errorexit=y|n */ |
|
250 |
jboolean pause; /* pause=y|n */ |
|
251 |
jboolean debug; /* debug=y|n */ |
|
252 |
jboolean verbose; /* verbose=y|n */ |
|
253 |
jboolean primfields; /* primfields=y|n */ |
|
254 |
jboolean primarrays; /* primarrays=y|n */ |
|
255 |
jint experiment; /* X=NUMBER */ |
|
256 |
||
257 |
int fd; /* file or socket (net=addr). */ |
|
258 |
jboolean socket; /* True if fd is a socket (net=addr). */ |
|
259 |
jboolean bci; /* True if any kind of BCI being done */ |
|
260 |
jboolean obj_watch; /* True if bci and watching allocs */ |
|
261 |
||
262 |
int bci_counter; /* Class BCI counter */ |
|
263 |
||
264 |
int heap_fd; |
|
265 |
char *output_filename; /* file=filename */ |
|
266 |
char *heapfilename; |
|
267 |
||
268 |
int check_fd; |
|
269 |
char *checkfilename; |
|
270 |
||
271 |
volatile jboolean dump_in_process; /* Dump in process */ |
|
272 |
volatile jboolean jvm_initializing; /* VMInit happening */ |
|
273 |
volatile jboolean jvm_initialized; /* VMInit happened */ |
|
274 |
volatile jboolean jvm_shut_down; /* VMDeath happened */ |
|
275 |
jboolean vm_death_callback_active; /* VMDeath happening */ |
|
276 |
||
277 |
/* Stack of objects freed during GC */ |
|
278 |
Stack * object_free_stack; |
|
279 |
jrawMonitorID object_free_lock; |
|
280 |
||
281 |
/* Lock for debug_malloc() */ |
|
282 |
jrawMonitorID debug_malloc_lock; |
|
283 |
||
284 |
/* Count of classes that JVMTI thinks are active */ |
|
285 |
jint class_count; |
|
286 |
||
287 |
/* Used to track callbacks for VM_DEATH */ |
|
288 |
jrawMonitorID callbackBlock; |
|
289 |
jrawMonitorID callbackLock; |
|
290 |
jint active_callbacks; |
|
291 |
||
292 |
/* Running totals on all bytes allocated */ |
|
293 |
jlong total_alloced_bytes; |
|
294 |
jlong total_alloced_instances; |
|
295 |
jint total_live_bytes; |
|
296 |
jint total_live_instances; |
|
297 |
||
298 |
/* Running total on all time spent in GC (very rough estimate) */ |
|
299 |
jlong gc_start_time; |
|
300 |
jlong time_in_gc; |
|
301 |
||
302 |
/* Global Data access Lock */ |
|
303 |
jrawMonitorID data_access_lock; |
|
304 |
||
305 |
/* Global Dump lock */ |
|
306 |
jrawMonitorID dump_lock; |
|
307 |
||
308 |
/* Milli-second clock when hprof onload started */ |
|
309 |
jlong micro_sec_ticks; |
|
310 |
||
311 |
/* Thread class (for starting agent threads) */ |
|
312 |
ClassIndex thread_cnum; |
|
313 |
||
314 |
/* Agent threads started information */ |
|
315 |
jboolean listener_loop_running; |
|
316 |
jrawMonitorID listener_loop_lock; |
|
317 |
jboolean cpu_loop_running; |
|
318 |
jrawMonitorID cpu_loop_lock; |
|
319 |
jrawMonitorID cpu_sample_lock; /* cpu=samples loop */ |
|
320 |
jint gc_finish; /* Count of GC finish events */ |
|
321 |
jboolean gc_finish_active; /* True if thread active */ |
|
322 |
jboolean gc_finish_stop_request; /* True if we want it to stop */ |
|
323 |
jrawMonitorID gc_finish_lock; |
|
324 |
||
325 |
jboolean pause_cpu_sampling; /* temp pause in cpu sampling */ |
|
326 |
||
327 |
/* Output buffer, position, size, and position in dump if reading */ |
|
328 |
char * write_buffer; |
|
329 |
int write_buffer_index; |
|
330 |
int write_buffer_size; |
|
331 |
char * heap_buffer; |
|
332 |
int heap_buffer_index; |
|
333 |
int heap_buffer_size; |
|
334 |
jlong heap_last_tag_position; |
|
335 |
jlong heap_write_count; |
|
336 |
char * check_buffer; |
|
337 |
int check_buffer_index; |
|
338 |
int check_buffer_size; |
|
339 |
||
340 |
/* Serial number counters for tables (see hprof_table.c), classes, |
|
341 |
* tls (thread local storage), and traces. |
|
342 |
*/ |
|
343 |
SerialNumber table_serial_number_start; |
|
344 |
SerialNumber class_serial_number_start; |
|
345 |
SerialNumber thread_serial_number_start; |
|
346 |
SerialNumber trace_serial_number_start; |
|
347 |
SerialNumber object_serial_number_start; |
|
348 |
SerialNumber frame_serial_number_start; |
|
349 |
SerialNumber gref_serial_number_start; |
|
350 |
||
351 |
SerialNumber table_serial_number_counter; |
|
352 |
SerialNumber class_serial_number_counter; |
|
353 |
SerialNumber thread_serial_number_counter; |
|
354 |
SerialNumber trace_serial_number_counter; |
|
355 |
SerialNumber object_serial_number_counter; |
|
356 |
SerialNumber frame_serial_number_counter; |
|
357 |
SerialNumber gref_serial_number_counter; |
|
358 |
||
359 |
/* The methodID for the Object <init> method. */ |
|
360 |
jmethodID object_init_method; |
|
361 |
||
362 |
/* Keeping track of the tracker class and it's methods */ |
|
363 |
volatile jint tracking_engaged; /* !=0 means it's on */ |
|
364 |
ClassIndex tracker_cnum; |
|
365 |
int tracker_method_count; |
|
366 |
struct { |
|
367 |
StringIndex name; /* String index for name */ |
|
368 |
StringIndex sig; /* String index for signature */ |
|
369 |
jmethodID method; /* Method ID */ |
|
370 |
} tracker_methods[12]; /* MAX 12 Tracker class methods */ |
|
371 |
||
372 |
/* Index to some common items */ |
|
373 |
LoaderIndex system_loader; |
|
374 |
SerialNumber unknown_thread_serial_num; |
|
375 |
TraceIndex system_trace_index; |
|
376 |
SiteIndex system_object_site_index; |
|
377 |
jint system_class_size; |
|
378 |
TraceIndex hprof_trace_index; |
|
379 |
SiteIndex hprof_site_index; |
|
380 |
||
381 |
/* Tables for strings, classes, sites, etc. */ |
|
382 |
struct LookupTable * string_table; |
|
383 |
struct LookupTable * ioname_table; |
|
384 |
struct LookupTable * class_table; |
|
385 |
struct LookupTable * site_table; |
|
386 |
struct LookupTable * object_table; |
|
387 |
struct LookupTable * reference_table; |
|
388 |
struct LookupTable * frame_table; |
|
389 |
struct LookupTable * trace_table; |
|
390 |
struct LookupTable * monitor_table; |
|
391 |
struct LookupTable * tls_table; |
|
392 |
struct LookupTable * loader_table; |
|
393 |
||
394 |
/* Handles to java_crw_demo library */ |
|
395 |
void * java_crw_demo_library; |
|
396 |
void * java_crw_demo_function; |
|
397 |
void * java_crw_demo_classname_function; |
|
398 |
||
399 |
/* Indication that the agent has been loaded */ |
|
400 |
jboolean isLoaded; |
|
401 |
||
402 |
} GlobalData; |
|
403 |
||
404 |
/* This should be the only 'extern' in the library (not exported). */ |
|
405 |
||
406 |
extern GlobalData * gdata; |
|
407 |
||
408 |
#endif |