---
title: Rust进程卡死
description: "死锁发生于两个及以上的线程互相等待对方采取行动，由于资源的锁定，没有线程能够获取所需资源，从而导致无限挂起。表现为程序会一直处于运行状态无法结束。定位思路如图1所示。"
url: https://www.hikunpeng.com/document/detail/zh/kunpenggrf/ref/kunpenggrffaq_10_0063.html
sourcePath: /source/zh/kunpenggrf/ref/kunpenggrffaq_10_0063.html
indexId: 41a467e3ab1b9b42b221b602211a7e307adc01d07c97357b9f9a04e306847c6c52
---
# Rust进程卡死

#### 定位思路

死锁发生于两个及以上的线程互相等待对方采取行动，由于资源的锁定，没有线程能够获取所需资源，从而导致无限挂起。表现为程序会一直处于运行状态无法结束。定位思路如图1所示。

图1 Rust进程卡死定位思路

1. 使用top命令查看相关进程仍在运行，程序长时间运行，并且没有新的打印日志。单核CPU出现100%或者所有cpu占用为0%状态，确认是进程卡死。
2. 根据业务逻辑，找到怀疑卡死的线程，运行GDB attach调试。
3. 分析堆栈信息及业务逻辑，找出卡死原因。
4. 修改代码，重新编译进行验证。
5. 若问题解决，则确认修改，合入原代码。
6. 若问题未解决，增加定位信息，重新编译运行。


#### 案例：管道通信导致系统卡死

问题现象：

在Rust中，线程通信一般依靠两种方式，管道通信和互斥锁管理。由于Rust特殊的所有权机制，有效的避免了大部分因数据竞争而导致的死锁问题。但对死锁问题依旧没有彻底解决。在互斥锁导致死锁的情况下，GDB调用栈会显示线程处于__lll_lock_wait状态，现象与问题定位过程与C/C++进程卡死一致。而遇到管道通信导致死锁，定位方法如下。

定位过程：

1. 运行过程中，发现运行时间过长，且通过top命令查看CPU占用为0，怀疑为进程卡死。
2. 运行cargo build进行编译，其生成的可执行文件存在于“./target/debug/”目录下，使用GDB运行。GDB使用说明请参见GDB。

```
gdb ./target/debug/FileCyber
(gdb) r
```


3. 遇到死锁时，使用ctrl c命令中止，并使用info threads命令查看线程。
4. 如果有线程存在pthread_mutex_lock，则需要查看其对应的线程。但在现在的状态下，thread 1在进行pthread_join，即在等待其他线程的运行结束，根据代码逻辑，此时进程在等待t1任务的完成。选择需要重点查看其他的线程：thread 4 和thread 2。
  查看backtrace：bt

  thread 4 的TID为33928，thread 2 的TID为33926。

5. 分析frame。
  根据bt信息查看代码，发现是由于t3未收到消息导致死锁，查看对应的逻辑之后，修改代码，死锁问题不再复现。

  在修改Rust第三方的代码时，注意使用上文的patch.crates-io标签，让Rust代码依赖本地的被修改的第三方库。
