2 // MachineProcess.mutable-impl.hpp
5 // Created by James McIlree on 10/30/12.
6 // Copyright (c) 2014 Apple. All rights reserved.
11 template <typename SIZE>
12 void MachineProcess<SIZE>::set_exit_by_syscall(AbsTime timestamp, int32_t exit_status) {
13 ASSERT(!is_exiting(), "Attempt to exit after process is already exiting");
14 ASSERT(_exit_initiated_timestamp == 0, "Sanity");
15 ASSERT(!is_kernel(), "Kernel process is attempting to exit");
17 _exit_status = exit_status;
18 _exit_initiated_timestamp = timestamp;
20 set_flags(kMachineProcessFlag::IsExitBySyscall);
23 template <typename SIZE>
24 void MachineProcess<SIZE>::set_exit_by_jetsam(AbsTime timestamp) {
25 ASSERT(!is_exiting(), "Attempt to exit after process is already exiting");
26 ASSERT(_exit_initiated_timestamp == 0, "Sanity");
27 ASSERT(!is_kernel(), "Kernel process is attempting to exit");
29 _exit_initiated_timestamp = timestamp;
31 set_flags(kMachineProcessFlag::IsExitByJetsam);
34 template <typename SIZE>
35 void MachineProcess<SIZE>::set_exit_by_exec(AbsTime timestamp) {
36 ASSERT(!is_exiting(), "Attempt to exit after process is already exiting");
37 ASSERT(_exit_initiated_timestamp == 0, "Sanity");
38 ASSERT(!is_kernel(), "Kernel process is attempting to exit");
40 _exit_initiated_timestamp = timestamp;
41 set_flags(kMachineProcessFlag::IsExitByExec);
43 for (MachineThread<SIZE>* thread : _threads_by_time) {
44 if (!thread->is_trace_terminated()) {
45 thread->set_trace_terminated(timestamp);
49 set_trace_terminated(timestamp);
52 template <typename SIZE>
53 void MachineProcess<SIZE>::set_trace_terminated(AbsTime timestamp){
54 ASSERT(is_exiting(), "Attempting to set trace terminated without precursor exit event");
55 ASSERT(!is_kernel(), "Kernel process is attempting to set trace terminated");
58 for (MachineThread<SIZE>* thread : _threads_by_time) {
59 ASSERT(thread->is_trace_terminated(), "Setting process as trace terminated when it still has live threads");
63 _timespan.set_max(timestamp + AbsTime(1));
64 set_flags(kMachineProcessFlag::IsTraceTerminated);
67 template <typename SIZE>
68 void MachineProcess<SIZE>::set_apptype(uint32_t type) {
69 ASSERT(type >= TASK_APPTYPE_NONE && type <= TASK_APPTYPE_APP_TAL, "Out of range");
70 ASSERT(_apptype == -1 || _apptype == type, "Attempt to set apptype more than once, or to change an inherited apptype");
71 ASSERT(!is_kernel(), "Kernel is attempting to set apptype");
72 ASSERT(!is_exiting(), "Setting apptype after exit");
77 template <typename SIZE>
78 void MachineProcess<SIZE>::set_apptype_from_trequested(uint32_t type) {
79 ASSERT(type >= TASK_APPTYPE_NONE && type <= TASK_APPTYPE_APP_TAL, "Out of range");
80 ASSERT(_apptype == -1 || _apptype == type, "trequested apptype does not match set apptype");
85 template <typename SIZE>
86 void MachineProcess<SIZE>::set_name(const char* name) {
87 ASSERT(name, "Sanity");
88 ASSERT(strlen(name) < sizeof(_name) - 1, "Sanity");
90 strlcpy(_name, name, sizeof(_name));
93 template <typename SIZE>
94 void MachineProcess<SIZE>::clear_fork_exec_in_progress() {
95 ASSERT(!is_unknown(), "Sanity");
96 ASSERT(!is_kernel(), "Sanity");
97 ASSERT(!is_exiting(), "Sanity");
98 ASSERT(!is_exec_in_progress(), "Sanity");
99 ASSERT(is_fork_exec_in_progress(), "Sanity");
101 clear_flags(kMachineProcessFlag::IsForkExecInProgress);
104 template <typename SIZE>
105 void MachineProcess<SIZE>::clear_exec_in_progress() {
106 ASSERT(!is_unknown(), "Sanity");
107 ASSERT(!is_kernel(), "Sanity");
108 ASSERT(!is_exiting(), "Sanity");
109 ASSERT(!is_fork_exec_in_progress(), "Sanity");
110 ASSERT(is_exec_in_progress(), "Sanity");
112 clear_flags(kMachineProcessFlag::IsExecInProgress);
115 template <typename SIZE>
116 void MachineProcess<SIZE>::add_thread(MachineThread<SIZE>* thread) {
117 ASSERT(thread, "Sanity");
118 ASSERT(&thread->process() == this, "Sanity");
119 ASSERT(!thread->is_trace_terminated(), "Attempt to add thread that is already terminated");
120 ASSERT(thread->timespan().location() >= _timespan.location(), "Attempt to add thread that started before this process");
121 ASSERT(!is_exiting(), "Adding thread to process that has exited");
123 // 6/20/2014, reworking time handling, is this still true?
125 // Process/thread created by a previous machine state will violate these
126 // rules, during initialization. However, only threads created in that
127 // form will be so tagged, and so we can exclude them from this assert.
129 // ASSERT(!is_exited() || thread->is_created_by_previous_machine_state(), "Adding thread to process that has marked itself as exited");
132 // At this point, the threads vector is not sorted.
133 // We have to look at everything :-(.
134 for (MachineThread<SIZE>* process_thread : _threads_by_time) {
135 if (process_thread->tid() == thread->tid()) {
136 ASSERT(!process_thread->timespan().intersects(thread->timespan()), "Overlapping duplicate threads");
141 _threads_by_time.push_back(thread);
144 template <typename SIZE>
145 void MachineProcess<SIZE>::post_initialize(AbsTime last_machine_timestamp) {
147 // For processes that are still alive at the post_initialize phase,
148 // we want to extend their timespan(s) to the end of the machine state,
149 // so they can be looked up by pid/name.
151 if (!is_trace_terminated()) {
152 ASSERT(_timespan.length() == 0, "Should not have timespan set");
154 // Time in a range is always half open. [ 10, 11 ) means 10 is included,
155 // but 11 is not. In order to include a given timestamp, we must use
156 // a value one greater.
157 AbsTime half_open_timestamp = last_machine_timestamp + AbsTime(1);
159 _timespan.set_max(half_open_timestamp);
162 std::sort(_threads_by_time.begin(), _threads_by_time.end(), thread_by_time_sort<SIZE>);