[Bug 303523] LTTng/TMF udpates:
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / state / evProcessor / state / StateUpdateHandlers.java
1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12 package org.eclipse.linuxtools.lttng.state.evProcessor.state;
13
14 import java.util.Map;
15
16 import org.eclipse.linuxtools.lttng.TraceDebug;
17 import org.eclipse.linuxtools.lttng.event.LttngEvent;
18 import org.eclipse.linuxtools.lttng.state.StateStrings;
19 import org.eclipse.linuxtools.lttng.state.StateStrings.BdevMode;
20 import org.eclipse.linuxtools.lttng.state.StateStrings.CpuMode;
21 import org.eclipse.linuxtools.lttng.state.StateStrings.Events;
22 import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode;
23 import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode;
24 import org.eclipse.linuxtools.lttng.state.StateStrings.Fields;
25 import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;
26 import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
27 import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessType;
28 import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
29 import org.eclipse.linuxtools.lttng.state.model.LTTngCPUState;
30 import org.eclipse.linuxtools.lttng.state.model.LttngBdevState;
31 import org.eclipse.linuxtools.lttng.state.model.LttngExecutionState;
32 import org.eclipse.linuxtools.lttng.state.model.LttngIRQState;
33 import org.eclipse.linuxtools.lttng.state.model.LttngProcessState;
34 import org.eclipse.linuxtools.lttng.state.model.LttngSoftIRQState;
35 import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
36 import org.eclipse.linuxtools.lttng.state.model.LttngTrapState;
37 import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
38
39 /**
40 * Wraps the creation of individual handlers, each method creates and instance
41 * of the corresponding handler
42 *
43 * @author alvaro
44 *
45 */
46 class StateUpdateHandlers {
47
48 final IEventProcessing getSyscallEntryHandler() {
49 AbsStateUpdate handler = new AbsStateUpdate() {
50
51 private Events eventType = Events.LTT_EVENT_SYSCALL_ENTRY;
52
53 // @Override
54 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
55
56 Long cpu = trcEvent.getCpuId();
57
58 // No syscall_entry update for initialization process
59 LttngProcessState process = traceSt.getRunning_process().get(
60 cpu);
61 if ((process != null) && (process.getPid() != null)
62 && (process.getPid().longValue() == 0L)) {
63 return true;
64 }
65
66 // Get the expected event field
67 Long syscall = getAFieldLong(trcEvent, traceSt,
68 Fields.LTT_FIELD_SYSCALL_ID);
69
70 String submode = null;
71 if (syscall == null) {
72 TraceDebug
73 .debug("Syscall Field not found, traceVent time: "
74 + trcEvent.getTimestamp());
75 } else {
76 submode = traceSt.getSyscall_names().get(syscall);
77 }
78
79 if (submode == null) {
80 submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN
81 .getInName();
82 }
83
84 push_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_SYSCALL,
85 submode, trcEvent.getTimestamp(), traceSt);
86 return false;
87 }
88
89 // @Override
90 public Events getEventHandleType() {
91 return eventType;
92 }
93 };
94 return handler;
95 }
96
97 final IEventProcessing getsySyscallExitHandler() {
98 AbsStateUpdate handler = new AbsStateUpdate() {
99
100 private Events eventType = Events.LTT_EVENT_SYSCALL_EXIT;
101
102 // @Override
103 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
104
105 Long cpu = trcEvent.getCpuId();
106 LttngProcessState process = traceSt.getRunning_process().get(
107 cpu);
108
109 // No syscall_entry update for initialization process
110 if ((process != null) && (process.getPid() != null)
111 && (process.getPid().longValue() == 0L)) {
112 return true;
113 }
114
115 pop_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_SYSCALL,
116 traceSt, trcEvent.getTimestamp());
117 return false;
118
119 }
120
121 // @Override
122 public Events getEventHandleType() {
123 return eventType;
124 }
125 };
126 return handler;
127 }
128
129 /**
130 * Update stacks related to the parsing of an LttngEvent
131 *
132 * @return
133 */
134 final IEventProcessing getTrapEntryHandler() {
135 AbsStateUpdate handler = new AbsStateUpdate() {
136
137 private Events eventType = Events.LTT_EVENT_TRAP_ENTRY;
138
139 // @Override
140 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
141 Long cpu = trcEvent.getCpuId();
142
143 Long trap = getAFieldLong(trcEvent, traceSt,
144 Fields.LTT_FIELD_TRAP_ID);
145 if (trap == null) {
146 TraceDebug
147 .debug("Trap field could not be found, event time: "
148 + trcEvent.getTimestamp());
149 return true;
150 }
151
152 // ready the trap submode name
153 String submode = traceSt.getTrap_names().get(trap);
154
155 if (submode == null) {
156 submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN
157 .getInName();
158 }
159
160 /* update process state */
161 push_state(cpu, StateStrings.ExecutionMode.LTTV_STATE_TRAP,
162 submode, trcEvent.getTimestamp(), traceSt);
163
164 /* update cpu status */
165 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
166 cpu_push_mode(cpust, StateStrings.CpuMode.LTTV_CPU_TRAP);
167 cpust.pushToTrapStack(trap); /* update trap status */
168
169 // update Trap State
170 LttngTrapState trap_state = null;
171 trap_state = traceSt.getTrap_states().get(trap);
172
173 // If the trape_state exists, just increment it's counter,
174 // otherwise, create it
175 if ( trap_state == null ) {
176 trap_state = new LttngTrapState();
177 trap_state.incrementRunning();
178 traceSt.getTrap_states().put(trap, trap_state);
179 }
180 else {
181 trap_state.incrementRunning();
182 }
183
184 return false;
185
186 }
187
188 // @Override
189 public Events getEventHandleType() {
190 return eventType;
191 }
192 };
193 return handler;
194 }
195
196 /**
197 *
198 * @return
199 */
200 final IEventProcessing getTrapExitHandler() {
201 AbsStateUpdate handler = new AbsStateUpdate() {
202
203 private Events eventType = Events.LTT_EVENT_TRAP_EXIT;
204
205 // @Override
206 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
207
208 Long cpu = trcEvent.getCpuId();
209 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
210 Long trap = cpust.popFromTrapStack();
211
212 /* update process state */
213 pop_state(cpu, ExecutionMode.LTTV_STATE_TRAP, traceSt, trcEvent
214 .getTimestamp());
215
216 /* update cpu status */
217 cpu_pop_mode(cpust);
218
219 if (trap != -1L) {
220 traceSt.getTrap_states().get(trap).decrementRunning();
221 }
222 // else {
223 // TraceDebug.debug("remove this line");
224 // }
225
226 return false;
227
228 }
229
230 // @Override
231 public Events getEventHandleType() {
232 return eventType;
233 }
234 };
235 return handler;
236 }
237
238 /**
239 *
240 * @return
241 */
242 final IEventProcessing getIrqEntryHandler() {
243 AbsStateUpdate handler = new AbsStateUpdate() {
244
245 private Events eventType = Events.LTT_EVENT_IRQ_ENTRY;
246
247 // @Override
248 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
249
250 Long cpu = trcEvent.getCpuId();
251
252 Long irq = getAFieldLong(trcEvent, traceSt,
253 Fields.LTT_FIELD_IRQ_ID);
254 if (irq == null) {
255 return true;
256 }
257
258 String submode;
259 submode = traceSt.getIrq_names().get(irq);
260
261 if (submode == null) {
262 submode = ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN
263 .getInName();
264 }
265
266 /*
267 * Do something with the info about being in user or system mode
268 * when int?
269 */
270 push_state(cpu, ExecutionMode.LTTV_STATE_IRQ, submode, trcEvent
271 .getTimestamp(), traceSt);
272
273 /* update cpu state */
274 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
275 cpu_push_mode(cpust, CpuMode.LTTV_CPU_IRQ); /* mode stack */
276 cpust.pushToIrqStack(irq); /* last irq */
277
278 /* udpate irq state */
279 irq_push_mode(traceSt.getIrq_states().get(irq),
280 IRQMode.LTTV_IRQ_BUSY);
281 return false;
282
283 }
284
285 public Events getEventHandleType() {
286 return eventType;
287 }
288 };
289 return handler;
290 }
291
292 /**
293 *
294 * @return
295 */
296 final IEventProcessing getSoftIrqExitHandler() {
297 AbsStateUpdate handler = new AbsStateUpdate() {
298
299 private Events eventType = Events.LTT_EVENT_SOFT_IRQ_EXIT;
300
301 // @Override
302 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
303
304 Long cpu = trcEvent.getCpuId();
305 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
306 Long softirq = cpust.popFromSoftIrqStack();
307
308 // Update process status
309 pop_state(cpu, ExecutionMode.LTTV_STATE_SOFT_IRQ, traceSt,
310 trcEvent.getTimestamp());
311
312 /* update softirq status */
313 if (softirq != -1) {
314 LttngSoftIRQState softIrqstate = traceSt
315 .getSoft_irq_states().get(softirq);
316 softIrqstate.decrementRunning();
317 }
318
319 /* update cpu status */
320 cpu_pop_mode(cpust);
321
322 return false;
323 }
324
325 // @Override
326 public Events getEventHandleType() {
327 return eventType;
328 }
329 };
330 return handler;
331 }
332
333 /**
334 *
335 * @return
336 */
337 final IEventProcessing getIrqExitHandler() {
338 AbsStateUpdate handler = new AbsStateUpdate() {
339
340 private Events eventType = Events.LTT_EVENT_IRQ_EXIT;
341
342 // @Override
343 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
344
345 Long cpu = trcEvent.getCpuId();
346
347 /* update process state */
348 pop_state(cpu, ExecutionMode.LTTV_STATE_IRQ, traceSt, trcEvent
349 .getTimestamp());
350
351 /* update cpu status */
352 LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
353 cpu_pop_mode(cpust);
354
355 /* update irq status */
356 Long last_irq = cpust.popFromIrqStack();
357 if (last_irq != -1L) {
358 LttngIRQState irq_state = traceSt.getIrq_states().get(
359 last_irq);
360 irq_pop_mode(irq_state);
361 }
362
363 return false;
364
365 }
366
367 // @Override
368 public Events getEventHandleType() {
369 return eventType;
370 }
371 };
372 return handler;
373 }
374
375 /**
376 *
377 * @return
378 */
379 final IEventProcessing getSoftIrqRaiseHandler() {
380 AbsStateUpdate handler = new AbsStateUpdate() {
381
382 private Events eventType = Events.LTT_EVENT_SOFT_IRQ_RAISE;
383
384 // @Override
385 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
386
387 // Long cpu = trcEvent.getCpuId();
388
389 // get event field
390 Long softirq = getAFieldLong(trcEvent, traceSt,
391 Fields.LTT_FIELD_SOFT_IRQ_ID);
392
393 if (softirq == null) {
394 TraceDebug.debug("Soft_irq_id not found in "
395 + eventType.getInName() + " time: "
396 + trcEvent.getTimestamp());
397 return true;
398 }
399
400 // String submode;
401 // String[] softIrqNames = traceSt.getSoft_irq_names();
402 // if (softirq < softIrqNames.length) {
403 // submode = softIrqNames[softirq];
404 // } else {
405 // submode = "softirq " + softirq;
406 // }
407
408 /* update softirq status */
409 /* a soft irq raises are not cumulative */
410 LttngSoftIRQState irqState = traceSt.getSoft_irq_states().get(
411 softirq);
412 if (irqState != null) {
413 irqState.setPending(1L);
414 } else {
415 TraceDebug
416 .debug("unexpected soft irq id value: " + softirq);
417 }
418
419 return false;
420
421 }
422
423 // @Override
424 public Events getEventHandleType() {
425 return eventType;
426 }
427 };
428 return handler;
429 }
430
431 /**
432 *
433 * @return
434 */
435 final IEventProcessing getSoftIrqEntryHandler() {
436 AbsStateUpdate handler = new AbsStateUpdate() {
437
438 private Events eventType = Events.LTT_EVENT_SOFT_IRQ_ENTRY;
439
440 // @Override
441 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
442
443 // obtrain cpu
444 Long cpu = trcEvent.getCpuId();
445
446 // get event field
447 Long softirq = getAFieldLong(trcEvent, traceSt,
448 Fields.LTT_FIELD_SOFT_IRQ_ID);
449
450 if (softirq == null) {
451 TraceDebug.debug("Soft IRQ ID not found, eventTime: "
452 + trcEvent.getTimestamp());
453 return true;
454 }
455
456 // obtain submode
457 Map<Long, String> softIrqNames = traceSt.getSoft_irq_names();
458 String submode = softIrqNames.get(softirq);
459 if (submode == null) {
460 submode = "softirq " + softirq;
461 softIrqNames.put(softirq, submode);
462 }
463
464 /* update softirq status */
465 LttngSoftIRQState irqState = traceSt.getSoft_irq_states().get(
466 softirq);
467 if (irqState != null) {
468 irqState.decrementPending();
469 irqState.incrementRunning();
470 } else {
471 TraceDebug
472 .debug("unexpected soft irq id value: " + softirq);
473 }
474
475 /* update cpu state */
476 LTTngCPUState cpu_state = traceSt.getCpu_states().get(cpu);
477 cpu_state.pushToSoftIrqStack(softirq);
478 cpu_push_mode(cpu_state, CpuMode.LTTV_CPU_SOFT_IRQ);
479
480 /* update process execution mode state stack */
481 push_state(cpu, ExecutionMode.LTTV_STATE_SOFT_IRQ, submode,
482 trcEvent.getTimestamp(), traceSt);
483
484 return false;
485
486 }
487
488 // @Override
489 public Events getEventHandleType() {
490 return eventType;
491 }
492 };
493 return handler;
494 }
495
496 /**
497 * Method to handle the event: LTT_EVENT_LIST_INTERRRUPT
498 *
499 * @return
500 */
501 final IEventProcessing getEnumInterruptHandler() {
502 AbsStateUpdate handler = new AbsStateUpdate() {
503
504 private Events eventType = Events.LTT_EVENT_LIST_INTERRUPT;
505
506 // @Override
507 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
508 String action = getAFieldString(trcEvent, traceSt,
509 Fields.LTT_FIELD_ACTION);
510 Long irq = getAFieldLong(trcEvent, traceSt,
511 Fields.LTT_FIELD_IRQ_ID);
512
513 if (action == null) {
514 TraceDebug.debug("Field Action not found in event "
515 + eventType.getInName() + " time: "
516 + trcEvent.getTimestamp());
517 return true;
518 }
519
520 if (irq == null) {
521 TraceDebug.debug("Field irq_id not found in event "
522 + eventType.getInName() + " time: "
523 + trcEvent.getTimestamp());
524 return true;
525 }
526
527 Map<Long, String> irq_names = traceSt.getIrq_names();
528
529 irq_names.put(irq, action);
530 return false;
531
532 }
533
534 // @Override
535 public Events getEventHandleType() {
536 return eventType;
537 }
538 };
539 return handler;
540 }
541
542 /**
543 * Handle the event LTT_EVENT_REQUEST_ISSUE
544 *
545 * @return
546 */
547 final IEventProcessing getBdevRequestIssueHandler() {
548 AbsStateUpdate handler = new AbsStateUpdate() {
549
550 private Events eventType = Events.LTT_EVENT_REQUEST_ISSUE;
551
552 // @Override
553 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
554
555 // Get Fields
556 Long major = getAFieldLong(trcEvent, traceSt,
557 Fields.LTT_FIELD_MAJOR);
558 Long minor = getAFieldLong(trcEvent, traceSt,
559 Fields.LTT_FIELD_MINOR);
560 Long operation = getAFieldLong(trcEvent, traceSt,
561 Fields.LTT_FIELD_OPERATION);
562
563 // calculate bdevcode
564 Long devcode = mkdev(major, minor);
565
566 if (devcode == null) {
567 TraceDebug
568 .debug("incorrect calcualtion of bdevcode input( major: "
569 + major
570 + " minor: "
571 + minor
572 + " operation: " + operation);
573 return true;
574 }
575
576 Map<Long, LttngBdevState> bdev_states = traceSt
577 .getBdev_states();
578 // Get the instance
579 LttngBdevState bdevState = bdev_states.get(devcode);
580 if (bdevState == null) {
581 bdevState = new LttngBdevState();
582 }
583
584 // update the mode in the stack
585 if (operation == 0L) {
586 bdevState.pushToBdevStack(BdevMode.LTTV_BDEV_BUSY_READING);
587 } else {
588 bdevState.pushToBdevStack(BdevMode.LTTV_BDEV_BUSY_WRITING);
589 }
590
591 // make sure it is included in the set
592 bdev_states.put(devcode, bdevState);
593 return false;
594
595 }
596
597 // @Override
598 public Events getEventHandleType() {
599 return eventType;
600 }
601 };
602 return handler;
603 }
604
605 /**
606 * <p>
607 * Handling event: LTT_EVENT_REQUEST_COMPLETE
608 * </p>
609 * <p>
610 * FIELDS(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION
611 * </p>
612 *
613 * @return
614 */
615 final IEventProcessing getBdevRequestCompleteHandler() {
616 AbsStateUpdate handler = new AbsStateUpdate() {
617
618 private Events eventType = Events.LTT_EVENT_REQUEST_COMPLETE;
619
620 // @Override
621 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
622
623 // Get Fields
624 Long major = getAFieldLong(trcEvent, traceSt,
625 Fields.LTT_FIELD_MAJOR);
626 Long minor = getAFieldLong(trcEvent, traceSt,
627 Fields.LTT_FIELD_MINOR);
628 Long operation = getAFieldLong(trcEvent, traceSt,
629 Fields.LTT_FIELD_OPERATION);
630
631 // calculate bdevcode
632 Long devcode = mkdev(major, minor);
633
634 if (devcode == null) {
635 TraceDebug
636 .debug("incorrect calcualtion of bdevcode input( major: "
637 + major
638 + " minor: "
639 + minor
640 + " operation: " + operation);
641 return true;
642 }
643
644 Map<Long, LttngBdevState> bdev_states = traceSt
645 .getBdev_states();
646 // Get the instance
647 LttngBdevState bdevState = bdev_states.get(devcode);
648 if (bdevState == null) {
649 bdevState = new LttngBdevState();
650 }
651
652 /* update block device */
653 bdev_pop_mode(bdevState);
654
655 return false;
656
657 }
658
659 // @Override
660 public Events getEventHandleType() {
661 return eventType;
662 }
663 };
664 return handler;
665 }
666
667 /**
668 * <p>
669 * Handles event: LTT_EVENT_FUNCTION_ENTRY
670 * </p>
671 * <p>
672 * FIELDS: LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE
673 * </p>
674 *
675 * @return
676 */
677 final IEventProcessing getFunctionEntryHandler() {
678 AbsStateUpdate handler = new AbsStateUpdate() {
679
680 private Events eventType = Events.LTT_EVENT_FUNCTION_ENTRY;
681
682 // @Override
683 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
684 Long cpu = trcEvent.getCpuId();
685 Long funcptr = getAFieldLong(trcEvent, traceSt,
686 Fields.LTT_FIELD_THIS_FN);
687
688 push_function(traceSt, funcptr, cpu);
689 return false;
690
691 }
692
693 // @Override
694 public Events getEventHandleType() {
695 return eventType;
696 }
697 };
698 return handler;
699 }
700
701 /**
702 *
703 * @return
704 */
705 final IEventProcessing getFunctionExitHandler() {
706 AbsStateUpdate handler = new AbsStateUpdate() {
707
708 private Events eventType = Events.LTT_EVENT_FUNCTION_EXIT;
709
710 // @Override
711 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
712
713 Long funcptr = getAFieldLong(trcEvent, traceSt,
714 Fields.LTT_FIELD_THIS_FN);
715
716 pop_function(traceSt, trcEvent, funcptr);
717 return false;
718
719 }
720
721 // @Override
722 public Events getEventHandleType() {
723 return eventType;
724 }
725 };
726 return handler;
727 }
728
729 /**
730 * <p>
731 * process event: LTT_EVENT_SYS_CALL_TABLE
732 * </p>
733 * <p>
734 * fields: LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL
735 * </p>
736 *
737 * @return
738 */
739 final IEventProcessing getDumpSyscallHandler() {
740 AbsStateUpdate handler = new AbsStateUpdate() {
741
742 private Events eventType = Events.LTT_EVENT_SYS_CALL_TABLE;
743
744 // @Override
745 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
746 // obtain the syscall id
747 Long id = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_ID);
748
749 // Long address = getAFieldLong(trcEvent, traceSt,
750 // Fields.LTT_FIELD_ADDRESS);
751
752 // Obtain the symbol
753 String symbol = getAFieldString(trcEvent, traceSt,
754 Fields.LTT_FIELD_SYMBOL);
755
756 // fill the symbol to the sycall_names collection
757 traceSt.getSyscall_names().put(id, symbol);
758
759 return false;
760 }
761
762 // @Override
763 public Events getEventHandleType() {
764 return eventType;
765 }
766 };
767 return handler;
768 }
769
770 /**
771 * <p>
772 * Handles event: LTT_EVENT_KPROBE_TABLE
773 * </p>
774 * <p>
775 * Fields: LTT_FIELD_IP, LTT_FIELD_SYMBOL
776 * </p>
777 *
778 * @return
779 */
780 final IEventProcessing getDumpKprobeHandler() {
781 AbsStateUpdate handler = new AbsStateUpdate() {
782
783 private Events eventType = Events.LTT_EVENT_KPROBE_TABLE;
784
785 // @Override
786 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
787
788 Long ip = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_IP);
789 String symbol = getAFieldString(trcEvent, traceSt,
790 Fields.LTT_FIELD_SYMBOL);
791
792 traceSt.getKprobe_table().put(ip, symbol);
793
794 return false;
795
796 }
797
798 // @Override
799 public Events getEventHandleType() {
800 return eventType;
801 }
802 };
803 return handler;
804 }
805
806 /**
807 * <p>
808 * Handles: LTT_EVENT_SOFTIRQ_VEC
809 * </p>
810 * <p>
811 * Fields: LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL
812 * </p>
813 *
814 * @return
815 */
816 final IEventProcessing getDumpSoftIrqHandler() {
817 AbsStateUpdate handler = new AbsStateUpdate() {
818
819 private Events eventType = Events.LTT_EVENT_SOFTIRQ_VEC;
820
821 // @Override
822 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
823
824 // Get id
825 Long id = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_ID);
826
827 // Address not needed
828 // Long address = ltt_event_get_long_unsigned(e,
829 // lttv_trace_get_hook_field(th,
830 // 1));
831
832 // Get symbol
833 String symbol = getAFieldString(trcEvent, traceSt,
834 Fields.LTT_FIELD_SYMBOL);
835
836 // Register the soft irq name
837 traceSt.getSoft_irq_names().put(id, symbol);
838 return false;
839
840 }
841
842 // @Override
843 public Events getEventHandleType() {
844 return eventType;
845 }
846 };
847 return handler;
848 }
849
850 /**
851 * <p>
852 * Handles: LTT_EVENT_SCHED_SCHEDULE
853 * </p>
854 * <p>
855 * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE
856 * </p>
857 *
858 * @return
859 */
860 final IEventProcessing getSchedChangeHandler() {
861 AbsStateUpdate handler = new AbsStateUpdate() {
862
863 private Events eventType = Events.LTT_EVENT_SCHED_SCHEDULE;
864
865 // @Override
866 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
867
868 Long cpu = trcEvent.getCpuId();
869 TmfTimestamp eventTime = trcEvent.getTimestamp();
870
871 LttngProcessState process = traceSt.getRunning_process().get(
872 cpu);
873
874 Long pid_out = getAFieldLong(trcEvent, traceSt,
875 Fields.LTT_FIELD_PREV_PID);
876 Long pid_in = getAFieldLong(trcEvent, traceSt,
877 Fields.LTT_FIELD_NEXT_PID);
878 Long state_out = getAFieldLong(trcEvent, traceSt,
879 Fields.LTT_FIELD_PREV_STATE);
880
881 if (process != null) {
882
883 /*
884 * We could not know but it was not the idle process
885 * executing. This should only happen at the beginning,
886 * before the first schedule event, and when the initial
887 * information (current process for each CPU) is missing. It
888 * is not obvious how we could, after the fact, compensate
889 * the wrongly attributed statistics.
890 */
891
892 // This test only makes sense once the state is known and if
893 // there
894 // is no
895 // missing events. We need to silently ignore schedchange
896 // coming
897 // after a
898 // process_free, or it causes glitches. (FIXME)
899 // if(unlikely(process->pid != pid_out)) {
900 // g_assert(process->pid == 0);
901 // }
902 if ((process.getPid().longValue() == 0L)
903 && (process.getState().getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) {
904 if ((pid_out != null) && (pid_out.longValue() == 0L)) {
905 /*
906 * Scheduling out of pid 0 at beginning of the trace
907 * : we know for sure it is in syscall mode at this
908 * point.
909 */
910
911 process.getState().setExec_mode(
912 ExecutionMode.LTTV_STATE_SYSCALL);
913 process.getState().setProc_status(
914 ProcessStatus.LTTV_STATE_WAIT);
915 process.getState().setChange_Time(
916 trcEvent.getTimestamp().getValue());
917 process.getState().setEntry_Time(
918 trcEvent.getTimestamp().getValue());
919 }
920 } else {
921 if (process.getState().getProc_status() == ProcessStatus.LTTV_STATE_EXIT) {
922 process.getState().setProc_status(
923 ProcessStatus.LTTV_STATE_ZOMBIE);
924 process.getState().setChange_Time(
925 trcEvent.getTimestamp().getValue());
926 } else {
927 if ((state_out != null)
928 && (state_out.longValue() == 0L)) {
929 process.getState().setProc_status(
930 ProcessStatus.LTTV_STATE_WAIT_CPU);
931 } else {
932 process.getState().setProc_status(
933 ProcessStatus.LTTV_STATE_WAIT);
934 }
935
936 process.getState().setChange_Time(
937 trcEvent.getTimestamp().getValue());
938 }
939
940 if ((state_out != null)
941 && (state_out == 32L || state_out == 64L)) { /*
942 * EXIT_DEAD
943 * ||
944 * TASK_DEAD
945 */
946 /* see sched.h for states */
947 if (!exit_process(traceSt, process)) {
948 process.getState().setProc_status(
949 ProcessStatus.LTTV_STATE_DEAD);
950 process.getState().setChange_Time(
951 trcEvent.getTimestamp().getValue());
952 }
953 }
954 }
955 }
956 process = lttv_state_find_process_or_create(traceSt, cpu,
957 pid_in, eventTime);
958
959 traceSt.getRunning_process().put(cpu, process);
960
961 process.getState().setProc_status(ProcessStatus.LTTV_STATE_RUN);
962 process.getState().setChange_Time(eventTime.getValue());
963 process.setCpu(cpu);
964 // process->state->s = LTTV_STATE_RUN;
965 // if(process->usertrace)
966 // process->usertrace->cpu = cpu;
967 // process->last_cpu_index =
968 // ltt_tracefile_num(((LttvTracefileContext*)s)->tf);
969
970 // process->state->change = s->parent.timestamp;
971
972 LTTngCPUState cpu_state = traceSt.getCpu_states().get(cpu);
973 /* update cpu status */
974 if ((pid_in != null) && (pid_in.longValue() == 0L)) {
975
976 /* going to idle task */
977 cpu_set_base_mode(cpu_state, CpuMode.LTTV_CPU_IDLE);
978 } else {
979 /*
980 * scheduling a real task. we must be careful here: if we
981 * just schedule()'ed to a process that is in a trap, we
982 * must put the cpu in trap mode
983 */
984 cpu_set_base_mode(cpu_state, CpuMode.LTTV_CPU_BUSY);
985 if (process.getState().getExec_mode() == ExecutionMode.LTTV_STATE_TRAP) {
986 cpu_push_mode(cpu_state, CpuMode.LTTV_CPU_TRAP);
987 }
988 }
989 return false;
990
991 }
992
993 // @Override
994 public Events getEventHandleType() {
995 return eventType;
996 }
997 };
998 return handler;
999 }
1000
1001 /**
1002 * <p>
1003 * Handles: LTT_EVENT_PROCESS_FORK
1004 * </p>
1005 * <p>
1006 * Fields: FIELD_ARRAY(LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID,
1007 * LTT_FIELD_CHILD_TGID)
1008 * </p>
1009 *
1010 * @return
1011 */
1012 final IEventProcessing getProcessForkHandler() {
1013 AbsStateUpdate handler = new AbsStateUpdate() {
1014
1015 private Events eventType = Events.LTT_EVENT_PROCESS_FORK;
1016
1017 // @Override
1018 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1019
1020 Long cpu = trcEvent.getCpuId();
1021 LttngProcessState process = traceSt.getRunning_process().get(
1022 cpu);
1023 TmfTimestamp timeStamp = trcEvent.getTimestamp();
1024
1025 // /* Parent PID */
1026 // Long parent_pid = getAFieldLong(trcEvent, traceSt,
1027 // Fields.LTT_FIELD_PARENT_PID);
1028
1029 /* Child PID */
1030 /* In the Linux Kernel, there is one PID per thread. */
1031 Long child_pid = getAFieldLong(trcEvent, traceSt,
1032 Fields.LTT_FIELD_CHILD_PID);
1033
1034 /* Child TGID */
1035 /* tgid in the Linux kernel is the "real" POSIX PID. */
1036 Long child_tgid = getAFieldLong(trcEvent, traceSt,
1037 Fields.LTT_FIELD_CHILD_TGID);
1038 if (child_tgid == null) {
1039 child_tgid = 0L;
1040 }
1041
1042 /*
1043 * Mathieu : it seems like the process might have been scheduled
1044 * in before the fork, and, in a rare case, might be the current
1045 * process. This might happen in a SMP case where we don't have
1046 * enough precision on the clocks.
1047 *
1048 * Test reenabled after precision fixes on time. (Mathieu)
1049 */
1050 // #if 0
1051 // zombie_process = lttv_state_find_process(ts, ANY_CPU,
1052 // child_pid);
1053 //
1054 // if(unlikely(zombie_process != NULL)) {
1055 // /* Reutilisation of PID. Only now we are sure that the old
1056 // PID
1057 // * has been released. FIXME : should know when release_task
1058 // happens
1059 // instead.
1060 // */
1061 // guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
1062 // guint i;
1063 // for(i=0; i< num_cpus; i++) {
1064 // g_assert(zombie_process != ts->running_process[i]);
1065 // }
1066 //
1067 // exit_process(s, zombie_process);
1068 // }
1069 // #endif //0
1070
1071 if (process.getPid().equals(child_pid)) {
1072 TraceDebug
1073 .debug("Unexpected, process pid equal to child pid: "
1074 + child_pid
1075 + " Event Time: "
1076 + trcEvent.getTimestamp());
1077 }
1078
1079 // g_assert(process->pid != child_pid);
1080 // FIXME : Add this test in the "known state" section
1081 // g_assert(process->pid == parent_pid);
1082 LttngProcessState child_process = lttv_state_find_process(
1083 traceSt, ANY_CPU, child_pid);
1084 if (child_process == null) {
1085 child_process = create_process(traceSt, cpu, child_pid,
1086 child_tgid, timeStamp);
1087 child_process.setPpid(process.getPid(), timeStamp.getValue());
1088 } else {
1089 /*
1090 * The process has already been created : due to time
1091 * imprecision between multiple CPUs : it has been scheduled
1092 * in before creation. Note that we shouldn't have this kind
1093 * of imprecision.
1094 *
1095 * Simply put a correct parent.
1096 */
1097 StringBuilder sb = new StringBuilder("Process " + child_pid);
1098 sb.append(" has been created at ["
1099 + child_process.getCreation_time() + "] ");
1100 sb.append("and inserted at ["
1101 + child_process.getInsertion_time() + "] ");
1102 sb.append("before \nfork on cpu " + cpu + " Event time: ["
1103 + trcEvent + "]\n.");
1104 sb
1105 .append("Probably an unsynchronized TSD problem on the traced machine.");
1106 TraceDebug.debug(sb.toString());
1107
1108 // g_assert(0); /* This is a problematic case : the process
1109 // has
1110 // beencreated
1111 // before the fork event */
1112 child_process.setPpid(process.getPid());
1113 child_process.setTgid(child_tgid);
1114 }
1115
1116 if (!child_process.getName().equals(
1117 ProcessStatus.LTTV_STATE_UNNAMED.getInName())) {
1118 TraceDebug.debug("Unexpected child process status: "
1119 + child_process.getName());
1120 }
1121
1122 child_process.setName(process.getName());
1123 child_process.setBrand(process.getBrand());
1124
1125 return false;
1126
1127 }
1128
1129 // @Override
1130 public Events getEventHandleType() {
1131 return eventType;
1132 }
1133 };
1134 return handler;
1135 }
1136
1137 /**
1138 * <p>
1139 * Handles: LTT_EVENT_KTHREAD_CREATE
1140 * </p>
1141 * <p>
1142 * Fields: LTT_FIELD_PID
1143 * </p>
1144 *
1145 * @return
1146 */
1147 final IEventProcessing getProcessKernelThreadHandler() {
1148 AbsStateUpdate handler = new AbsStateUpdate() {
1149
1150 private Events eventType = Events.LTT_EVENT_KTHREAD_CREATE;
1151
1152 // @Override
1153 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1154 /*
1155 * We stamp a newly created process as kernel_thread. The thread
1156 * should not be running yet.
1157 */
1158
1159 LttngExecutionState exState;
1160 Long pid;
1161 LttngProcessState process;
1162
1163 /* PID */
1164 pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID);
1165 // s->parent.target_pid = pid;
1166
1167 process = lttv_state_find_process_or_create(traceSt, ANY_CPU,
1168 pid, new TmfTimestamp());
1169
1170 if (!process.getState().getProc_status().equals(
1171 ProcessStatus.LTTV_STATE_DEAD)) {
1172 // Leave only the first element in the stack with execution
1173 // mode to
1174 // syscall
1175 exState = process.getFirstElementFromExecutionStack();
1176 exState.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL);
1177 process.clearExecutionStack();
1178 process.pushToExecutionStack(exState);
1179 }
1180
1181 process.setType(ProcessType.LTTV_STATE_KERNEL_THREAD);
1182
1183 return false;
1184
1185 }
1186
1187 // @Override
1188 public Events getEventHandleType() {
1189 return eventType;
1190 }
1191 };
1192 return handler;
1193 }
1194
1195 /**
1196 * <p>
1197 * Handles: LTT_EVENT_PROCESS_EXIT
1198 * </p>
1199 * <p>
1200 * LTT_FIELD_PID
1201 * </p>
1202 *
1203 * @return
1204 */
1205 final IEventProcessing getProcessExitHandler() {
1206 AbsStateUpdate handler = new AbsStateUpdate() {
1207
1208 private Events eventType = Events.LTT_EVENT_PROCESS_EXIT;
1209
1210 // @Override
1211 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1212
1213 Long pid;
1214 LttngProcessState process;
1215
1216 pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID);
1217 // s->parent.target_pid = pid;
1218
1219 // FIXME : Add this test in the "known state" section
1220 // g_assert(process->pid == pid);
1221
1222 process = lttv_state_find_process(traceSt, ANY_CPU, pid);
1223 if (process != null) {
1224 process.getState().setProc_status(
1225 ProcessStatus.LTTV_STATE_EXIT);
1226 }
1227 return false;
1228
1229 }
1230
1231 // @Override
1232 public Events getEventHandleType() {
1233 return eventType;
1234 }
1235 };
1236 return handler;
1237 }
1238
1239 /**
1240 * <p>
1241 * Handles: LTT_EVENT_PROCESS_FREE
1242 * </p>
1243 * <p>
1244 * Fields: LTT_FIELD_PID
1245 * </p>
1246 *
1247 * @return
1248 */
1249 final IEventProcessing getProcessFreeHandler() {
1250 AbsStateUpdate handler = new AbsStateUpdate() {
1251
1252 private Events eventType = Events.LTT_EVENT_PROCESS_FREE;
1253
1254 // @Override
1255 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1256
1257 Long release_pid;
1258 LttngProcessState process;
1259
1260 /* PID of the process to release */
1261 release_pid = getAFieldLong(trcEvent, traceSt,
1262 Fields.LTT_FIELD_PID);
1263 // s->parent.target_pid = release_pid;
1264
1265 if ((release_pid != null) && (release_pid.longValue() == 0L)) {
1266 TraceDebug.debug("Unexpected release_pid: 0, Event time: "
1267 + trcEvent.getTimestamp());
1268 }
1269
1270 process = lttv_state_find_process(traceSt, ANY_CPU, release_pid);
1271 if (process != null) {
1272 exit_process(traceSt, process);
1273 }
1274
1275 return false;
1276 // DISABLED
1277 // if(process != null) {
1278 /*
1279 * release_task is happening at kernel level : we can now safely
1280 * release the data structure of the process
1281 */
1282 // This test is fun, though, as it may happen that
1283 // at time t : CPU 0 : process_free
1284 // at time t+150ns : CPU 1 : schedule out
1285 // Clearly due to time imprecision, we disable it. (Mathieu)
1286 // If this weird case happen, we have no choice but to put the
1287 // Currently running process on the cpu to 0.
1288 // I re-enable it following time precision fixes. (Mathieu)
1289 // Well, in the case where an process is freed by a process on
1290 // another
1291 // CPU
1292 // and still scheduled, it happens that this is the schedchange
1293 // that
1294 // will
1295 // drop the last reference count. Do not free it here!
1296
1297 // int num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
1298 // guint i;
1299 // for(i=0; i< num_cpus; i++) {
1300 // //g_assert(process != ts->running_process[i]);
1301 // if(process == ts->running_process[i]) {
1302 // //ts->running_process[i] = lttv_state_find_process(ts, i, 0);
1303 // break;
1304 // }
1305 // }
1306 // if(i == num_cpus) /* process is not scheduled */
1307 // exit_process(s, process);
1308 // }
1309 //
1310 // return false;
1311
1312 }
1313
1314 // @Override
1315 public Events getEventHandleType() {
1316 return eventType;
1317 }
1318 };
1319 return handler;
1320 }
1321
1322 /**
1323 * <p>
1324 * Handles: LTT_EVENT_EXEC
1325 * </p>
1326 * <p>
1327 * FIELDS: LTT_FIELD_FILENAME
1328 * </p>
1329 *
1330 * @return
1331 */
1332 final IEventProcessing getProcessExecHandler() {
1333 AbsStateUpdate handler = new AbsStateUpdate() {
1334
1335 private Events eventType = Events.LTT_EVENT_EXEC;
1336
1337 // @Override
1338 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1339
1340 Long cpu = trcEvent.getCpuId();
1341 LttngProcessState process = traceSt.getRunning_process().get(
1342 cpu);
1343
1344 // #if 0//how to use a sequence that must be transformed in a
1345 // string
1346 // /* PID of the process to release */
1347 // guint64 name_len = ltt_event_field_element_number(e,
1348 // lttv_trace_get_hook_field(th, 0));
1349 // //name = ltt_event_get_string(e,
1350 // lttv_trace_get_hook_field(th, 0));
1351 // LttField *child = ltt_event_field_element_select(e,
1352 // lttv_trace_get_hook_field(th, 0), 0);
1353 // gchar *name_begin =
1354 // (gchar*)(ltt_event_data(e)+ltt_event_field_offset(e, child));
1355 // gchar *null_term_name = g_new(gchar, name_len+1);
1356 // memcpy(null_term_name, name_begin, name_len);
1357 // null_term_name[name_len] = '\0';
1358 // process->name = g_quark_from_string(null_term_name);
1359 // #endif //0
1360
1361 process.setName(getAFieldString(trcEvent, traceSt,
1362 Fields.LTT_FIELD_FILENAME));
1363 process.setBrand(StateStrings.LTTV_STATE_UNBRANDED);
1364 return false;
1365
1366 }
1367
1368 // @Override
1369 public Events getEventHandleType() {
1370 return eventType;
1371 }
1372 };
1373 return handler;
1374 }
1375
1376 /**
1377 * <p>
1378 * LTT_EVENT_THREAD_BRAND
1379 * </p>
1380 * <p>
1381 * FIELDS: LTT_FIELD_NAME
1382 * </p>
1383 *
1384 * @return
1385 */
1386 final IEventProcessing GetThreadBrandHandler() {
1387 AbsStateUpdate handler = new AbsStateUpdate() {
1388
1389 private Events eventType = Events.LTT_EVENT_THREAD_BRAND;
1390
1391 // @Override
1392 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1393
1394 String name;
1395 Long cpu = trcEvent.getCpuId();
1396 LttngProcessState process = traceSt.getRunning_process().get(
1397 cpu);
1398
1399 name = getAFieldString(trcEvent, traceSt, Fields.LTT_FIELD_NAME);
1400 process.setBrand(name);
1401 return false;
1402
1403 }
1404
1405 // @Override
1406 public Events getEventHandleType() {
1407 return eventType;
1408 }
1409 };
1410 return handler;
1411 }
1412
1413 /**
1414 * @return
1415 */
1416 final IEventProcessing getStateDumpEndHandler() {
1417 AbsStateUpdate handler = new AbsStateUpdate() {
1418
1419 private Events eventType = Events.LTT_EVENT_STATEDUMP_END;
1420
1421 // @Override
1422 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1423
1424 /* For all processes */
1425 /*
1426 * if kernel thread, if stack[0] is unknown, set to syscall
1427 * mode, wait
1428 */
1429 /* else, if stack[0] is unknown, set to user mode, running */
1430 LttngProcessState[] processes = traceSt.getProcesses();
1431 TmfTimestamp time = trcEvent.getTimestamp();
1432
1433 for (int pos = 0; pos < processes.length; pos++) {
1434 fix_process(processes[pos], time);
1435 }
1436
1437 return false;
1438
1439 }
1440
1441 // @Override
1442 public Events getEventHandleType() {
1443 return eventType;
1444 }
1445
1446 /**
1447 * Private method used to establish the first execution state in the
1448 * stack for a given process
1449 *
1450 * @param process
1451 * @param timestamp
1452 */
1453 private void fix_process(LttngProcessState process,
1454 TmfTimestamp timestamp) {
1455
1456 LttngExecutionState es;
1457
1458 if (process.getType() == ProcessType.LTTV_STATE_KERNEL_THREAD) {
1459 es = process.getFirstElementFromExecutionStack();
1460
1461 if (es.getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN) {
1462 es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL);
1463 es
1464 .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE
1465 .getInName());
1466 es.setEntry_Time(timestamp.getValue());
1467 es.setChange_Time(timestamp.getValue());
1468 es.setCum_cpu_time(0L);
1469 if (es.getProc_status() == ProcessStatus.LTTV_STATE_UNNAMED) {
1470 es.setProc_status(ProcessStatus.LTTV_STATE_WAIT);
1471 }
1472 }
1473 } else {
1474 es = process.getFirstElementFromExecutionStack();
1475 if (es.getExec_mode() == ExecutionMode.LTTV_STATE_MODE_UNKNOWN) {
1476 es.setExec_mode(ExecutionMode.LTTV_STATE_USER_MODE);
1477 es
1478 .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE
1479 .getInName());
1480 es.setEntry_Time(timestamp.getValue());
1481 es.setChange_Time(timestamp.getValue());
1482 es.setCum_cpu_time(0L);
1483 if (es.getProc_status() == ProcessStatus.LTTV_STATE_UNNAMED) {
1484 es.setProc_status(ProcessStatus.LTTV_STATE_RUN);
1485 }
1486
1487 // If the first element is also the one on top... mean
1488 // we have ONE element on the stack
1489 if (process.getFirstElementFromExecutionStack() == process
1490 .peekFromExecutionStack()) {
1491 /*
1492 * Still in bottom unknown mode, means never did a
1493 * system call May be either in user mode, syscall
1494 * mode, running or waiting.
1495 */
1496 /*
1497 * FIXME : we may be tagging syscall mode when being
1498 * user mode
1499 */
1500 // Get a new execution State
1501 es = new LttngExecutionState();
1502
1503 // initialize values
1504 es.setExec_mode(ExecutionMode.LTTV_STATE_SYSCALL);
1505 es
1506 .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_NONE
1507 .getInName());
1508 es.setEntry_Time(timestamp.getValue());
1509 es.setChange_Time(timestamp.getValue());
1510 es.setCum_cpu_time(0L);
1511 es.setProc_status(ProcessStatus.LTTV_STATE_WAIT);
1512
1513 // Push the new state to the stack
1514 process.pushToExecutionStack(es);
1515 }
1516 }
1517 }
1518 }
1519 };
1520 return handler;
1521 }
1522
1523 /**
1524 * <p>
1525 * Handles: LTT_EVENT_PROCESS_STATE
1526 * </p>
1527 * <p>
1528 * FIELDS: LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME,
1529 * LTT_FIELD_TYPE, LTT_FIELD_MODE, LTT_FIELD_SUBMODE, LTT_FIELD_STATUS,
1530 * LTT_FIELD_TGID
1531 * </p>
1532 *
1533 * @return
1534 */
1535 final IEventProcessing getEnumProcessStateHandler() {
1536 AbsStateUpdate handler = new AbsStateUpdate() {
1537
1538 private Events eventType = Events.LTT_EVENT_PROCESS_STATE;
1539
1540 // @Override
1541 public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
1542
1543 Long parent_pid;
1544 Long pid;
1545 Long tgid;
1546 String command;
1547 Long cpu = trcEvent.getCpuId();
1548
1549 LttngProcessState process = traceSt.getRunning_process().get(
1550 cpu);
1551 LttngProcessState parent_process;
1552 String type;
1553 // String mode, submode, status;
1554 LttngExecutionState es;
1555
1556 /* PID */
1557 pid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_PID);
1558
1559 /* Parent PID */
1560 parent_pid = getAFieldLong(trcEvent, traceSt,
1561 Fields.LTT_FIELD_PARENT_PID);
1562
1563 /* Command name */
1564 command = getAFieldString(trcEvent, traceSt,
1565 Fields.LTT_FIELD_NAME);
1566
1567 Long typeVal = getAFieldLong(trcEvent, traceSt,
1568 Fields.LTT_FIELD_TYPE);
1569
1570 type = ProcessType.LTTV_STATE_KERNEL_THREAD.getInName();
1571 if ((typeVal != null) && (typeVal.longValue() == 0L)) {
1572 type = ProcessType.LTTV_STATE_USER_THREAD.getInName();
1573 }
1574
1575 // /* mode */
1576 // mode = getAFieldString(trcEvent, traceSt,
1577 // Fields.LTT_FIELD_MODE);
1578 //
1579 // /* submode */
1580 // submode = getAFieldString(trcEvent, traceSt,
1581 // Fields.LTT_FIELD_SUBMODE);
1582 //
1583 // /* status */
1584 // status = getAFieldString(trcEvent, traceSt,
1585 // Fields.LTT_FIELD_STATUS);
1586
1587 /* TGID */
1588 tgid = getAFieldLong(trcEvent, traceSt, Fields.LTT_FIELD_TGID);
1589 if (tgid == null) {
1590 tgid = 0L;
1591 }
1592
1593 if ((pid != null) && (pid.longValue() == 0L)) {
1594 for (Long acpu : traceSt.getCpu_states().keySet()) {
1595 process = lttv_state_find_process(traceSt, acpu, pid);
1596 if (process != null) {
1597 process.setPpid(parent_pid);
1598 process.setTgid(tgid);
1599 process.setName(command);
1600 process
1601 .setType(ProcessType.LTTV_STATE_KERNEL_THREAD);
1602 } else {
1603 StringBuilder sb = new StringBuilder(
1604 "Unexpected, null process read from the TraceState list of processes, event time: "
1605 + trcEvent.getTimestamp());
1606 TraceDebug.debug(sb.toString());
1607 }
1608 }
1609 } else {
1610 /*
1611 * The process might exist if a process was forked while
1612 * performing the state dump.
1613 */
1614 process = lttv_state_find_process(traceSt, ANY_CPU, pid);
1615 if (process == null) {
1616 parent_process = lttv_state_find_process(traceSt,
1617 ANY_CPU, parent_pid);
1618 TmfTimestamp eventTime = trcEvent.getTimestamp();
1619 process = create_process(traceSt, cpu, pid, tgid,
1620 command, eventTime);
1621 if (parent_process != null) {
1622 process.setPpid(parent_process.getPid(), eventTime.getValue());
1623 }
1624
1625 /* Keep the stack bottom : a running user mode */
1626 /*
1627 * Disabled because of inconsistencies in the current
1628 * statedump states.
1629 */
1630 if (type.equals(ProcessType.LTTV_STATE_KERNEL_THREAD
1631 .getInName())) {
1632 /*
1633 * FIXME Kernel thread : can be in syscall or
1634 * interrupt or trap.
1635 */
1636 /*
1637 * Will cause expected trap when in fact being
1638 * syscall (even after end of statedump event) Will
1639 * cause expected interrupt when being syscall.
1640 * (only before end of statedump event)
1641 */
1642 // process type is USER_THREAD by default.
1643 process
1644 .setType(ProcessType.LTTV_STATE_KERNEL_THREAD);
1645
1646 }
1647
1648 //Only one entry needed in the execution stack
1649 process.popFromExecutionStack();
1650 es = process.getState();
1651 es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN);
1652 es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED);
1653 es
1654 .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN
1655 .getInName());
1656 // #if 0
1657 // /* UNKNOWN STATE */
1658 // {
1659 // es = process->state =
1660 // &g_array_index(process->execution_stack,
1661 // LttvExecutionState, 1);
1662 // es->t = LTTV_STATE_MODE_UNKNOWN;
1663 // es->s = LTTV_STATE_UNNAMED;
1664 // es->n = LTTV_STATE_SUBMODE_UNKNOWN;
1665 // }
1666 // #endif //0
1667 } else {
1668 /*
1669 * The process has already been created : Probably was
1670 * forked while dumping the process state or was simply
1671 * scheduled in prior to get the state dump event.
1672 */
1673 process.setPpid(parent_pid);
1674 process.setTgid(tgid);
1675 process.setName(command);
1676 if (type.equals(ProcessType.LTTV_STATE_KERNEL_THREAD
1677 .getInName())) {
1678 process
1679 .setType(ProcessType.LTTV_STATE_KERNEL_THREAD);
1680 } else {
1681 process.setType(ProcessType.LTTV_STATE_USER_THREAD);
1682 }
1683
1684 // es =
1685 // &g_array_index(process->execution_stack,
1686 // LttvExecutionState,
1687 // 0);
1688 // #if 0
1689 // if(es->t == LTTV_STATE_MODE_UNKNOWN) {
1690 // if(type == LTTV_STATE_KERNEL_THREAD)
1691 // es->t = LTTV_STATE_SYSCALL;
1692 // else
1693 // es->t = LTTV_STATE_USER_MODE;
1694 // }
1695 // #endif //0
1696 /*
1697 * Don't mess around with the stack, it will eventually
1698 * become ok after the end of state dump.
1699 */
1700 }
1701 }
1702
1703 return false;
1704
1705 }
1706
1707 // @Override
1708 public Events getEventHandleType() {
1709 return eventType;
1710 }
1711 };
1712 return handler;
1713 }
1714
1715 }
This page took 0.069702 seconds and 5 git commands to generate.