IntelRealSense / librealsense

Intel® RealSense™ SDK
https://www.intelrealsense.com/
Apache License 2.0
7.56k stars 4.82k forks source link

Raspbian Buster and RTAB-Map, segfault on frame unpack, I have a fix #4919

Closed frank26080115 closed 4 years ago

frank26080115 commented 5 years ago
Required Info
Camera Model D415
Firmware Version Signed_Image_UVC_5_11_10_0
Operating System & Version Raspbian Buster
Kernel Version (Linux Only) 4.19
Platform Raspberry Pi 4
SDK Version 2.28.0 ff2a2919 (FORCE_UVC=ON)

Issue Description

As soon as RTAB-Map starts the camera, it would seg fault. I built a debug version of librealsense and GDB told me

Thread 38 "rtabmap" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x840aa310 (LWP 12758)]
0xb2d70ea0 in librealsense::unpack_yuy2<(rs2_format)5> (d=0x8bc014b8, 
    s=0x8f40c008 "{z}~}}~\200{\202{\201|\204z~~\202~\177|\201{\177|\201}\177|\202{\177}\201\200\177~\200~\177|\200y}{\200}}~\201}\177}\201|\201|\200~\202\177\200\202\203\202~~\201\200~\177\201\177~\201\201\201}}\202\177~\177\203~\177~\202\200|}\201~|\200\202\200|\202\202\177{}\201\200|\177\201\201}\202\200\200~\177\200|~\201\201\205{\205\201\201~\177\201\201\201\202\201\202\177\200\202\203~\177\202}\201\202\201\200\177\202\201\200~}\200\200}\177\200\177}\200\201\201\177\202\203\201\177\177\204}~~\201\200\177~\200\201~\201\201\202|\201\203\200}\200\204\177\201\200\203z~u\202u}x\202"..., width=640, height=480, actual_size=66312) at /home/pi/handheld3dscanner/librealsense/src/image.cpp:550
550             int16_t y[16] = {
(gdb) backtrace
#0  0xb2d70ea0 in librealsense::unpack_yuy2<(rs2_format)5>(unsigned char* const*, unsigned char const*, int, int, int)
    (d=0x8bc014b8, s=0x8f40c008 "{z}~}}~\200{\202{\201|\204z~~\202~\177|\201{\177|\201}\177|\202{\177}\201\200\177~\200~\177|\200y}{\200}}~\201}\177}\201|\201|\200~\202\177\200\202\203\202~~\201\200~\177\201\177~\201\201\201}}\202\177~\177\203~\177~\202\200|}\201~|\200\202\200|\202\202\177{}\201\200|\177\201\201}\202\200\200~\177\200|~\201\201\205{\205\201\201~\177\201\201\201\202\201\202\177\200\202\203~\177\202}\201\202\201\200\177\202\201\200~}\200\200}\177\200\177}\200\201\201\177\202\203\201\177\177\204}~~\201\200\177~\200\201~\201\201\202|\201\203\200}\200\204\177\201\200\203z~u\202u}x\202"..., width=640, height=480, actual_size=66312) at /home/pi/handheld3dscanner/librealsense/src/image.cpp:550
#1  0xb2de8aa0 in librealsense::uvc_sensor::<lambda(librealsense::platform::stream_profile, librealsense::platform::frame_object, std::function<void()>)>::operator()(librealsense::platform::stream_profile, librealsense::platform::frame_object, std::function<void()>) (__closure=0x8bc0a2e0, p=..., f=..., continuation=...) at /home/pi/handheld3dscanner/librealsense/src/sensor.cpp:536
#2  0xb2df196c in std::_Function_handler<void(librealsense::platform::stream_profile, librealsense::platform::frame_object, std::function<void()>), librealsense::uvc_sensor::open(const stream_profiles&)::<lambda(librealsense::platform::stream_profile, librealsense::platform::frame_object, std::function<void()>)> >::_M_invoke(const std::_Any_data &, librealsense::platform::stream_profile &&, librealsense::platform::frame_object &&, std::function<void()> &&) (__functor=..., __args#0=..., __args#1=..., __args#2=...) at /usr/include/c++/8/bits/std_function.h:297
#3  0xb2b15b10 in std::function<void (librealsense::platform::stream_profile, librealsense::platform::frame_object, std::function<void ()>)>::operator()(librealsense::platform::stream_profile, librealsense::platform::frame_object, std::function<void ()>) const (this=0x840a9c50, __args#0=..., __args#1=..., __args#2=...) at /usr/include/c++/8/bits/std_function.h:687
#4  0xb2c66b80 in librealsense::platform::libuvc_uvc_device::uvc_callback(uvc_frame*, std::function<void (librealsense::platform::stream_profile, librealsense::platform::frame_object, std::function<void ()>)>, librealsense::platform::stream_profile) (this=0xcf03f4, frame=0x28a7378, callback=..., profile=...) at /home/pi/handheld3dscanner/librealsense/src/libuvc/libuvc.cpp:658
#5  0xb2c5fc64 in librealsense::platform::internal_uvc_callback(uvc_frame_t*, void*) (frame=0x28a7378, ptr=0x28f1400) at /home/pi/handheld3dscanner/librealsense/src/libuvc/libuvc.cpp:723
#6  0xb2c5e3cc in _uvc_user_caller(void*) (arg=0x28a7260) at /home/pi/handheld3dscanner/librealsense/src/libuvc/stream.cpp:1221
#7  0xb2c5df34 in <lambda()>::operator()(void) const (__closure=0x25ee8bc) at /home/pi/handheld3dscanner/librealsense/src/libuvc/stream.cpp:1155
...
...

similar, if not identical, to issue #2942 , but the patch file provided in that thread is not compatible with the kernel v4.19

cause? probably because the raspberry pi is slow

I've come up with my bandaid solution

diff --git a/src/sensor.cpp b/src/sensor.cpp
index 408afcd3d..b12998c54 100644
--- a/src/sensor.cpp
+++ b/src/sensor.cpp
@@ -531,7 +531,7 @@ namespace librealsense
                     }

                     // Unpack the frame
-                    if (requires_processing && (dest.size() > 0))
+                    if (requires_processing && (dest.size() > 0) && f.frame_size >= (mode.profile.width * mode.profile.height))
                     {
                         unpacker.unpack(dest.data(), reinterpret_cast<const byte *>(f.pixels), mode.profile.width, mode.profile.height, f.frame_size);
                     }

That seems to have fixed the problem, it runs without segfault and I seem to be getting a continuous stream of video inside of rtabmap

Now... I actually have absolutely no idea what I actually did there, 640x480 is equal to 307200 and the GDB trace told me it was given 66312 but I have no idea if I have to account for bits per pixel in that if-statement

So please have a look, consider how to properly handle this scenario. I wish I could be of more assistance.

RealSenseCustomerSupport commented 4 years ago

Issue should be addressed with the latest librealsense master build. Please give it a try. We will close this issue unless otherwise. Thank you.