Where is the data race with imread and cvtColor?

  c++, multithreading, opencv

According to ThreadSanitizer, I have a data race in the following code.

#include <iostream>
#include <opencv2/imgcodecs.hpp>  // cv::imread
#include <opencv2/imgproc.hpp>    // cv::cvtColor, cv::COLOR_BGR2HSV
#include <string>

cv::Mat hsvImage(const std::string& file) {
  const cv::Mat im = cv::imread(file);
  if (im.empty()) {
    return im;
  }

  cv::Mat conv;
  cv::cvtColor(im, conv, cv::COLOR_BGR2HSV);
  return conv;
}

int main() {
  const cv::Mat img = hsvImage("img.png");
  if (img.empty()) {
    std::cout << "failed to get hsv image" << std::endl;
    return 1;
  }

  return 0;
}

Here’s the result of running the code.

$ ./bin/main
==================
WARNING: ThreadSanitizer: data race (pid=9735)
  Write of size 8 at 0x7b2000000100 by thread T6:
    #0 operator delete[](void*) <null> (main+0xe07d7)
    #1 <null> <null> (libtbb.so.2+0x23236)

  Previous read of size 8 at 0x7b2000000100 by thread T2:
    #0 memcmp <null> (main+0x98cf0)
    #1 <null> <null> (libtbb.so.2+0x214a4)

  Thread T6 (tid=9742, running) created by thread T2 at:
    #0 pthread_create <null> (main+0x9337a)
    #1 <null> <null> (libtbb.so.2+0x206e0)

  Thread T2 (tid=9738, finished) created by main thread at:
    #0 pthread_create <null> (main+0x9337a)
    #1 <null> <null> (libtbb.so.2+0x206e0)
    #2 main /home/user/main.cpp:18:23 (main+0xe1794)

SUMMARY: ThreadSanitizer: data race (/home/user/bin/main+0xe07d7) in operator delete[](void*)
==================
ThreadSanitizer: reported 1 warnings

This is how I’m compiling.

clang++ -std=c++17 
    $(pkg-config --cflags --libs opencv4) 
    -O1 -g -fsanitize=thread -fno-omit-frame-pointer 
    -fsanitize=signed-integer-overflow,null,alignment 
    -fno-sanitize-recover=null -fsanitize-trap=alignment 
    -Wunused-value -Wshadow 
    -o main main.cpp

It seems like it has something to do with one (or both) of the cv::Mat objects being cleaned up at the end of hsvImage, although, I thought it was being copied back up to the caller on return.

Source: Windows Questions C++

LEAVE A COMMENT