1 /*
2     Copyright (c) 1998--2006 Benhur Stein
3 
4     This file is part of Paj�.
5 
6     Paj� is free software; you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License as published by the
8     Free Software Foundation; either version 2 of the License, or (at your
9     option) any later version.
10 
11     Paj� is distributed in the hope that it will be useful, but WITHOUT ANY
12     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13     FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
14     for more details.
15 
16     You should have received a copy of the GNU Lesser General Public License
17     along with Paj�; if not, write to the Free Software Foundation, Inc.,
18 	51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
19 */
20 
21 
22 //////////////////////////////////////////////////
23 /*      Author: Geovani Ricardo Wiedenhoft      */
24 /*      Email: grw@inf.ufsm.br                  */
25 //////////////////////////////////////////////////
26 
27 
28 
29 #include "JRastro.h"
30 
31 
32 FILE *file;
33 rst_file_t data;
34 rst_event_t ev;
35 static bool read=false;
36 timestamp_t first;
37 hash_t h_class;
38 hash_t h_method;
39 hash_t h_mem;
40 hash_data_t *class_name;
41 hash_data_t *class_number;
42 hash_data_t *data_mem;
43 list_t monitores;
44 int count = 0;
45 
46 
jrst_constant(FILE * file)47 void jrst_constant(FILE *file)
48 {
49 	fprintf(file,"1\tPJ\t0\t\"Program Java\"\n");
50 	fprintf(file,"1\tJVM\tPJ\t\"Java Virtual Machine\"\n");
51 	fprintf(file,"1\tT\tJVM\t\"Thread\"\n");
52 	fprintf(file,"1\tM\tJVM\t\"Monitor\"\n");
53 
54 	fprintf(file,"2\tE\tT\t\"MonitorE\"\n");
55 	fprintf(file,"2\tEX\tT\t\"ExceptionE\"\n");
56 
57 	fprintf(file,"3\tJS\tJVM\t\"JVM State\"\n");
58 	fprintf(file,"3\tS\tT\t\"Metodo\"\n");
59 	fprintf(file,"3\tMS\tM\t\"Monitor State\"\n");
60 
61 	fprintf(file,"4\tMEM\tJVM\t\"Memory Allocation\"\n");
62 
63 	fprintf(file,"5\tLTM\tJVM\tT\tM\t\"Thread blocked\"\n");
64 	fprintf(file,"5\tLMT\tJVM\tM\tT\t\"Thread unblocked\"\n");
65 
66 	fprintf(file,"6\texe\tJS\t\"Executing\"\n");
67 	fprintf(file,"6\tgc\tJS\t\"Garbage Collection\"\n");
68 	fprintf(file,"6\tlock\tS\t\"Thread locked\"\n");
69 	fprintf(file,"6\tlock\tMS\t\"Monitor locked\"\n");
70 	fprintf(file,"6\tfree\tMS\t\"Monitor free\"\n");
71 	fprintf(file,"6\tme\tE\t\"Monitor enter\"\n");
72 	fprintf(file,"6\tmed\tE\t\"Monitor entered\"\n");
73 	fprintf(file,"6\tmw\tE\t\"Monitor wait\"\n");
74 	fprintf(file,"6\tmwd\tE\t\"Monitor waited\"\n");
75 	fprintf(file,"6\tlb\tLTM\t\"Thread blocked\"\n");
76 	fprintf(file,"6\tlub\tLMT\t\"Thread unblocked\"\n");
77 	fprintf(file,"6\tex\tEX\t\"Start Exception\"\n");
78 	fprintf(file,"6\texpop\tEX\t\"Frame pop by Exception\"\n");
79 
80 	fprintf(file,"7\t0.0\tpj\tPJ\t0\t\"Programa Java\"\n");
81 
82 }
83 
jrst_access_flags(FILE * file,unsigned int flags)84 void jrst_access_flags(FILE *file, unsigned int flags)
85 {
86 	if(flags & JVM_ACC_PUBLIC){
87 		fprintf(file," PUBLIC");
88 	}
89 	if(flags & JVM_ACC_PRIVATE){
90 		fprintf(file," PRIVATE");
91 	}
92 	if(flags & JVM_ACC_PROTECTED){
93 		fprintf(file," PROTECTED");
94 	}
95 	if(flags & JVM_ACC_STATIC){
96 		fprintf(file," STATIC");
97 	}
98 	if(flags & JVM_ACC_FINAL){
99 		fprintf(file," FINAL");
100 	}
101 	if(flags & JVM_ACC_SYNCHRONIZED){
102 		fprintf(file," SYNCHRONIZED");
103 	}
104 	if(flags & JVM_ACC_NATIVE){
105 		fprintf(file," NATIVE");
106 	}
107 	if(flags & JVM_ACC_INTERFACE){
108 		fprintf(file," INTERFACE");
109 	}
110 	if(flags & JVM_ACC_ABSTRACT){
111 		fprintf(file," ABSTRACT");
112 	}
113 	if(flags & JVM_ACC_STRICT){
114 		fprintf(file," STRICT");
115 	}
116 }
117 
jrst_initialize()118 void jrst_initialize()
119 {
120 	if(!read){
121 		first=ev.timestamp;
122 		read=true;
123 	}
124 
125 	if(ev.id1 == ev.id2){
126 		fprintf(file,"7\t%.6f\tj-%lld\tJVM\tpj\t\"JVM-%lld\"\n",(((double)(ev.timestamp - first))/ 1000000.0),ev.id1,ev.id1);
127 		fprintf(file,"11\t%.6f\tJS\tj-%lld\texe\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1);
128 		fprintf(file,"13\t%.6f\tMEM\tj-%lld\t0.0\n",(((double)(ev.timestamp - first))/ 1000000.0), ev.id1);
129 	}
130 	fprintf(file,"777\t%.6f\tt-%lld\tT\tj-%lld\t\"%s-%d\"\t%x\t%x\t%x\n",(((double)(ev.timestamp - first))/ 1000000.0),ev.id2,ev.id1,ev.v_string[0], count, ev.v_uint32[1], ev.v_uint32[2],ev.v_uint32[3]);
131 	count++;
132 }
133 
jrst_finalize()134 void jrst_finalize()
135 {
136 	fprintf(file,"8\t%.6f\tt-%lld\tT\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2);
137 }
138 
jrst_event_class()139 void jrst_event_class()
140 {
141 	hash_insert(&h_class, (hash_key_t)(ev.v_uint32[0]+(int)ev.id1), (hash_data_t)ev.v_string[0]);
142 }
143 
jrst_event_method()144 void jrst_event_method()
145 {
146 	class_name = hash_locate(&h_class, (hash_key_t)(ev.v_uint32[1]+(int)ev.id1));
147 	if(class_name == NULL){
148 		printf("ERROR: Cannot load Method\n");
149 		exit(1);
150 	}
151 	if(ev.v_uint32[2] == 0){
152 		fprintf(file,"666\te-%lld.%x\tS\t\"%s.%s\"\t%lld.%x\n", ev.id1, ev.v_uint32[0], *(char **)class_name, ev.v_string[0], ev.id1, ev.v_uint32[1]);
153 	}else{
154 		fprintf(file,"6666\te-%lld.%x\tS\t\"%s.%s\"\t%lld.%x\t\"F=", ev.id1, ev.v_uint32[0], *(char **)class_name, ev.v_string[0], ev.id1, ev.v_uint32[1]);
155 		jrst_access_flags(file, ev.v_uint32[2]);
156 		fprintf(file,"\"\n");
157 	}
158 
159 	hash_insert(&h_method, (hash_key_t)(ev.v_uint32[0]+(int)ev.id1), (hash_data_t)(ev.v_uint32[1]+(int)ev.id1));
160 }
161 
jrst_event_method_entry_alloc()162 void jrst_event_method_entry_alloc()
163 {
164 	fprintf(file,"111\t%.6f\tS\tt-%lld\te-%lld.%x\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000),ev.id2, ev.id1, ev.v_uint32[1], ev.id1, ev.v_uint32[0]);
165 	fprintf(file,"14\t%.6f\tMEM\tj-%lld\t%lld\n",(((double)(ev.timestamp - first)) / 1000000),ev.id1, ev.v_uint64[0]);
166 	hash_insert(&h_mem, (hash_key_t)(ev.v_uint32[0]+(int)ev.id1), (hash_data_t)((long)ev.v_uint64[0]));
167 }
168 
jrst_jvmti_event_method_entry()169 void jrst_jvmti_event_method_entry()
170 {
171 	fprintf(file,"111\t%.6f\tS\tt-%lld\te-%lld.%x\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000),ev.id2, ev.id1, ev.v_uint32[1], ev.id1, ev.v_uint32[0]);
172 }
173 
jrst_method_entry()174 void jrst_method_entry()
175 {
176 	class_number = hash_locate(&h_method, (hash_key_t)(ev.v_uint32[0]+(int)ev.id1));
177 	if(class_number == NULL){
178 		printf("metodo nao achado seila=[%d]\n",ev.v_uint32[0]);
179 		printf("ERROR: Cannot Method Class\n");
180 		exit(2);
181 	}
182 	fprintf(file,"111\t%.6f\tS\tt-%lld\te-%lld.%x\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000),ev.id2, ev.id1, ev.v_uint32[0], ev.id1, (*((int*)class_number)-(int)ev.id1));
183 }
184 
jrst_jvmti_event_method_exit()185 void jrst_jvmti_event_method_exit()
186 {
187 	fprintf(file,"12\t%.6f\tS\tt-%lld\n",(((double)(ev.timestamp - first)) / 1000000),ev.id2);
188 }
189 
jrst_method_exception()190 void jrst_method_exception()
191 {
192 	fprintf(file,"9999\t%.6f\tEX\tt-%lld\tex\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2, ev.id1, ev.v_uint32[0]);
193 }
194 
jrst_method_exit_exception()195 void jrst_method_exit_exception()
196 {
197 	fprintf(file,"12\t%.6f\tS\tt-%lld\n",(((double)(ev.timestamp - first)) / 1000000),ev.id2);
198 	fprintf(file,"9\t%.6f\tEX\tt-%lld\texpop\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2);
199 }
200 
jrst_jvmti_event_vm_object_alloc()201 void jrst_jvmti_event_vm_object_alloc()
202 {
203 	fprintf(file,"14\t%.6f\tMEM\tj-%lld\t%lld\n",(((double)(ev.timestamp - first)) / 1000000),ev.id1, ev.v_uint64[0]);
204 	hash_insert(&h_mem, (hash_key_t)(ev.v_uint32[0] + (int)ev.id1), (hash_data_t)((long)ev.v_uint64[0]));
205 }
206 
jrst_jvmti_event_object_free()207 void jrst_jvmti_event_object_free()
208 {
209 	data_mem = hash_locate(&h_mem, (hash_key_t)(ev.v_uint32[0] + (int)ev.id1));
210 	if(data_mem == NULL){
211 		printf("ERROR: Cannot JVMTI_EVENT_OBJECT_FREE \n");
212 		printf("\tObjeto=[%x] nao achado para liberar\n",ev.v_uint32[0]);
213 		return;
214 		//continue;
215 		//exit(2);
216 	}
217 	fprintf(file,"15\t%.6f\tMEM\tj-%lld\t%lld\n",(((double)(ev.timestamp - first)) / 1000000),ev.id1, (long long)*(long*)data_mem);
218 }
219 
jrst_jvmti_event_garbage_collection_start()220 void jrst_jvmti_event_garbage_collection_start()
221 {
222 	fprintf(file,"11\t%.6f\tJS\tj-%lld\tgc\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1);
223 }
224 
jrst_jvmti_event_garbage_collection_finish()225 void jrst_jvmti_event_garbage_collection_finish()
226 {
227 	fprintf(file,"12\t%.6f\tJS\tj-%lld\n",(((double)(ev.timestamp - first)) / 1000000),ev.id1);
228 }
229 
jrst_event_monitor_enter()230 void jrst_event_monitor_enter()
231 {
232 	list_object_t obj;
233 	obj.jvm = ev.id1;
234 	obj.idObject = ev.v_uint32[0];
235 	if(!list_find(&monitores, (void *)&obj)){
236 		list_insert_after(&monitores, NULL, (void *)&obj);
237 		fprintf(file,"7\t%.6f\to-%lld.%x\tM\tj-%lld\t\"Monitor-%lld.%x\"\n",(((double)(ev.timestamp - first))/ 1000000.0), ev.id1, ev.v_uint32[0], ev.id1, ev.id1, ev.v_uint32[0]);
238 
239 	}
240 	//fprintf(file,"9\t%.6f\tE\tt-%lld\tme\n",(((double)(ev.timestamp - first)) / 1000000), ev.v_uint64[0]);
241 	fprintf(file,"999\t%.6f\tE\tt-%lld\tme\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2, ev.id1, ev.v_uint32[0]);
242 	fprintf(file,"11\t%.6f\tS\tt-%lld\tlock\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2);
243 	fprintf(file,"11\t%.6f\tMS\to-%lld.%x\tlock\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.v_uint32[0]);
244 
245 	fprintf(file,"18\t%.6f\tLTM\tj-%lld\tlb\tt-%lld\tl-%lld-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.id2, ev.id2, ev.id1, ev.v_uint32[0]);
246 	fprintf(file,"19\t%.6f\tLTM\tj-%lld\tlb\to-%lld.%x\tl-%lld-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.id1, ev.v_uint32[0], ev.id2, ev.id1, ev.v_uint32[0]);
247 }
248 
jrst_event_monitor_entered()249 void jrst_event_monitor_entered()
250 {
251 	fprintf(file,"999\t%.6f\tE\tt-%lld\tmed\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2, ev.id1, ev.v_uint32[0]);
252 	fprintf(file,"12\t%.6f\tS\tt-%lld\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2);
253 	fprintf(file,"12\t%.6f\tMS\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.v_uint32[0]);
254 
255 	fprintf(file,"18\t%.6f\tLMT\tj-%lld\tlub\to-%lld.%x\tlu-%lld.%x-%lld\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.id1, ev.v_uint32[0], ev.id1, ev.v_uint32[0], ev.id2);
256 	fprintf(file,"19\t%.6f\tLMT\tj-%lld\tlub\tt-%lld\tlu-%lld.%x-%lld\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.id2, ev.id1, ev.v_uint32[0], ev.id2);
257 }
258 
jrst_event_monitor_wait()259 void jrst_event_monitor_wait()
260 {
261 	//if(!list_find(&monitores, (void *)&ev.v_uint32[0])){
262 	//	list_insert_after(&monitores, NULL, (void *)&ev.v_uint32[0]);
263 	//	fprintf(file,"7\t%.6f\to-%lld.%x\tM\tj-%lld\t\"Monitor-%lld.%x\"\n",(((double)(ev.timestamp - first))/ 1000000.0), ev.id1, ev.v_uint32[0], ev.id1, ev.id1, ev.v_uint32[0]);
264 	//}
265 	//fprintf(file,"9\t%.6f\tE\tt-%lld\tme\n",(((double)(ev.timestamp - first)) / 1000000), ev.v_uint64[0]);
266 	fprintf(file,"999\t%.6f\tE\tt-%lld\tmw\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2, ev.id1, ev.v_uint32[0]);
267 	fprintf(file,"11\t%.6f\tS\tt-%lld\tlock\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2);
268 	//fprintf(file,"11\t%.6f\tMS\to-%lld.%x\tlock\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.v_uint32[0]);
269 
270 	//fprintf(file,"18\t%.6f\tLTM\tj-%lld\tlb\tt-%lld\tl-%lld-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.id2, ev.id2, ev.id1, ev.v_uint32[0]);
271 	//fprintf(file,"19\t%.6f\tLTM\tj-%lld\tlb\to-%lld.%x\tl-%lld-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.id1, ev.v_uint32[0], ev.id2, ev.id1, ev.v_uint32[0]);
272 }
273 
jrst_event_monitor_waited()274 void jrst_event_monitor_waited()
275 {
276 	fprintf(file,"999\t%.6f\tE\tt-%lld\tmwd\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2, ev.id1, ev.v_uint32[0]);
277 	fprintf(file,"12\t%.6f\tS\tt-%lld\n",(((double)(ev.timestamp - first)) / 1000000), ev.id2);
278 	//fprintf(file,"12\t%.6f\tMS\to-%lld.%x\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.v_uint32[0]);
279 
280 	//fprintf(file,"18\t%.6f\tLMT\tj-%lld\tlub\to-%lld.%x\tlu-%lld.%x-%lld\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.id1, ev.v_uint32[0], ev.id1, ev.v_uint32[0], ev.id2);
281 	//fprintf(file,"19\t%.6f\tLMT\tj-%lld\tlub\tt-%lld\tlu-%lld.%x-%lld\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1, ev.id2, ev.id1, ev.v_uint32[0], ev.id2);
282 }
283 
jrst_event_select()284 void jrst_event_select()
285 {
286 
287 	if(ev.type == INITIALIZE){
288 		jrst_initialize();
289 
290 	}else if(ev.type == FINALIZE){
291 		jrst_finalize();
292 
293 	}else if(ev.type == CLASS_LOAD){
294 		jrst_event_class();
295 
296 	}else if(ev.type == METHOD_LOAD){
297 		jrst_event_method();
298 
299 	}else if(ev.type == EVENT_METHOD_ENTRY_ALLOC){
300 		jrst_event_method_entry_alloc();
301 
302 	}else if(ev.type == JVMTI_EVENT_METHOD_ENTRY){
303 		jrst_jvmti_event_method_entry();
304 
305 	}else if(ev.type == METHOD_ENTRY){
306 		jrst_method_entry();
307 
308 	}else if(ev.type == JVMTI_EVENT_METHOD_EXIT){
309 		jrst_jvmti_event_method_exit();
310 
311 	}else if(ev.type == METHOD_EXCEPTION){
312 		jrst_method_exception();
313 
314 	}else if(ev.type == METHOD_EXIT_EXCEPTION){
315 		jrst_method_exit_exception();
316 
317 	}else if(ev.type == JVMTI_EVENT_VM_OBJECT_ALLOC){
318 		jrst_jvmti_event_vm_object_alloc();
319 
320 	}else if(ev.type == JVMTI_EVENT_OBJECT_FREE){
321 		jrst_jvmti_event_object_free();
322 
323 	}else if(ev.type == JVMTI_EVENT_GARBAGE_COLLECTION_START){
324 		jrst_jvmti_event_garbage_collection_start();
325 
326 	}else if(ev.type == JVMTI_EVENT_GARBAGE_COLLECTION_FINISH){
327 		jrst_jvmti_event_garbage_collection_finish();
328 
329 	}else if(ev.type == MONITOR_ENTER){
330 		jrst_event_monitor_enter();
331 
332 	}else if(ev.type == MONITOR_ENTERED){
333 		jrst_event_monitor_entered();
334 
335 	}else if(ev.type == MONITOR_WAIT){
336 		jrst_event_monitor_wait();
337 
338 	}else if(ev.type == MONITOR_WAITED){
339 		jrst_event_monitor_waited();
340 
341 	}
342 }
343 
344 
345 
main(int argc,char * argv[])346 int main(int argc, char *argv[])
347 {
348 
349 	int i;
350 
351 	if(argc < 3){
352 		printf("ERROR: Cannot read args\n");
353 		printf("\t%s <TimeSync File> <Trace Files>\n",argv[0]);
354 		exit(1);
355 	}
356 	file=fopen("rastros.trace","w");
357 
358 	paje_header(file);
359 
360 	jrst_constant(file);
361 
362 	list_initialize(&monitores, list_copy_object, list_cmp_object, list_destroy_int);
363 
364 	hash_initialize(&h_class, hash_value, hash_copy, hash_key_cmp, hash_destroy);
365 	hash_initialize(&h_method, hash_value, hash_copy_new, hash_key_cmp, hash_destroy_new);
366 	hash_initialize(&h_mem, hash_value, hash_copy_new, hash_key_cmp, hash_destroy_new);
367 
368 	for (i=2; i<argc; i++) {
369 		if (rst_open_file(argv[i], &data, argv[1], 100000) == -1) {
370 			fprintf(stderr, "could not open rastro file %s\n", argv[i]);
371 			continue;
372 		}
373 	}
374 	while (rst_decode_event(&data, &ev)){
375 
376 		jrst_event_select();
377 
378 	}
379 
380 	position_t pos;
381 	for(pos = list_inicio(&monitores); pos != NULL ; pos = list_inicio(&monitores)){
382 		list_object_t *obj;
383 
384 		obj = (list_object_t *) pos->data;
385 
386 		fprintf(file,"8\t%.6f\to-%lld.%x\tM\n",(((double)(ev.timestamp - first)) / 1000000), (long long)obj->jvm, obj->idObject);
387 		list_rem_position (&monitores, pos);
388 	}
389 	list_finalize(&monitores);
390 
391 	fprintf(file,"12\t%.6f\tJS\tj-%lld\n",(((double)(ev.timestamp - first)) / 1000000),ev.id1);
392 	fprintf(file,"8\t%.6f\tj-%lld\tJVM\n",(((double)(ev.timestamp - first)) / 1000000), ev.id1);
393 	fprintf(file,"8\t%.6f\tpj\tPJ\n",(((double)(ev.timestamp - first)) / 1000000));
394 
395 	hash_finalize(&h_class);
396 	hash_finalize(&h_method);
397 	hash_finalize(&h_mem);
398 	fclose(file);
399 	return 0;
400 }
401 
402