Unknowable bug on "ROS_INFO", Bus error and Segmentation fault
Hello, experts. I have a bug on my code.
When it reach functions as ROS_INFO or assignment values, this bug log "Bus error (core dumped)" or "Segmentation fault (core dumped)" or "Aborted (core dumped)".
I want to test it more accurately, but it is not easy to debug because I get an error in one of the thousands of cases in the Bag file.
Briefly, it is a function that it convert points position with matrix. I attached the code.
// Conver a point from a Lidar point to a Image point
void Fusion::Conversion::points2img(const Fusion::Point &_lidar_pt, const cv::Mat &projection_matrix, cv::Point2f &_point){
cv::Mat pt_3D(4, 1, CV_32FC1);
float *pt_3D_data = (float*) pt_3D.data;
pt_3D_data[0] = _lidar_pt.x;
pt_3D_data[1] = _lidar_pt.y;
pt_3D_data[2] = _lidar_pt.z;
pt_3D_data[3] = 1.0f;
ROS_INFO("Check Error 0: %f, 1: %f, 2: %f, 4: %f", (float)pt_3D.data[0], (float)pt_3D.data[1], (float)pt_3D.data[2], (float)pt_3D.data[3]);
cv::Mat pt_2D = projection_matrix * pt_3D;
float *pt_2D_data = (float*) pt_2D.data;
ROS_INFO("Check Error 0 1: %f, 1: %f, 2: %f", (float)pt_2D.data[0], (float)pt_2D.data[1], (float)pt_2D.data[2]);
float w = pt_2D_data[2];
ROS_INFO("w %f", w);
float y = pt_2D_data[0] / w;
ROS_INFO("y %f", y);
float x = pt_2D_data[1] / w;
ROS_INFO("x %f", x);
cv::Point2f result(y, x);
_point = result;
return;
}
The error was caused on float w = pt_2D_data[2];
or float w = pt_2D_data[2];
or other ROS_INFO functions.
Below is the error log.
*** Error in `/PATH/conversion/conversion_points2img_node': corrupted double-linked list: 0x000000000343b2d0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f1fd7b317e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82970)[0x7f1fd7b3c970]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7f1fd7b3e184]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_Znwm+0x18)[0x7f1fd8127e78]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7reserveEm+0x7d)[0x7f1fd81b987d]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi+0xe5)[0x7f1fd81adcd5]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKcl+0x89)[0x7f1fd81b7e79]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE13_M_insert_intImEES3_S3_RSt8ios_basecT_+0xf4)[0x7f1fd819d214]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecm+0xd)[0x7f1fd819d36d]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSo9_M_insertImEERSoT_+0xca)[0x7f1fd81a969a]
/opt/ros/kinetic/lib/librostime.so(_ZN3roslsERSoRKNS_8WallTimeE+0xae)[0x7f1fd6b391ae]
/opt/ros/kinetic/lib/librosconsole.so(_ZN3ros7console9TimeToken9getStringB5cxx11EPvNS0_6levels5LevelEPKcS6_S6_i+0x4a)[0x7f1fd8d735fa]
/opt/ros/kinetic/lib/librosconsole.so(_ZN3ros7console9Formatter5printEPvNS0_6levels5LevelEPKcS6_S6_i+0x13b)[0x7f1fd8d6fc3b]
/opt/ros/kinetic/lib/librosconsole.so(_ZN3ros7console6_printEPvNS0_6levels5LevelEPKcS5_S5_i+0x20)[0x7f1fd8d6fde0]
/opt/ros/kinetic/lib/librosconsole_log4cxx.so(_ZN3ros7console4impl23ROSConsoleStdioAppender6appendERKN7log4cxx7helpers10ObjectPtrTINS3_3spi12LoggingEventEEERNS4_4PoolE+0x1e2)[0x7f1fd60c9322]
/usr/lib/x86_64-linux-gnu/liblog4cxx.so.10(_ZN7log4cxx16AppenderSkeleton8doAppendERKNS_7helpers10ObjectPtrTINS_3spi12LoggingEventEEERNS1_4PoolE+0x226)[0x7f1fd5bab9b6]
/usr/lib/x86_64-linux-gnu/liblog4cxx.so.10(_ZN7log4cxx7helpers22AppenderAttachableImpl21appendLoopOnAppendersERKNS0_10ObjectPtrTINS_3spi12LoggingEventEEERNS0_4PoolE+0x3f)[0x7f1fd5ba96af]
/usr/lib/x86_64-linux-gnu/liblog4cxx.so.10(_ZNK7log4cxx6Logger13callAppendersERKNS_7helpers10ObjectPtrTINS_3spi12LoggingEventEEERNS1_4PoolE+0xe8)[0x7f1fd5bf1428]
/usr/lib/x86_64-linux-gnu/liblog4cxx.so.10(_ZNK7log4cxx6Logger9forcedLogERKNS_7helpers10ObjectPtrTINS_5LevelEEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3spi12LocationInfoE+0xbe)[0x7f1fd5bf167e]
/opt/ros/kinetic/lib/librosconsole_log4cxx.so(_ZN3ros7console4impl5printEPvNS0_6levels5LevelEPKcS6_S6_i+0x8b)[0x7f1fd60c609b]
/opt/ros/kinetic/lib/librosconsole.so(_ZN3ros7console5printEPNS0_10FilterBaseEPvNS0_6levels5LevelEPKciS7_S7_z+0x1a9)[0x7f1fd8d70549]
...
...
gdb debuger log
Thread 1 "conversion_poin" received signal SIGSEGV, Segmentation fault. malloc_consolidate (av=av@entry=0x7ffff59f8b20 <main_arena>) at malloc.c:4167 4167 malloc.c: No such file or directory.
I do not know how to solve this problem. Has anyone experienced a similar problem?
UPDATE: I fixed this problem.
But, I didn't find reason for this issue.
When I developed this function at first time, I used Mat.at
member function to access it's data.
I had missed changing one of at()
function to Mat.data[]
in overall code.
I changed it to Mat.data[]
. After that, the bug was fixed.
I'm sorry about that I can not have provided clear environmental specifications for this troubleshooting.
Thanks.
Asked by harderthan on 2018-08-20 04:23:19 UTC
Answers
The problem is this line here:
float pt_3D_data = (float) pt_3D.data;
pt_3D.data is a pointer to the start of the data your casting this to a float storing it in a float and then trying to use it as a pointer. This is all over the place and I'm surprised it compiles tbh.
It should be:
float *pt_3D_data = pt_3D.data;
EDIT: Okay that's updated now.
I really recommend you use the cv::Mat::at methods to access and update the elements of the cv::Mat object this is exactly what they're for, accessing the data directly and casting pointers all over the place is going to cause you a world of pain.
The data property of the Mat object has a type of uchar*
so when you index it with an lvalue using [2]
you're adding two bytes to it not (2 * sizeof(float)), you're then casting a non-aligned pointer to a float* which if nothing else if going to give you garbage values. All in all stick to the at
methods unless performance is really important to you.
UPDATE:
If you really need to access the data directly fair enough, but get the code working correctly with at
methods first then optimise the code from this point where you know it's working.
Having said that. The code (float)pt_2D.data[2]
seems to be attempting to get the 3rd element of a 2 element vector! Which you would expect to crash you code, you seem to have copy and pasted the code to print out the 3D vector without removing the last element.
Asked by PeteBlackerThe3rd on 2018-08-20 04:34:10 UTC
Comments
Hello, @PeteBlackerThe3rd.
Thank for your answer.
First of all, could you check this link.
It show us the way to use Mat.data
with a pointer.
I have a issue about real-time processing.
So, I didn't use Mat.at
Asked by harderthan on 2018-08-20 08:30:39 UTC
By the way, I guesss that you maybe looked wrong code.
float *pt_3D_data = (float*) pt_3D.data;
-> float pt_3D_data = (float) pt_3D.data;
Asked by harderthan on 2018-08-20 08:30:50 UTC
I fixed this issue.
Asked by harderthan on 2018-08-20 21:41:40 UTC
Comments
ADD:
I can sure about that the type of
const Fusion::Point _lidar_pt
's member arefloat
.Asked by harderthan on 2018-08-20 08:33:08 UTC