8.5 KiB
问题处理文档
2026-06-15
#11 libcom_channel + libcom_scan 合并为 libcom_decode
问题:两个模块紧耦合(com_channel 调 com_recv_data,com_scan 调 com_channel_interface_get),且 app_comm_channel 线程为空壳
修复:
- 合并为
libcom_decode模块,按功能拆分 4 个文件 - 整合为 1 个 app 线程(删除空壳线程)
- 枚举值合并(ENUM_APP_COMM + ENUM_APP_COM_SCAN → ENUM_APP_COM_DECODE)
状态:✅ 已完成
涉及文件:新建 src/system/libcom_decode/(4源文件+makefile),修改 mySystem.h、app_sys.cpp、self_ptl.cpp、iec.cpp、makefile
验证:./release/build.sh 编译通过
#10 libcomm + 调用者缺陷修复
问题:
- UDP
recvfrom永久阻塞,无超时无退出机制 - UDP
close后state_cb(id, -1, disconnected),回调拿到的是已关闭的 -1 com_scan/self_ptl/iec三处 send+event 回滚竞态:msg_queue_send成功 →event_send失败 →try_recv可能取出旧消息com_channel_recv_cb中comm_send到已断开的 TCP_C_0 不检查 fd
修复:
udp_run中recvfrom前加select1s 超时udp_close先保存 fd 再 close,回调传入正确值- 三处改为先
event_send再msg_queue_send,消除回滚竞态 com_channel_recv_cb在comm_send前检查socket_fd >= 0
状态:✅ 已完成
涉及文件:comm_udp.cpp, com_scan.cpp, self_ptl.cpp, iec.cpp, com_channel.cpp
验证:./release/build.sh 编译通过
#9 libcomm 模块修补
问题:
- UART send 不完整:裸 write 无流量控制,缺少原始模式终端设置(~ICANON/~ECHO/~OPOST)
- TCP client select 100ms 空轮询,空闲时 CPU 空转
- 无
comm_destroy接口,内存泄漏 stru_comm结构体中 6 个函数指针字段从未使用,冗余
修复:
- 重写
comm_uart.cpp:恢复原始模式 + VTIME=1 读超时 + tcflush/tcdrain 完整发送 - TCP client select 去掉超时参数,永久阻塞
- 新增
comm_destroy(id)API - 删除
stru_comm中 6 个未使用字段
状态:✅ 已完成
涉及文件:comm_uart.cpp, comm_tcp.cpp, comm.cpp, comm.h, myComm.h
验证:./release/build.sh 编译通过
#8 libtask 事件/消息队列缺陷修复
问题:
task_event_destroy和task_msg_queue_destroy在free(p)后仍访问p->name(use-after-free)task_event_recv中 AND 检查用opt == TASK_EVENT_FLAG_AND而非位测试,AND | CLEAR组合被误识别为 ORtask_event_send用pthread_cond_signal而非cond_broadcast,多等待者场景可能唤醒不足
修复:
free(p)移到LOG_I之后,先打日志再释放opt ==改为opt &位测试cond_signal改为cond_broadcast
状态:✅ 已完成
涉及文件:src/public/libtask/src/myTask.c
验证:./release/build.sh 编译通过
#7 libtask 定时器 SIGEV_THREAD 线程爆炸
问题:myTask.c 使用 timer_create(CLOCK_REALTIME, SIGEV_THREAD) 模式,每次定时器超时内核创建一个新线程执行回调。9 个 app 线程 × 3 个定时器(10ms/100ms/1000ms)= 27 个定时器,每秒约 1000 次内核线程创建/销毁,系统开销极大。回调仅做 task_event_send 设一个事件位(几微秒),线程创建开销远大于实际工作。
需求:
- 消除每次定时器超时创建线程的开销
- API 签名全部不变,调用方零修改
- 仅 Linux 平台
修复方案:用 Linux timerfd + epoll + 单例管理器线程 替代 SIGEV_THREAD:
stru_task_timer:timer_t timerid→int timerfd,新增pthread_cond_t cond、int in_epoll- 删除
task_timer_sig_handler,新增timer_manager_thread(epoll_wait 监听所有 timerfd,超时时调用原始回调) task_timer_stop/destroy:while(running) usleep(1000)忙等 →cond_wait零 CPU 阻塞- 6 个 API 签名全部不变
状态:✅ 已完成
涉及文件:src/public/libtask/src/myTask.c(仅此一个文件,release/inc/myTask.h 无改动)
验证:./release/build.sh 编译通过,零错误零警告
2026-06-12
#6 Tab 补全子命令前缀丢失
问题:输入 datacenter + p + Tab 后,datacenter 前缀被 param 覆盖,整行只剩 param。
根因:linenoiseEdit 中 Tab 键处理用 strncpy(buf, completions[0]) 整行覆盖。
修复:改为找到最后一个空格,只替换空格之后的当前词,保留前缀。
#5 app_cmd 交互卡顿与 Tab 补全失效
问题:上一轮将 cmd_recv 改为 select 非阻塞 + EV_TIMER2(100ms) 后:
- 回车后
cmd>回显不及时,有明显卡顿感 - 输入
d后按 Tab,不会弹出命令补全
根因:select() 方案与 linenoise() 交互式行编辑器根本性不兼容——select 时终端处于规范模式(行缓冲),Tab 不是行终止符不会触发 select;100ms 定时器引入最多 100ms 延迟。
修复:将 app_cmd 线程从定时器事件驱动改为简单阻塞循环 while(1) { cmd_recv(); }。linenoise() 自管理终端模式切换和 Tab 补全,线程阻塞在 stdin 上零延迟响应。
验证:编译通过。
#4 app_cmd 线程启用后 CPU 飙升至 108%
问题:app_cmd 线程中 cmd_recv() 启用后,CPU 占用 108%,导致该入口被暂时屏蔽(app_cmd.cpp:117 被注释)。
根因:
- 死循环层面:
linenoiseEdit()(my_cmd.cpp:107)中read()只检查了返回-1,未处理返回0(EOF)。当进程无真正控制终端时(RTU 嵌入式环境常见),read()立即返回 0 形成死循环。 - 架构层面:
linenoise()是同步阻塞调用,却被放在 10ms 定时器 EVI_TIMER1 中执行,与其他定时器事件循环模型不兼容。
修复内容:
my_cmd.cpp:read()返回值判断改为<= 0(含 EOF 处理);enableRawMode()返回值在linenoise()中检查,失败直接返回 NULLapp_cmd.cpp:重构cmd_recv为cmd_recv_nonblock(),用select()实现非阻塞 stdin 检查 +isatty()过滤非终端环境,移至 EV_TIMER2(100ms)调用CLAUDE.md:全文翻译为中文
验证:编译通过(零错误零警告),./test/RTU < /dev/null 运行 3 秒 CPU 占用 0.0%。
2026-06-10
#1 libmms_m RCB 订阅编号硬编码
问题:mms_m_icd_report_init() 中硬编码 if(0 == rpt_no.compare("01")),只订阅编号为 "01" 的 RCB,其他编号被丢弃,无法按需灵活订阅多个 RCB 实例。
需求:
- 灵活可配置订阅的控制块编号
- libmms_m 提供接口,由 libiec61850m 传入
- 可传入一个或多个编号,不传默认
"01" - 无效数据打印错误并返回失败
处理计划:RCB订阅编号可配置化
状态:✅ 已完成
涉及文件:myMms_m.h, mms_m.h, mms_m.cpp, iec61850m.cpp
#2 libweb_server 模块缺陷修复
问题:WebSocket 服务端模块存在 10 个缺陷,含严重级别(单客户端、多线程竞态、悬空指针、non-null-terminated UB)和高危/中等级别(调试 printf、SBO 阻塞、LOG 格式化缺失等)。
需求:
- 兼容多个 WebSocket 客户端同时连接
- 完善断连处理
- 多线程安全保护
- 修复 UB 和格式化问题
- 增量推送优化(仅变化时发送)
处理计划:libweb_server模块分析
状态:✅ 已完成
涉及文件:web_server.cpp, ws_method.cpp
#3 libweb_server 多连接资源共享冲突
问题:支持多客户端后,所有连接共享同一套全局信号资源(g_ws_out_signals 等),一个客户端的 add/del 操作会影响其他客户端的数据推送。
需求:
- 每个连接独立的信号资源(per-connection session)
- 连接建立时自动开辟资源,断开时自动释放
ws_task()按 session 独立构建 JSON 推送到对应连接
处理计划:libweb_server模块分析
状态:✅ 已完成
涉及文件:ws_method.h, ws_method.cpp, web_server.cpp