Skip to content

Commit

Permalink
server/motion_processor.cpp: fix crash by freeing cv::Mat the right way
Browse files Browse the repository at this point in the history
This happens when schedule changes from 'M' to 'C'.

This is how it looks in the logs:

 I(1/software): motion_blend_radio is set to 15:1
 I(1/software): motion_debug is set to 0
 I(1/software): Motion detected
 E(): Got connection, but failed to accept
 I(1/software): Switching to new recording schedule 'continuous'
 BUG: Segment violation at 0x0000000000000366
 Call trace:
 [0x000055db84eb8d5b]  @ /usr/sbin/bc-server
 [0x00007f9949977320]  @ /lib/x86_64-linux-gnu/libc.so.6
 [0x00007f994a5c77e9] _ZN2cv3Mat7releaseEv+0x00000000 @ /lib/x86_64-linux-gnu/libopencv_core.so.406
 [0x000055db84eb8ee4]  @ /usr/sbin/bc-server
 [0x000055db84ebc2d6]  @ /usr/sbin/bc-server
 [0x000055db84ebc8dd]  @ /usr/sbin/bc-server
 [0x00007f99499cea94]  @ /lib/x86_64-linux-gnu/libc.so.6
 [0x00007f9949a5ba34] __clone+0x00000000 @ /lib/x86_64-linux-gnu/libc.so.6

This is how it looks in the debugger:

 #0  0x00007f994a5c77e9 in cv::Mat::release() () from /lib/x86_64-linux-gnu/libopencv_core.so.406
 #1  0x000055db84eb8ee4 in motion_processor::~motion_processor (this=0x7f993000bbb0, __in_chrg=<optimized out>) at motion_processor.cpp:59
 #2  0x000055db84ebc2d6 in motion_processor::~motion_processor (this=0x7f993000bbb0, __in_chrg=<optimized out>) at motion_processor.cpp:42
 #3  motion_processor::run (this=0x7f993000bbb0) at motion_processor.cpp:201
 #4  0x000055db84ebc8dd in bc_mproc_thread (data=<optimized out>) at motion_processor.cpp:861
 #5  0x00007f99499cea94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
 #6  0x00007f9949a5ba34 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100

According to the documentation, cv::Mat automatically derefs and frees
data as needed on being destroyed (e.g. delete)

https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#ae48d4913285518e2c21a3457017e716e

The bug was introduced by a memory leak fix.

Fixes: 089e6de ("motion_processor: release cv::Mat objects")
  • Loading branch information
andrey-utkin committed Dec 11, 2024
1 parent 252fd3e commit f0b3840
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions server/motion_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ motion_processor::motion_processor(bc_record *bcRecord)

memset(&m_debugEventTime, 0, sizeof(struct tm));
m_debugEventTime.tm_sec = -1;

// m_refFrames[2] is a static array so ctors, dtors are not called automatically on elements
new(&m_refFrames[0]) cv::Mat();
new(&m_refFrames[1]) cv::Mat();
}

motion_processor::~motion_processor()
Expand All @@ -55,9 +59,9 @@ motion_processor::~motion_processor()
}
#endif

for (int i = 0; i < sizeof(m_refFrames); i++) {
m_refFrames[i].release();
}
// m_refFrames[2] is a static array so ctors, dtors are not called automatically on elements
m_refFrames[0].~Mat();
m_refFrames[1].~Mat();
delete output_source;
}

Expand Down Expand Up @@ -579,7 +583,6 @@ int motion_processor::detect_opencv(AVFrame *rawFrame)
// first things first... get the original frame from the AVFrame and convert it to an OpenCV Grayscale Mat, and the "downscale" size.
cv::Mat m = cv::Mat(dst_h, dst_w, CV_8UC1);
if (convert_AVFrame_to_grayMat(rawFrame, m) == 0) {
m.release();
return 0; // error converting frame...
}

Expand Down Expand Up @@ -620,7 +623,6 @@ int motion_processor::detect_opencv(AVFrame *rawFrame)

if (m_motionDebug)
check_for_new_debug_event(ret);
m.release();
return ret;
}

Expand All @@ -633,7 +635,6 @@ int motion_processor::detect_opencv_advanced(AVFrame *rawFrame)
// first things first... get the original frame from the AVFrame and convert it to an OpenCV Grayscale Mat, and the "downscale" size.
cv::Mat m = cv::Mat(dst_h, dst_w, CV_8UC1);
if (convert_AVFrame_to_grayMat(rawFrame, m) == 0) {
m.release();
return 0; // error converting frame...
}

Expand Down Expand Up @@ -669,7 +670,6 @@ int motion_processor::detect_opencv_advanced(AVFrame *rawFrame)
}

m_motionTriggered = (num_md_frames >= m_minMotionFrames);
m.release();
return m_motionTriggered;
}

Expand Down

0 comments on commit f0b3840

Please sign in to comment.