opencv / opencv_contrib

Repository for OpenCV's extra modules
Apache License 2.0
9.36k stars 5.75k forks source link

wechat_qrcode multithreading issue in global_histogram_binarizer.cpp #3405

Open nxt007 opened 1 year ago

nxt007 commented 1 year ago
System information (version)
Detailed description

In file opencv_contrib-4.6.0/modules/wechat_qrcode/src/zxing/common/binarizer/global_histogram_binarizer.cpp there is global shared state in line 18, which causing segfault in case of multithreading.

Steps to reproduce

Flaky to reproduce. In my case, one of 4 test runs with 8 threads simultaneously processing same image with same WeChatQRCode instance for around 15 sec cause segfault.

Cant provide image due to NDA. Any small image like 120 * 50 should be fine, I guess.

{
    auto index = 0;
    auto image = mats[index];

    bool finish = false;
    std::atomic_uint32_t counter;
    std::vector<std::thread> threads;

    cv::WeChatQRCode decoder;
    for (size_t i = 0; i < 8; ++i) {
        threads.emplace_back([&] {
            while (!finish) {
                decoder.detectAndDecode(image, {});
                auto val = counter++;
                if (val % 100 == 0) {
                    std::cout << val << std::endl;
                }
            }
        });
    }

    while (counter < 7000) {
        sleep(1);
    }

    finish = true;
    for (auto& t : threads) {
        t.join();
    }
}
How to fix:

Wipe out this shared variable and initialize luminances var with default ctor. Also add check for !luminances in line 29.

Issue submission checklist
misu99 commented 9 months ago

I have the same problem

YoungZH-code commented 5 months ago

I also met this problem. The Implement of shared ArrayRef is not safe in multithreads. The Solution mentioned by @nxt007 Is Right. The global Shared ArrayRef EMPTY should not used In multithread.