### What do you see as an issue?

The documentation for zombie tasks https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/tasks.html#zombie-undead-tasks is a bit abstract at the moment. There is a scope for enhancing the document by explaining how Airflow detects tasks as zombies

### Solving the problem

We can enhance the documentation by translating this query https://github.com/astronomer/airflow/blob/main/airflow/jobs/scheduler_job_runner.py#L1721 to a layman readable text in our documentation.

### Anything else

It might also help to add developer contribution steps to reproduce zombies locally.

### Are you willing to submit PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

"""Respond to executor events."""
        if not self._standalone_dag_processor and not self.processor_agent:
            raise ValueError("Processor agent is not started.")
        ti_primary_key_to_try_number_map: dict[tuple[str, str, str, int], int] = {}
        event_buffer = self.job.executor.get_event_buffer()
        tis_with_right_state: list[TaskInstanceKey] = []
        
        for ti_key, (state, _) in event_buffer.items():
            
            ti_primary_key_to_try_number_map[ti_key.primary] = ti_key.try_number
            self.log.info("Received executor event with state %s for task instance %s", state, ti_key)
            if state in (TaskInstanceState.FAILED, TaskInstanceState.SUCCESS, TaskInstanceState.QUEUED):
                tis_with_right_state.append(ti_key)
        
        if not tis_with_right_state:
            return len(event_buffer)
        
        filter_for_tis = TI.filter_for_tis(tis_with_right_state)
        query = select(TI).where(filter_for_tis).options(selectinload(TI.dag_model))