178 lines
3.7 KiB
Markdown
178 lines
3.7 KiB
Markdown
# libtask 缺陷修复计划
|
||
|
||
> **For agentic workers:** 此计划列出 libtask 事件和消息队列子系统的已知缺陷修复步骤。
|
||
|
||
**目标**: 修复 4 个缺陷 — use-after-free ×2、AND 位测试陷阱、cond_signal 稳健性
|
||
|
||
**涉及文件**: 仅 `src/public/libtask/src/myTask.c`
|
||
|
||
---
|
||
|
||
### Task 1: 修复 `task_event_destroy` use-after-free
|
||
|
||
**文件**: `src/public/libtask/src/myTask.c:106-131`
|
||
|
||
- [ ] **Step 1: 修改 `task_event_destroy`**
|
||
|
||
将 `free(p)` 后访问 `p->name` 改为先保存到栈变量:
|
||
|
||
```c
|
||
int task_event_destroy(stru_task_event_t p_event)
|
||
{
|
||
if(!p_event)
|
||
{
|
||
LOG_E("task_event_destroy error, p_event is NULL");
|
||
return -1;
|
||
}
|
||
|
||
stru_task_event *p = (stru_task_event *)p_event;
|
||
|
||
pthread_mutex_lock(&p->mutex);
|
||
p->ref_count--;
|
||
if(p->ref_count > 0)
|
||
{
|
||
pthread_mutex_unlock(&p->mutex);
|
||
return 0;
|
||
}
|
||
|
||
pthread_mutex_unlock(&p->mutex);
|
||
pthread_mutex_destroy(&p->mutex);
|
||
pthread_cond_destroy(&p->cond);
|
||
|
||
LOG_I("task_event_destroy success, name:%s", p->name);
|
||
|
||
free(p);
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
**改动**: `free(p)` 下移到 `LOG_I` 之后。
|
||
|
||
- [ ] **Step 2: 编译验证**
|
||
|
||
```bash
|
||
./release/build.sh
|
||
```
|
||
预期: 编译通过,零错误零警告。
|
||
|
||
---
|
||
|
||
### Task 2: 修复 `task_msg_queue_destroy` use-after-free
|
||
|
||
**文件**: `src/public/libtask/src/myTask.c:317-343`
|
||
|
||
- [ ] **Step 1: 修改 `task_msg_queue_destroy`**
|
||
|
||
同样将 `free(p)` 放到 `LOG_I` 之后:
|
||
|
||
```c
|
||
int task_msg_queue_destroy(stru_task_msg_queue_t p_queue)
|
||
{
|
||
if(!p_queue)
|
||
{
|
||
LOG_E("task_msg_queue_destroy error, p_queue is NULL");
|
||
return -1;
|
||
}
|
||
|
||
stru_task_msg_queue *p = (stru_task_msg_queue *)p_queue;
|
||
|
||
pthread_mutex_lock(&p->mutex);
|
||
p->ref_count--;
|
||
if(p->ref_count > 0)
|
||
{
|
||
pthread_mutex_unlock(&p->mutex);
|
||
return 0;
|
||
}
|
||
|
||
pthread_mutex_unlock(&p->mutex);
|
||
pthread_mutex_destroy(&p->mutex);
|
||
pthread_cond_destroy(&p->cond);
|
||
free(p->buffer);
|
||
|
||
LOG_I("task_msg_queue_destroy success, name:%s", p->name);
|
||
|
||
free(p);
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
- [ ] **Step 2: 编译验证**
|
||
|
||
```bash
|
||
./release/build.sh
|
||
```
|
||
预期: 编译通过。
|
||
|
||
---
|
||
|
||
### Task 3: 修复 `task_event_recv` AND 检查用 `==` 而非位测试
|
||
|
||
**文件**: `src/public/libtask/src/myTask.c:182`
|
||
|
||
- [ ] **Step 1: 修改 AND 条件判断**
|
||
|
||
将第 182 行从 `==` 改为 `&`:
|
||
|
||
```c
|
||
if(opt & TASK_EVENT_FLAG_AND)
|
||
{
|
||
```
|
||
|
||
- [ ] **Step 2: 编译验证**
|
||
|
||
```bash
|
||
./release/build.sh
|
||
```
|
||
预期: 编译通过。
|
||
|
||
---
|
||
|
||
### Task 4: `task_event_send` 改用 `cond_broadcast`
|
||
|
||
**文件**: `src/public/libtask/src/myTask.c:145`
|
||
|
||
- [ ] **Step 1: 修改 signal 为 broadcast**
|
||
|
||
将第 145 行:
|
||
|
||
```c
|
||
pthread_cond_signal(&p->cond);
|
||
```
|
||
|
||
改为:
|
||
|
||
```c
|
||
pthread_cond_broadcast(&p->cond);
|
||
```
|
||
|
||
- [ ] **Step 2: 编译验证**
|
||
|
||
```bash
|
||
./release/build.sh
|
||
```
|
||
预期: 编译通过。
|
||
|
||
---
|
||
|
||
### Task 5: 最终验证
|
||
|
||
- [ ] **Step 1: 全量编译**
|
||
|
||
```bash
|
||
./release/build.sh
|
||
```
|
||
预期: `Build complete`,零错误零警告。
|
||
|
||
- [ ] **Step 2: 更新分析文档**
|
||
|
||
在 `mimo/工程/libtask模块分析.md` 的缺点表中更新:标记 use-after-free 已修复、AND 位测试已修复。
|
||
|
||
---
|
||
|
||
## 未纳入修复的已知问题(调用方侧)
|
||
|
||
| 问题 | 位置 | 说明 |
|
||
|------|------|------|
|
||
| 消息队列 send+event 回滚误取 | self_ptl.cpp:317/iec.cpp:336/com_scan.cpp:38 | `send` 成功但 `event_send` 失败时,`try_recv` 从队首取可能误删旧消息。这是调用方逻辑问题,非 libtask 缺陷,需调用方自行处理。 |
|
||
| `task_msg_queue_send_timeout` 未被使用 | — | API 已提供但无调用者,三个 send 调用点可考虑切换为 timeout 版本避免队列满丢数据。 |
|