Potentially fix hang when opening LSP menu (#49046) (cherry-pick to stable) (#49049)

zed-zippy[bot] , John Tur , and Eric Holk created

Cherry-pick of #49046 to stable

----
It is maybe possible that, if a process's parent dies, the PID can be
reused by a different process. This could cause an infinite loop in
`is_descendant_of`. To fix this, break out of the loop when a cycle is
detected.

- [ ] Tests or screenshots needed?
- [X] Code Reviewed
- [X] Manual QA

Release Notes:

- N/A

---------

Co-authored-by: Eric Holk <eric@zed.dev>

Co-authored-by: John Tur <john-tur@outlook.com>
Co-authored-by: Eric Holk <eric@zed.dev>

Change summary

crates/language_tools/src/lsp_button.rs | 4 ++++
1 file changed, 4 insertions(+)

Detailed changes

crates/language_tools/src/lsp_button.rs 🔗

@@ -125,7 +125,11 @@ impl ProcessMemoryCache {
 
     fn is_descendant_of(&self, pid: Pid, root_pid: Pid, parent_map: &HashMap<Pid, Pid>) -> bool {
         let mut current = pid;
+        let mut visited = HashSet::default();
         while current != root_pid {
+            if !visited.insert(current) {
+                return false;
+            }
             match parent_map.get(&current) {
                 Some(&parent) => current = parent,
                 None => return false,