| 361 | } |
| 362 | |
| 363 | void test_zombie_process(void* /*arg*/) { |
| 364 | klog::Info("=== Zombie Process Test ==="); |
| 365 | |
| 366 | bool passed = true; |
| 367 | |
| 368 | // 1. 创建父 TCB(不加入调度,entry 为 nullptr),验证 parent_pid 字段正确关联 |
| 369 | auto parent_uptr = |
| 370 | kstd::make_unique<TaskControlBlock>("Parent", 10, nullptr, nullptr); |
| 371 | auto* parent = parent_uptr.get(); |
| 372 | parent->pid = local_pid_counter.fetch_add(1); |
| 373 | parent->aux->tgid = parent->pid; |
| 374 | parent->aux->parent_pid = 1; |
| 375 | |
| 376 | auto* local_child = |
| 377 | new TaskControlBlock("ZombieFsmTest", 10, nullptr, nullptr); |
| 378 | local_child->pid = local_pid_counter.fetch_add(1); |
| 379 | local_child->aux->tgid = local_child->pid; |
| 380 | local_child->aux->parent_pid = parent->pid; |
| 381 | |
| 382 | if (local_child->aux->parent_pid != parent->pid) { |
| 383 | klog::Err( |
| 384 | "test_zombie_process: FAIL — child parent_pid mismatch " |
| 385 | "(expected {}, got {})", |
| 386 | parent->pid, local_child->aux->parent_pid); |
| 387 | passed = false; |
| 388 | } |
| 389 | |
| 390 | local_child->aux->exit_code = 0; |
| 391 | local_child->fsm.Receive(MsgSchedule{}); // kUnInit -> kReady |
| 392 | local_child->fsm.Receive(MsgSchedule{}); // kReady -> kRunning |
| 393 | local_child->fsm.Receive( |
| 394 | MsgExit{0, true}); // kRunning -> kZombie (has parent) |
| 395 | if (local_child->GetStatus() != TaskStatus::kZombie) { |
| 396 | klog::Err( |
| 397 | "test_zombie_process: FAIL — child with living parent should be " |
| 398 | "kZombie (got {})", |
| 399 | static_cast<int>(local_child->GetStatus())); |
| 400 | passed = false; |
| 401 | } |
| 402 | if (local_child->aux->parent_pid != parent->pid) { |
| 403 | klog::Err( |
| 404 | "test_zombie_process: FAIL — child parent_pid changed after " |
| 405 | "status update"); |
| 406 | passed = false; |
| 407 | } |
| 408 | |
| 409 | klog::Info("Child process (pid={}) became zombie, waiting for parent to reap", |
| 410 | local_child->pid); |
| 411 | |
| 412 | delete local_child; |
| 413 | |
| 414 | // 3. 用真实工作函数验证有父进程的子任务能正常执行 |
| 415 | std::atomic<int> work_flag{0}; |
| 416 | auto real_child = kstd::make_unique<TaskControlBlock>( |
| 417 | "RealChild", 10, child_work, reinterpret_cast<void*>(&work_flag)); |
| 418 | real_child->aux->parent_pid = parent->pid; |
| 419 | TaskManagerSingleton::instance().AddTask(std::move(real_child)); |
| 420 | |