1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
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
10 * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.state
;
14 import java
.util
.List
;
17 import org
.eclipse
.linuxtools
.lttng
.TraceDebug
;
18 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
19 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
;
20 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.BdevMode
;
21 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.CpuMode
;
22 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.Events
;
23 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ExecutionMode
;
24 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ExecutionSubMode
;
25 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.Fields
;
26 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.IRQMode
;
27 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ProcessStatus
;
28 import org
.eclipse
.linuxtools
.lttng
.state
.StateStrings
.ProcessType
;
29 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.IEventProcessing
;
30 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LTTngCPUState
;
31 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngBdevState
;
32 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngExecutionState
;
33 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngIRQState
;
34 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngProcessState
;
35 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngSoftIRQState
;
36 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngTraceState
;
37 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngTrapState
;
38 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimestamp
;
41 * Wraps the creation of individual handlers, each method creates and instance
42 * of the corresponding handler
47 class StateUpdateHandlers
{
49 final IEventProcessing
getSyscallEntryHandler() {
50 AbsStateUpdate handler
= new AbsStateUpdate() {
52 private Events eventType
= Events
.LTT_EVENT_SYSCALL_ENTRY
;
55 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
57 Long cpu
= trcEvent
.getCpuId();
59 // No syscall_entry update for initialization process
60 LttngProcessState process
= traceSt
.getRunning_process().get(
62 if ((process
!= null) && (process
.getPid() != null)
63 && (process
.getPid().longValue() == 0L)) {
67 // Get the expected event field
68 Long syscall
= getAFieldLong(trcEvent
, traceSt
,
69 Fields
.LTT_FIELD_SYSCALL_ID
);
71 String submode
= null;
72 if (syscall
== null) {
74 .debug("Syscall Field not found, traceVent time: "
75 + trcEvent
.getTimestamp());
77 submode
= traceSt
.getSyscall_names().get(syscall
);
80 if (submode
== null) {
81 submode
= ExecutionSubMode
.LTTV_STATE_SUBMODE_UNKNOWN
85 push_state(cpu
, StateStrings
.ExecutionMode
.LTTV_STATE_SYSCALL
,
86 submode
, trcEvent
.getTimestamp(), traceSt
);
91 public Events
getEventHandleType() {
98 final IEventProcessing
getsySyscallExitHandler() {
99 AbsStateUpdate handler
= new AbsStateUpdate() {
101 private Events eventType
= Events
.LTT_EVENT_SYSCALL_EXIT
;
104 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
106 Long cpu
= trcEvent
.getCpuId();
107 LttngProcessState process
= traceSt
.getRunning_process().get(
110 // No syscall_entry update for initialization process
111 if ((process
!= null) && (process
.getPid() != null)
112 && (process
.getPid().longValue() == 0L)) {
116 pop_state(cpu
, StateStrings
.ExecutionMode
.LTTV_STATE_SYSCALL
,
117 traceSt
, trcEvent
.getTimestamp());
123 public Events
getEventHandleType() {
131 * Update stacks related to the parsing of an LttngEvent
135 final IEventProcessing
getTrapEntryHandler() {
136 AbsStateUpdate handler
= new AbsStateUpdate() {
138 private Events eventType
= Events
.LTT_EVENT_TRAP_ENTRY
;
141 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
142 Long cpu
= trcEvent
.getCpuId();
144 Long trap
= getAFieldLong(trcEvent
, traceSt
,
145 Fields
.LTT_FIELD_TRAP_ID
);
148 .debug("Trap field could not be found, event time: "
149 + trcEvent
.getTimestamp());
153 // ready the trap submode name
154 String submode
= traceSt
.getTrap_names().get(trap
);
156 if (submode
== null) {
157 submode
= ExecutionSubMode
.LTTV_STATE_SUBMODE_UNKNOWN
161 /* update process state */
162 push_state(cpu
, StateStrings
.ExecutionMode
.LTTV_STATE_TRAP
,
163 submode
, trcEvent
.getTimestamp(), traceSt
);
165 /* update cpu status */
166 LTTngCPUState cpust
= traceSt
.getCpu_states().get(cpu
);
167 cpu_push_mode(cpust
, StateStrings
.CpuMode
.LTTV_CPU_TRAP
);
168 cpust
.pushToTrapStack(trap
); /* update trap status */
171 LttngTrapState trap_state
= traceSt
.getTrap_states().get(trap
);
172 trap_state
.incrementRunning();
179 public Events
getEventHandleType() {
190 final IEventProcessing
getTrapExitHandler() {
191 AbsStateUpdate handler
= new AbsStateUpdate() {
193 private Events eventType
= Events
.LTT_EVENT_TRAP_EXIT
;
196 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
198 Long cpu
= trcEvent
.getCpuId();
199 LTTngCPUState cpust
= traceSt
.getCpu_states().get(cpu
);
200 Long trap
= cpust
.popFromTrapStack();
202 /* update process state */
203 pop_state(cpu
, ExecutionMode
.LTTV_STATE_TRAP
, traceSt
, trcEvent
206 /* update cpu status */
210 traceSt
.getTrap_states().get(trap
).decrementRunning();
213 // TraceDebug.debug("remove this line");
221 public Events
getEventHandleType() {
232 final IEventProcessing
getIrqEntryHandler() {
233 AbsStateUpdate handler
= new AbsStateUpdate() {
235 private Events eventType
= Events
.LTT_EVENT_IRQ_ENTRY
;
238 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
240 Long cpu
= trcEvent
.getCpuId();
242 Long irq
= getAFieldLong(trcEvent
, traceSt
,
243 Fields
.LTT_FIELD_IRQ_ID
);
249 submode
= traceSt
.getIrq_names().get(irq
);
251 if (submode
== null) {
252 submode
= ExecutionSubMode
.LTTV_STATE_SUBMODE_UNKNOWN
257 * Do something with the info about being in user or system mode
260 push_state(cpu
, ExecutionMode
.LTTV_STATE_IRQ
, submode
, trcEvent
261 .getTimestamp(), traceSt
);
263 /* update cpu state */
264 LTTngCPUState cpust
= traceSt
.getCpu_states().get(cpu
);
265 cpu_push_mode(cpust
, CpuMode
.LTTV_CPU_IRQ
); /* mode stack */
266 cpust
.pushToIrqStack(irq
); /* last irq */
268 /* udpate irq state */
269 irq_push_mode(traceSt
.getIrq_states().get(irq
),
270 IRQMode
.LTTV_IRQ_BUSY
);
275 public Events
getEventHandleType() {
286 final IEventProcessing
getSoftIrqExitHandler() {
287 AbsStateUpdate handler
= new AbsStateUpdate() {
289 private Events eventType
= Events
.LTT_EVENT_SOFT_IRQ_EXIT
;
292 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
294 Long cpu
= trcEvent
.getCpuId();
295 LTTngCPUState cpust
= traceSt
.getCpu_states().get(cpu
);
296 Long softirq
= cpust
.popFromSoftIrqStack();
298 // Update process status
299 pop_state(cpu
, ExecutionMode
.LTTV_STATE_SOFT_IRQ
, traceSt
,
300 trcEvent
.getTimestamp());
302 /* update softirq status */
304 LttngSoftIRQState softIrqstate
= traceSt
305 .getSoft_irq_states().get(softirq
);
306 softIrqstate
.decrementRunning();
309 /* update cpu status */
316 public Events
getEventHandleType() {
327 final IEventProcessing
getIrqExitHandler() {
328 AbsStateUpdate handler
= new AbsStateUpdate() {
330 private Events eventType
= Events
.LTT_EVENT_IRQ_EXIT
;
333 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
335 Long cpu
= trcEvent
.getCpuId();
337 /* update process state */
338 pop_state(cpu
, ExecutionMode
.LTTV_STATE_IRQ
, traceSt
, trcEvent
341 /* update cpu status */
342 LTTngCPUState cpust
= traceSt
.getCpu_states().get(cpu
);
345 /* update irq status */
346 Long last_irq
= cpust
.popFromIrqStack();
347 if (last_irq
!= -1L) {
348 LttngIRQState irq_state
= traceSt
.getIrq_states().get(
350 irq_pop_mode(irq_state
);
358 public Events
getEventHandleType() {
369 final IEventProcessing
getSoftIrqRaiseHandler() {
370 AbsStateUpdate handler
= new AbsStateUpdate() {
372 private Events eventType
= Events
.LTT_EVENT_SOFT_IRQ_RAISE
;
375 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
377 // Long cpu = trcEvent.getCpuId();
380 Long softirq
= getAFieldLong(trcEvent
, traceSt
,
381 Fields
.LTT_FIELD_SOFT_IRQ_ID
);
383 if (softirq
== null) {
384 TraceDebug
.debug("Soft_irq_id not found in "
385 + eventType
.getInName() + " time: "
386 + trcEvent
.getTimestamp());
391 // String[] softIrqNames = traceSt.getSoft_irq_names();
392 // if (softirq < softIrqNames.length) {
393 // submode = softIrqNames[softirq];
395 // submode = "softirq " + softirq;
398 /* update softirq status */
399 /* a soft irq raises are not cumulative */
400 LttngSoftIRQState irqState
= traceSt
.getSoft_irq_states().get(
402 if (irqState
!= null) {
403 irqState
.setPending(1L);
406 .debug("unexpected soft irq id value: " + softirq
);
414 public Events
getEventHandleType() {
425 final IEventProcessing
getSoftIrqEntryHandler() {
426 AbsStateUpdate handler
= new AbsStateUpdate() {
428 private Events eventType
= Events
.LTT_EVENT_SOFT_IRQ_ENTRY
;
431 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
434 Long cpu
= trcEvent
.getCpuId();
437 Long softirq
= getAFieldLong(trcEvent
, traceSt
,
438 Fields
.LTT_FIELD_SOFT_IRQ_ID
);
440 if (softirq
== null) {
441 TraceDebug
.debug("Soft IRQ ID not found, eventTime: "
442 + trcEvent
.getTimestamp());
447 Map
<Long
, String
> softIrqNames
= traceSt
.getSoft_irq_names();
448 String submode
= softIrqNames
.get(softirq
);
449 if (submode
== null) {
450 submode
= "softirq " + softirq
;
451 softIrqNames
.put(softirq
, submode
);
454 /* update softirq status */
455 LttngSoftIRQState irqState
= traceSt
.getSoft_irq_states().get(
457 if (irqState
!= null) {
458 irqState
.decrementPending();
459 irqState
.incrementRunning();
462 .debug("unexpected soft irq id value: " + softirq
);
465 /* update cpu state */
466 LTTngCPUState cpu_state
= traceSt
.getCpu_states().get(cpu
);
467 cpu_state
.pushToSoftIrqStack(softirq
);
468 cpu_push_mode(cpu_state
, CpuMode
.LTTV_CPU_SOFT_IRQ
);
470 /* update process execution mode state stack */
471 push_state(cpu
, ExecutionMode
.LTTV_STATE_SOFT_IRQ
, submode
,
472 trcEvent
.getTimestamp(), traceSt
);
479 public Events
getEventHandleType() {
487 * Method to handle the event: LTT_EVENT_LIST_INTERRRUPT
491 final IEventProcessing
getEnumInterruptHandler() {
492 AbsStateUpdate handler
= new AbsStateUpdate() {
494 private Events eventType
= Events
.LTT_EVENT_LIST_INTERRUPT
;
497 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
498 String action
= getAFieldString(trcEvent
, traceSt
,
499 Fields
.LTT_FIELD_ACTION
);
500 Long irq
= getAFieldLong(trcEvent
, traceSt
,
501 Fields
.LTT_FIELD_IRQ_ID
);
503 if (action
!= null) {
504 TraceDebug
.debug("Field Action not found in event "
505 + eventType
.getInName() + " time: "
506 + trcEvent
.getTimestamp());
511 TraceDebug
.debug("Field irq_id not found in event "
512 + eventType
.getInName() + " time: "
513 + trcEvent
.getTimestamp());
517 Map
<Long
, String
> irq_names
= traceSt
.getIrq_names();
519 irq_names
.put(irq
, action
);
525 public Events
getEventHandleType() {
533 * Handle the event LTT_EVENT_REQUEST_ISSUE
537 final IEventProcessing
getBdevRequestIssueHandler() {
538 AbsStateUpdate handler
= new AbsStateUpdate() {
540 private Events eventType
= Events
.LTT_EVENT_REQUEST_ISSUE
;
543 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
546 Long major
= getAFieldLong(trcEvent
, traceSt
,
547 Fields
.LTT_FIELD_MAJOR
);
548 Long minor
= getAFieldLong(trcEvent
, traceSt
,
549 Fields
.LTT_FIELD_MINOR
);
550 Long operation
= getAFieldLong(trcEvent
, traceSt
,
551 Fields
.LTT_FIELD_OPERATION
);
553 // calculate bdevcode
554 Long devcode
= mkdev(major
, minor
);
556 if (devcode
== null) {
558 .debug("incorrect calcualtion of bdevcode input( major: "
562 + " operation: " + operation
);
566 Map
<Long
, LttngBdevState
> bdev_states
= traceSt
569 LttngBdevState bdevState
= bdev_states
.get(devcode
);
570 if (bdevState
== null) {
571 bdevState
= new LttngBdevState();
574 // update the mode in the stack
575 if (operation
== 0L) {
576 bdevState
.pushToBdevStack(BdevMode
.LTTV_BDEV_BUSY_READING
);
578 bdevState
.pushToBdevStack(BdevMode
.LTTV_BDEV_BUSY_WRITING
);
581 // make sure it is included in the set
582 bdev_states
.put(devcode
, bdevState
);
588 public Events
getEventHandleType() {
597 * Handling event: LTT_EVENT_REQUEST_COMPLETE
600 * FIELDS(LTT_FIELD_MAJOR, LTT_FIELD_MINOR, LTT_FIELD_OPERATION
605 final IEventProcessing
getBdevRequestCompleteHandler() {
606 AbsStateUpdate handler
= new AbsStateUpdate() {
608 private Events eventType
= Events
.LTT_EVENT_REQUEST_COMPLETE
;
611 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
614 Long major
= getAFieldLong(trcEvent
, traceSt
,
615 Fields
.LTT_FIELD_MAJOR
);
616 Long minor
= getAFieldLong(trcEvent
, traceSt
,
617 Fields
.LTT_FIELD_MINOR
);
618 Long operation
= getAFieldLong(trcEvent
, traceSt
,
619 Fields
.LTT_FIELD_OPERATION
);
621 // calculate bdevcode
622 Long devcode
= mkdev(major
, minor
);
624 if (devcode
== null) {
626 .debug("incorrect calcualtion of bdevcode input( major: "
630 + " operation: " + operation
);
634 Map
<Long
, LttngBdevState
> bdev_states
= traceSt
637 LttngBdevState bdevState
= bdev_states
.get(devcode
);
638 if (bdevState
== null) {
639 bdevState
= new LttngBdevState();
642 /* update block device */
643 bdev_pop_mode(bdevState
);
650 public Events
getEventHandleType() {
659 * Handles event: LTT_EVENT_FUNCTION_ENTRY
662 * FIELDS: LTT_FIELD_THIS_FN, LTT_FIELD_CALL_SITE
667 final IEventProcessing
getFunctionEntryHandler() {
668 AbsStateUpdate handler
= new AbsStateUpdate() {
670 private Events eventType
= Events
.LTT_EVENT_FUNCTION_ENTRY
;
673 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
674 Long cpu
= trcEvent
.getCpuId();
675 Long funcptr
= getAFieldLong(trcEvent
, traceSt
,
676 Fields
.LTT_FIELD_THIS_FN
);
678 push_function(traceSt
, funcptr
, cpu
);
684 public Events
getEventHandleType() {
695 final IEventProcessing
getFunctionExitHandler() {
696 AbsStateUpdate handler
= new AbsStateUpdate() {
698 private Events eventType
= Events
.LTT_EVENT_FUNCTION_EXIT
;
701 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
703 Long funcptr
= getAFieldLong(trcEvent
, traceSt
,
704 Fields
.LTT_FIELD_THIS_FN
);
706 pop_function(traceSt
, trcEvent
, funcptr
);
712 public Events
getEventHandleType() {
721 * process event: LTT_EVENT_SYS_CALL_TABLE
724 * fields: LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL
729 final IEventProcessing
getDumpSyscallHandler() {
730 AbsStateUpdate handler
= new AbsStateUpdate() {
732 private Events eventType
= Events
.LTT_EVENT_SYS_CALL_TABLE
;
735 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
736 // obtain the syscall id
737 Long id
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_ID
);
739 // Long address = getAFieldLong(trcEvent, traceSt,
740 // Fields.LTT_FIELD_ADDRESS);
743 String symbol
= getAFieldString(trcEvent
, traceSt
,
744 Fields
.LTT_FIELD_SYMBOL
);
746 // fill the symbol to the sycall_names collection
747 traceSt
.getSyscall_names().put(id
, symbol
);
753 public Events
getEventHandleType() {
762 * Handles event: LTT_EVENT_KPROBE_TABLE
765 * Fields: LTT_FIELD_IP, LTT_FIELD_SYMBOL
770 final IEventProcessing
getDumpKprobeHandler() {
771 AbsStateUpdate handler
= new AbsStateUpdate() {
773 private Events eventType
= Events
.LTT_EVENT_KPROBE_TABLE
;
776 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
778 Long ip
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_IP
);
779 String symbol
= getAFieldString(trcEvent
, traceSt
,
780 Fields
.LTT_FIELD_SYMBOL
);
782 traceSt
.getKprobe_table().put(ip
, symbol
);
789 public Events
getEventHandleType() {
798 * Handles: LTT_EVENT_SOFTIRQ_VEC
801 * Fields: LTT_FIELD_ID, LTT_FIELD_ADDRESS, LTT_FIELD_SYMBOL
806 final IEventProcessing
getDumpSoftIrqHandler() {
807 AbsStateUpdate handler
= new AbsStateUpdate() {
809 private Events eventType
= Events
.LTT_EVENT_SOFTIRQ_VEC
;
812 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
815 Long id
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_ID
);
817 // Address not needed
818 // Long address = ltt_event_get_long_unsigned(e,
819 // lttv_trace_get_hook_field(th,
823 String symbol
= getAFieldString(trcEvent
, traceSt
,
824 Fields
.LTT_FIELD_SYMBOL
);
826 // Register the soft irq name
827 traceSt
.getSoft_irq_names().put(id
, symbol
);
833 public Events
getEventHandleType() {
842 * Handles: LTT_EVENT_SCHED_SCHEDULE
845 * Fields: LTT_FIELD_PREV_PID, LTT_FIELD_NEXT_PID, LTT_FIELD_PREV_STATE
850 final IEventProcessing
getSchedChangeHandler() {
851 AbsStateUpdate handler
= new AbsStateUpdate() {
853 private Events eventType
= Events
.LTT_EVENT_SCHED_SCHEDULE
;
856 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
858 Long cpu
= trcEvent
.getCpuId();
859 TmfTimestamp eventTime
= trcEvent
.getTimestamp();
861 LttngProcessState process
= traceSt
.getRunning_process().get(
864 Long pid_out
= getAFieldLong(trcEvent
, traceSt
,
865 Fields
.LTT_FIELD_PREV_PID
);
866 Long pid_in
= getAFieldLong(trcEvent
, traceSt
,
867 Fields
.LTT_FIELD_NEXT_PID
);
868 Long state_out
= getAFieldLong(trcEvent
, traceSt
,
869 Fields
.LTT_FIELD_PREV_STATE
);
871 if (process
!= null) {
874 * We could not know but it was not the idle process
875 * executing. This should only happen at the beginning,
876 * before the first schedule event, and when the initial
877 * information (current process for each CPU) is missing. It
878 * is not obvious how we could, after the fact, compensate
879 * the wrongly attributed statistics.
882 // This test only makes sense once the state is known and if
885 // missing events. We need to silently ignore schedchange
888 // process_free, or it causes glitches. (FIXME)
889 // if(unlikely(process->pid != pid_out)) {
890 // g_assert(process->pid == 0);
892 if ((process
.getPid().longValue() == 0L)
893 && (process
.getState().getExec_mode() == ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
)) {
894 if ((pid_out
!= null) && (pid_out
.longValue() == 0L)) {
896 * Scheduling out of pid 0 at beginning of the trace
897 * : we know for sure it is in syscall mode at this
901 process
.getState().setExec_mode(
902 ExecutionMode
.LTTV_STATE_SYSCALL
);
903 process
.getState().setProc_status(
904 ProcessStatus
.LTTV_STATE_WAIT
);
905 process
.getState().setChange_Time(
906 trcEvent
.getTimestamp());
907 process
.getState().setEntry_Time(
908 trcEvent
.getTimestamp());
911 if (process
.getState().getProc_status() == ProcessStatus
.LTTV_STATE_EXIT
) {
912 process
.getState().setProc_status(
913 ProcessStatus
.LTTV_STATE_ZOMBIE
);
914 process
.getState().setChange_Time(
915 trcEvent
.getTimestamp());
917 if ((state_out
!= null)
918 && (state_out
.longValue() == 0L)) {
919 process
.getState().setProc_status(
920 ProcessStatus
.LTTV_STATE_WAIT_CPU
);
922 process
.getState().setProc_status(
923 ProcessStatus
.LTTV_STATE_WAIT
);
926 process
.getState().setChange_Time(
927 trcEvent
.getTimestamp());
930 if ((state_out
!= null)
931 && (state_out
== 32L || state_out
== 64L)) { /*
936 /* see sched.h for states */
937 if (!exit_process(traceSt
, process
)) {
938 process
.getState().setProc_status(
939 ProcessStatus
.LTTV_STATE_DEAD
);
940 process
.getState().setChange_Time(
941 trcEvent
.getTimestamp());
946 process
= lttv_state_find_process_or_create(traceSt
, cpu
,
949 traceSt
.getRunning_process().put(cpu
, process
);
951 process
.getState().setProc_status(ProcessStatus
.LTTV_STATE_RUN
);
952 process
.getState().setChange_Time(eventTime
);
954 // process->state->s = LTTV_STATE_RUN;
955 // if(process->usertrace)
956 // process->usertrace->cpu = cpu;
957 // process->last_cpu_index =
958 // ltt_tracefile_num(((LttvTracefileContext*)s)->tf);
960 // process->state->change = s->parent.timestamp;
962 LTTngCPUState cpu_state
= traceSt
.getCpu_states().get(cpu
);
963 /* update cpu status */
964 if ((pid_in
!= null) && (pid_in
.longValue() == 0L)) {
966 /* going to idle task */
967 cpu_set_base_mode(cpu_state
, CpuMode
.LTTV_CPU_IDLE
);
970 * scheduling a real task. we must be careful here: if we
971 * just schedule()'ed to a process that is in a trap, we
972 * must put the cpu in trap mode
974 cpu_set_base_mode(cpu_state
, CpuMode
.LTTV_CPU_BUSY
);
975 if (process
.getState().getExec_mode() == ExecutionMode
.LTTV_STATE_TRAP
) {
976 cpu_push_mode(cpu_state
, CpuMode
.LTTV_CPU_TRAP
);
984 public Events
getEventHandleType() {
993 * Handles: LTT_EVENT_PROCESS_FORK
996 * Fields: FIELD_ARRAY(LTT_FIELD_PARENT_PID, LTT_FIELD_CHILD_PID,
997 * LTT_FIELD_CHILD_TGID)
1002 final IEventProcessing
getProcessForkHandler() {
1003 AbsStateUpdate handler
= new AbsStateUpdate() {
1005 private Events eventType
= Events
.LTT_EVENT_PROCESS_FORK
;
1008 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
1010 Long cpu
= trcEvent
.getCpuId();
1011 LttngProcessState process
= traceSt
.getRunning_process().get(
1013 TmfTimestamp timeStamp
= trcEvent
.getTimestamp();
1016 // Long parent_pid = getAFieldLong(trcEvent, traceSt,
1017 // Fields.LTT_FIELD_PARENT_PID);
1020 /* In the Linux Kernel, there is one PID per thread. */
1021 Long child_pid
= getAFieldLong(trcEvent
, traceSt
,
1022 Fields
.LTT_FIELD_CHILD_PID
);
1025 /* tgid in the Linux kernel is the "real" POSIX PID. */
1026 Long child_tgid
= getAFieldLong(trcEvent
, traceSt
,
1027 Fields
.LTT_FIELD_CHILD_TGID
);
1028 if (child_tgid
== null) {
1033 * Mathieu : it seems like the process might have been scheduled
1034 * in before the fork, and, in a rare case, might be the current
1035 * process. This might happen in a SMP case where we don't have
1036 * enough precision on the clocks.
1038 * Test reenabled after precision fixes on time. (Mathieu)
1041 // zombie_process = lttv_state_find_process(ts, ANY_CPU,
1044 // if(unlikely(zombie_process != NULL)) {
1045 // /* Reutilisation of PID. Only now we are sure that the old
1047 // * has been released. FIXME : should know when release_task
1051 // guint num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
1053 // for(i=0; i< num_cpus; i++) {
1054 // g_assert(zombie_process != ts->running_process[i]);
1057 // exit_process(s, zombie_process);
1061 if (process
.getPid().equals(child_pid
)) {
1063 .debug("Unexpected, process pid equal to child pid: "
1066 + trcEvent
.getTimestamp());
1069 // g_assert(process->pid != child_pid);
1070 // FIXME : Add this test in the "known state" section
1071 // g_assert(process->pid == parent_pid);
1072 LttngProcessState child_process
= lttv_state_find_process(
1073 traceSt
, ANY_CPU
, child_pid
);
1074 if (child_process
== null) {
1075 child_process
= create_process(traceSt
, cpu
, child_pid
,
1076 child_tgid
, timeStamp
);
1077 child_process
.setPpid(process
.getPid(), timeStamp
);
1080 * The process has already been created : due to time
1081 * imprecision between multiple CPUs : it has been scheduled
1082 * in before creation. Note that we shouldn't have this kind
1085 * Simply put a correct parent.
1087 StringBuilder sb
= new StringBuilder("Process " + child_pid
);
1088 sb
.append(" has been created at ["
1089 + child_process
.getCreation_time() + "] ");
1090 sb
.append("and inserted at ["
1091 + child_process
.getInsertion_time() + "] ");
1092 sb
.append("before \nfork on cpu " + cpu
+ " Event time: ["
1093 + trcEvent
+ "]\n.");
1095 .append("Probably an unsynchronized TSD problem on the traced machine.");
1096 TraceDebug
.debug(sb
.toString());
1098 // g_assert(0); /* This is a problematic case : the process
1101 // before the fork event */
1102 child_process
.setPpid(process
.getPid());
1103 child_process
.setTgid(child_tgid
);
1106 if (!child_process
.getName().equals(
1107 ProcessStatus
.LTTV_STATE_UNNAMED
.getInName())) {
1108 TraceDebug
.debug("Unexpected child process status: "
1109 + child_process
.getName());
1112 child_process
.setName(process
.getName());
1113 child_process
.setBrand(process
.getBrand());
1120 public Events
getEventHandleType() {
1129 * Handles: LTT_EVENT_KTHREAD_CREATE
1132 * Fields: LTT_FIELD_PID
1137 final IEventProcessing
getProcessKernelThreadHandler() {
1138 AbsStateUpdate handler
= new AbsStateUpdate() {
1140 private Events eventType
= Events
.LTT_EVENT_KTHREAD_CREATE
;
1143 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
1145 * We stamp a newly created process as kernel_thread. The thread
1146 * should not be running yet.
1149 LttngExecutionState exState
;
1151 LttngProcessState process
;
1154 pid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_PID
);
1155 // s->parent.target_pid = pid;
1157 process
= lttv_state_find_process_or_create(traceSt
, ANY_CPU
,
1158 pid
, new TmfTimestamp());
1160 if (!process
.getState().getProc_status().equals(
1161 ProcessStatus
.LTTV_STATE_DEAD
)) {
1162 // Leave only the first element in the stack with execution
1165 exState
= process
.getFirstElementFromExecutionStack();
1166 exState
.setExec_mode(ExecutionMode
.LTTV_STATE_SYSCALL
);
1167 process
.clearExecutionStack();
1168 process
.pushToExecutionStack(exState
);
1170 // update the process state to the only one in the stack
1171 process
.setState(exState
);
1174 process
.setType(ProcessType
.LTTV_STATE_KERNEL_THREAD
);
1181 public Events
getEventHandleType() {
1190 * Handles: LTT_EVENT_PROCESS_EXIT
1198 final IEventProcessing
getProcessExitHandler() {
1199 AbsStateUpdate handler
= new AbsStateUpdate() {
1201 private Events eventType
= Events
.LTT_EVENT_PROCESS_EXIT
;
1204 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
1207 LttngProcessState process
;
1209 pid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_PID
);
1210 // s->parent.target_pid = pid;
1212 // FIXME : Add this test in the "known state" section
1213 // g_assert(process->pid == pid);
1215 process
= lttv_state_find_process(traceSt
, ANY_CPU
, pid
);
1216 if (process
!= null) {
1217 process
.getState().setProc_status(
1218 ProcessStatus
.LTTV_STATE_EXIT
);
1225 public Events
getEventHandleType() {
1234 * Handles: LTT_EVENT_PROCESS_FREE
1237 * Fields: LTT_FIELD_PID
1242 final IEventProcessing
getProcessFreeHandler() {
1243 AbsStateUpdate handler
= new AbsStateUpdate() {
1245 private Events eventType
= Events
.LTT_EVENT_PROCESS_FREE
;
1248 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
1251 LttngProcessState process
;
1253 /* PID of the process to release */
1254 release_pid
= getAFieldLong(trcEvent
, traceSt
,
1255 Fields
.LTT_FIELD_PID
);
1256 // s->parent.target_pid = release_pid;
1258 if ((release_pid
!= null) && (release_pid
.longValue() == 0L)) {
1259 TraceDebug
.debug("Unexpected release_pid: 0, Event time: "
1260 + trcEvent
.getTimestamp());
1263 process
= lttv_state_find_process(traceSt
, ANY_CPU
, release_pid
);
1264 if (process
!= null) {
1265 exit_process(traceSt
, process
);
1270 // if(process != null) {
1272 * release_task is happening at kernel level : we can now safely
1273 * release the data structure of the process
1275 // This test is fun, though, as it may happen that
1276 // at time t : CPU 0 : process_free
1277 // at time t+150ns : CPU 1 : schedule out
1278 // Clearly due to time imprecision, we disable it. (Mathieu)
1279 // If this weird case happen, we have no choice but to put the
1280 // Currently running process on the cpu to 0.
1281 // I re-enable it following time precision fixes. (Mathieu)
1282 // Well, in the case where an process is freed by a process on
1285 // and still scheduled, it happens that this is the schedchange
1288 // drop the last reference count. Do not free it here!
1290 // int num_cpus = ltt_trace_get_num_cpu(ts->parent.t);
1292 // for(i=0; i< num_cpus; i++) {
1293 // //g_assert(process != ts->running_process[i]);
1294 // if(process == ts->running_process[i]) {
1295 // //ts->running_process[i] = lttv_state_find_process(ts, i, 0);
1299 // if(i == num_cpus) /* process is not scheduled */
1300 // exit_process(s, process);
1308 public Events
getEventHandleType() {
1317 * Handles: LTT_EVENT_EXEC
1320 * FIELDS: LTT_FIELD_FILENAME
1325 final IEventProcessing
getProcessExecHandler() {
1326 AbsStateUpdate handler
= new AbsStateUpdate() {
1328 private Events eventType
= Events
.LTT_EVENT_EXEC
;
1331 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
1333 Long cpu
= trcEvent
.getCpuId();
1334 LttngProcessState process
= traceSt
.getRunning_process().get(
1337 // #if 0//how to use a sequence that must be transformed in a
1339 // /* PID of the process to release */
1340 // guint64 name_len = ltt_event_field_element_number(e,
1341 // lttv_trace_get_hook_field(th, 0));
1342 // //name = ltt_event_get_string(e,
1343 // lttv_trace_get_hook_field(th, 0));
1344 // LttField *child = ltt_event_field_element_select(e,
1345 // lttv_trace_get_hook_field(th, 0), 0);
1346 // gchar *name_begin =
1347 // (gchar*)(ltt_event_data(e)+ltt_event_field_offset(e, child));
1348 // gchar *null_term_name = g_new(gchar, name_len+1);
1349 // memcpy(null_term_name, name_begin, name_len);
1350 // null_term_name[name_len] = '\0';
1351 // process->name = g_quark_from_string(null_term_name);
1354 process
.setName(getAFieldString(trcEvent
, traceSt
,
1355 Fields
.LTT_FIELD_FILENAME
));
1356 process
.setBrand(StateStrings
.LTTV_STATE_UNBRANDED
);
1362 public Events
getEventHandleType() {
1371 * LTT_EVENT_THREAD_BRAND
1374 * FIELDS: LTT_FIELD_NAME
1379 final IEventProcessing
GetThreadBrandHandler() {
1380 AbsStateUpdate handler
= new AbsStateUpdate() {
1382 private Events eventType
= Events
.LTT_EVENT_THREAD_BRAND
;
1385 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
1388 Long cpu
= trcEvent
.getCpuId();
1389 LttngProcessState process
= traceSt
.getRunning_process().get(
1392 name
= getAFieldString(trcEvent
, traceSt
, Fields
.LTT_FIELD_NAME
);
1393 process
.setBrand(name
);
1399 public Events
getEventHandleType() {
1409 final IEventProcessing
getStateDumpEndHandler() {
1410 AbsStateUpdate handler
= new AbsStateUpdate() {
1412 private Events eventType
= Events
.LTT_EVENT_STATEDUMP_END
;
1415 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
1417 /* For all processes */
1419 * if kernel thread, if stack[0] is unknown, set to syscall
1422 /* else, if stack[0] is unknown, set to user mode, running */
1423 List
<LttngProcessState
> processes
= traceSt
.getProcesses();
1424 TmfTimestamp time
= trcEvent
.getTimestamp();
1426 for (LttngProcessState process
: processes
) {
1427 fix_process(process
, time
);
1435 public Events
getEventHandleType() {
1440 * Private method used to establish the first execution state in the
1441 * stack for a given process
1446 private void fix_process(LttngProcessState process
,
1447 TmfTimestamp timestamp
) {
1449 LttngExecutionState es
;
1451 if (process
.getType() == ProcessType
.LTTV_STATE_KERNEL_THREAD
) {
1452 es
= process
.getFirstElementFromExecutionStack();
1454 if (es
.getExec_mode() == ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
) {
1455 es
.setExec_mode(ExecutionMode
.LTTV_STATE_SYSCALL
);
1457 .setExec_submode(ExecutionSubMode
.LTTV_STATE_SUBMODE_NONE
1459 es
.setEntry_Time(timestamp
);
1460 es
.setChange_Time(timestamp
);
1461 es
.setCum_cpu_time(0L);
1462 if (es
.getProc_status() == ProcessStatus
.LTTV_STATE_UNNAMED
) {
1463 es
.setProc_status(ProcessStatus
.LTTV_STATE_WAIT
);
1467 es
= process
.getFirstElementFromExecutionStack();
1468 if (es
.getExec_mode() == ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
) {
1469 es
.setExec_mode(ExecutionMode
.LTTV_STATE_USER_MODE
);
1471 .setExec_submode(ExecutionSubMode
.LTTV_STATE_SUBMODE_NONE
1473 es
.setEntry_Time(timestamp
);
1474 es
.setChange_Time(timestamp
);
1475 es
.setCum_cpu_time(0L);
1476 if (es
.getProc_status() == ProcessStatus
.LTTV_STATE_UNNAMED
) {
1477 es
.setProc_status(ProcessStatus
.LTTV_STATE_RUN
);
1480 // If the first element is also the one on top... mean
1481 // we have ONE element on the stack
1482 if (process
.getFirstElementFromExecutionStack() == process
1483 .peekFromExecutionStack()) {
1485 * Still in bottom unknown mode, means never did a
1486 * system call May be either in user mode, syscall
1487 * mode, running or waiting.
1490 * FIXME : we may be tagging syscall mode when being
1493 // Get a new execution State
1494 es
= new LttngExecutionState();
1496 // initialize values
1497 es
.setExec_mode(ExecutionMode
.LTTV_STATE_SYSCALL
);
1499 .setExec_submode(ExecutionSubMode
.LTTV_STATE_SUBMODE_NONE
1501 es
.setEntry_Time(timestamp
);
1502 es
.setChange_Time(timestamp
);
1503 es
.setCum_cpu_time(0L);
1504 es
.setProc_status(ProcessStatus
.LTTV_STATE_UNNAMED
);
1506 // Push the new state to the stack
1507 process
.pushToExecutionStack(es
);
1518 * Handles: LTT_EVENT_PROCESS_STATE
1521 * FIELDS: LTT_FIELD_PID, LTT_FIELD_PARENT_PID, LTT_FIELD_NAME,
1522 * LTT_FIELD_TYPE, LTT_FIELD_MODE, LTT_FIELD_SUBMODE, LTT_FIELD_STATUS,
1528 final IEventProcessing
getEnumProcessStateHandler() {
1529 AbsStateUpdate handler
= new AbsStateUpdate() {
1531 private Events eventType
= Events
.LTT_EVENT_PROCESS_STATE
;
1534 public boolean process(LttngEvent trcEvent
, LttngTraceState traceSt
) {
1540 Long cpu
= trcEvent
.getCpuId();
1541 LttngProcessState process
= traceSt
.getRunning_process().get(
1543 LttngProcessState parent_process
;
1545 // String mode, submode, status;
1546 LttngExecutionState es
;
1549 pid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_PID
);
1552 parent_pid
= getAFieldLong(trcEvent
, traceSt
,
1553 Fields
.LTT_FIELD_PARENT_PID
);
1556 command
= getAFieldString(trcEvent
, traceSt
,
1557 Fields
.LTT_FIELD_NAME
);
1559 Long typeVal
= getAFieldLong(trcEvent
, traceSt
,
1560 Fields
.LTT_FIELD_TYPE
);
1561 if ((typeVal
!= null) && (typeVal
.longValue() == 0L)) {
1562 type
= ProcessType
.LTTV_STATE_USER_THREAD
.getInName();
1564 type
= ProcessType
.LTTV_STATE_KERNEL_THREAD
.getInName();
1568 // mode = getAFieldString(trcEvent, traceSt,
1569 // Fields.LTT_FIELD_MODE);
1572 // submode = getAFieldString(trcEvent, traceSt,
1573 // Fields.LTT_FIELD_SUBMODE);
1576 // status = getAFieldString(trcEvent, traceSt,
1577 // Fields.LTT_FIELD_STATUS);
1580 tgid
= getAFieldLong(trcEvent
, traceSt
, Fields
.LTT_FIELD_TGID
);
1585 if ((pid
!= null) && (pid
.longValue() == 0L)) {
1586 for (Long acpu
: traceSt
.getCpu_states().keySet()) {
1587 process
= lttv_state_find_process(traceSt
, acpu
, pid
);
1588 if (process
!= null) {
1589 process
.setPpid(parent_pid
);
1590 process
.setTgid(tgid
);
1591 process
.setName(command
);
1593 .setType(ProcessType
.LTTV_STATE_KERNEL_THREAD
);
1595 StringBuilder sb
= new StringBuilder(
1596 "Unexpected, null process read from the TraceState list of processes, event time: "
1597 + trcEvent
.getTimestamp());
1598 TraceDebug
.debug(sb
.toString());
1603 * The process might exist if a process was forked while
1604 * performing the state dump.
1606 process
= lttv_state_find_process(traceSt
, ANY_CPU
, pid
);
1607 if (process
== null) {
1608 parent_process
= lttv_state_find_process(traceSt
,
1609 ANY_CPU
, parent_pid
);
1610 TmfTimestamp eventTime
= trcEvent
.getTimestamp();
1611 process
= create_process(traceSt
, cpu
, pid
, tgid
,
1612 command
, eventTime
);
1613 if (parent_process
!= null) {
1614 process
.setPpid(parent_process
.getPid(), eventTime
);
1617 /* Keep the stack bottom : a running user mode */
1619 * Disabled because of inconsistencies in the current
1622 if (type
.equals(ProcessType
.LTTV_STATE_KERNEL_THREAD
1625 * FIXME Kernel thread : can be in syscall or
1626 * interrupt or trap.
1629 * Will cause expected trap when in fact being
1630 * syscall (even after end of statedump event) Will
1631 * cause expected interrupt when being syscall.
1632 * (only before end of statedump event)
1635 .setType(ProcessType
.LTTV_STATE_KERNEL_THREAD
);
1638 // es->t = LTTV_STATE_SYSCALL;
1644 * User space process : bottom : user mode either
1645 * currently running or scheduled out. can be
1646 * scheduled out because interrupted in (user mode
1647 * or in syscall) or because of an explicit call to
1648 * the scheduler in syscall. Note that the scheduler
1649 * call comes after the irq_exit, so never in
1650 * interrupt context.
1652 // temp workaround : set size to 1 : only have user
1655 // will cause g_info message of expected syscall
1658 // in user mode. Can also cause expected trap when
1661 // mode in the event of a page fault reenabling
1664 // Expected syscall and trap can also happen after
1667 // This will cause a
1668 // "popping last state on stack, ignoring it."
1670 // process->execution_stack =
1671 // g_array_set_size(process->execution_stack, 1);
1672 // es = process->state =
1673 // &g_array_index(process->execution_stack,
1674 // LttvExecutionState, 0);
1675 // a new process must have only one state in the
1677 // be the same as the current state
1678 // es = process.getState();
1679 // es.setExec_mode(ExecutionMode.LTTV_STATE_MODE_UNKNOWN);
1680 // es.setProc_status(ProcessStatus.LTTV_STATE_UNNAMED);
1682 // .setExec_submode(ExecutionSubMode.LTTV_STATE_SUBMODE_UNKNOWN
1686 // es->t = LTTV_STATE_USER_MODE;
1691 // TODO: clean up comments above: Moved repeated code
1693 // if / else blocks above,
1694 // comments left temporarily for easier visualization
1696 // comparision with c code
1697 es
= process
.getState();
1698 es
.setExec_mode(ExecutionMode
.LTTV_STATE_MODE_UNKNOWN
);
1699 es
.setProc_status(ProcessStatus
.LTTV_STATE_UNNAMED
);
1701 .setExec_submode(ExecutionSubMode
.LTTV_STATE_SUBMODE_UNKNOWN
1704 // /* UNKNOWN STATE */
1706 // es = process->state =
1707 // &g_array_index(process->execution_stack,
1708 // LttvExecutionState, 1);
1709 // es->t = LTTV_STATE_MODE_UNKNOWN;
1710 // es->s = LTTV_STATE_UNNAMED;
1711 // es->n = LTTV_STATE_SUBMODE_UNKNOWN;
1716 * The process has already been created : Probably was
1717 * forked while dumping the process state or was simply
1718 * scheduled in prior to get the state dump event.
1720 process
.setPpid(parent_pid
);
1721 process
.setTgid(tgid
);
1722 process
.setName(command
);
1723 if (type
.equals(ProcessType
.LTTV_STATE_KERNEL_THREAD
1726 .setType(ProcessType
.LTTV_STATE_KERNEL_THREAD
);
1728 process
.setType(ProcessType
.LTTV_STATE_USER_THREAD
);
1732 // &g_array_index(process->execution_stack,
1733 // LttvExecutionState,
1736 // if(es->t == LTTV_STATE_MODE_UNKNOWN) {
1737 // if(type == LTTV_STATE_KERNEL_THREAD)
1738 // es->t = LTTV_STATE_SYSCALL;
1740 // es->t = LTTV_STATE_USER_MODE;
1744 * Don't mess around with the stack, it will eventually
1745 * become ok after the end of state dump.
1755 public Events
getEventHandleType() {