环境介绍

库是使用的easylogging++,使用多线程进行业务管理,然后使用easylogging++进行多线程日志输出。

现象说明

使用systemctl进行自启动管理,经常发生崩溃。崩溃出现在日志编写之后。

systemctl提示内存泄漏

Jul 30 22:05:47 13 webrtc-streamer[816]: 2024-07-30 22:05:47,300 INFO [default] TR Data = 182.9°{"type":"command","subType":"tank","value":{"left":0,"right":0,"turret":100,"gun":0,"gunShake":false}}
Jul 30 22:05:47 13 systemd[1]: rws.service: Main process exited, code=killed, status=11/SEGV
Jul 30 22:05:47 13 systemd[1]: rws.service: Failed with result 'signal'.
Jul 30 22:05:52 13 systemd[1]: rws.service: Service RestartSec=5s expired, scheduling restart.
Jul 30 22:05:52 13 systemd[1]: rws.service: Scheduled restart job, restart counter is at 2.
Jul 30 22:05:52 13 systemd[1]: Stopped Rpi WebRTC Streamer.
Jul 30 22:05:52 13 systemd[1]: Started Rpi WebRTC Streamer.

问题聚焦

怀疑是上下位机通信时产生中断,或下位机死机造成通信中断,上位机死机。
遂用GDB进行调试

sudo gdb webrtc-streamer
run

发生崩溃:

Thread 9 "webrtc-streamer" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x711fe3c0 (LWP 895)]
0x00484a54 in el::base::DefaultLogDispatchCallback::dispatch (this=this@entry=0x9bea00, logLine="2024-07-30 22:12:47,724 DEBUG [default] [root@unknown-host] [void SendAngle_Cb(float)] [streamer.cc:114] Send Angle to app :118°\n") at easylogging++.h:2477
2477        easylogging++.h: No such file or directory.

锁定是easylogging++的问题,查之。
偶然看到自己的某行备注:

// 日志库 cmake里面必须加上 add_definitions(-DELPP_NO_DEFAULT_LOG_FILE -DELPP_THREAD_SAFE)不创建默认日志、线程安全

在看Makfile文件,意识到可能是多线程导致的崩溃。遂加之

# easylogging to protect therad safty
EASYLOGGING_FLAGS = -DELPP_NO_DEFAULT_LOG_FILE -DELPP_THREAD_SAFE

CCFLAGS += $(EASYLOGGING_FLAGS)

问题解决!