| 128 | } |
| 129 | |
| 130 | void test_exit_with_error(void* /*arg*/) { |
| 131 | klog::Info("=== Exit With Error Test ==="); |
| 132 | |
| 133 | bool passed = true; |
| 134 | |
| 135 | // 1. 创建 TCB,确认 exit_code 默认为 0 |
| 136 | auto* task = new TaskControlBlock("ExitError", 10, nullptr, nullptr); |
| 137 | task->pid = local_pid_counter.fetch_add(1); |
| 138 | task->aux->tgid = task->pid; |
| 139 | task->aux->parent_pid = 1; |
| 140 | |
| 141 | if (task->aux->exit_code != 0) { |
| 142 | klog::Err("test_exit_with_error: FAIL — default exit_code != 0 (got {})", |
| 143 | task->aux->exit_code); |
| 144 | passed = false; |
| 145 | } |
| 146 | |
| 147 | // 2. 创建带实际工作的任务,以错误码退出 |
| 148 | std::atomic<int> work_flag{0}; |
| 149 | auto worker = kstd::make_unique<TaskControlBlock>( |
| 150 | "ExitErrorWorker", 10, error_work, reinterpret_cast<void*>(&work_flag)); |
| 151 | TaskManagerSingleton::instance().AddTask(std::move(worker)); |
| 152 | |
| 153 | int timeout = 10; |
| 154 | while (timeout > 0 && work_flag.load() == 0) { |
| 155 | (void)sys_sleep(50); |
| 156 | timeout--; |
| 157 | } |
| 158 | |
| 159 | if (work_flag.load() != 42) { |
| 160 | klog::Err("test_exit_with_error: FAIL — worker did not set error flag"); |
| 161 | passed = false; |
| 162 | } else { |
| 163 | klog::Info("test_exit_with_error: worker set flag to {}", work_flag.load()); |
| 164 | } |
| 165 | |
| 166 | // 3. 验证 TCB 中的退出码字段可以正确存储非零值 |
| 167 | task->aux->exit_code = 42; |
| 168 | task->fsm.Receive(MsgSchedule{}); // kUnInit -> kReady |
| 169 | task->fsm.Receive(MsgSchedule{}); // kReady -> kRunning |
| 170 | task->fsm.Receive(MsgExit{42, true}); // kRunning -> kZombie |
| 171 | if (task->aux->exit_code != 42) { |
| 172 | klog::Err( |
| 173 | "test_exit_with_error: FAIL — exit_code write-back mismatch " |
| 174 | "(expected 42, got {})", |
| 175 | task->aux->exit_code); |
| 176 | passed = false; |
| 177 | } |
| 178 | if (task->GetStatus() != TaskStatus::kZombie) { |
| 179 | klog::Err("test_exit_with_error: FAIL — status write-back mismatch"); |
| 180 | passed = false; |
| 181 | } |
| 182 | |
| 183 | if (passed) { |
| 184 | klog::Info("Exit With Error Test: PASSED"); |
| 185 | } else { |
| 186 | klog::Err("Exit With Error Test: FAILED"); |
| 187 | g_tests_failed++; |