<h5 dir="auto">System information (version)</h5>
<ul dir="auto">
<li>OpenCV =&gt; 4.1.2</li>
<li>Operating System / Platform =&gt; Arch Linux</li>
<li>Compiler =&gt; g++ 9.2.0</li>
</ul>
<h5 dir="auto">Detailed description</h5>
<p dir="auto">I found that my application sometimes crashes on <code class="notranslate">readNetFromCaffe</code> with a segmentation fault. I believe it is caused by the opencv function not being thread safe while I call it multiple times concurrently.</p>
<h5 dir="auto">Steps to reproduce</h5>
<p dir="auto">Here is a simple test application that crashes around 10% of the runs. In my real application I have less threads (usually 2...16), but 1000 threads makes the test have this bug more frequently.</p>
<div class="highlight highlight-source-c++ notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#include &lt;thread&gt;
#include &lt;vector&gt;

#include &lt;opencv2/dnn.hpp&gt;

void test() {
    cv::dnn::readNetFromCaffe(..., ...);
}

int main() {
    std::vector&lt;std::thread&gt; threads;

    for (size_t i = 0; i &lt; 1000; ++i) {
        threads.emplace_back(test);
    }

    for (auto&amp; thread : threads) {
        thread.join();
    }
}"><pre class="notranslate">#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>thread<span class="pl-pds">&gt;</span></span>
#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>vector<span class="pl-pds">&gt;</span></span>

#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>opencv2/dnn.hpp<span class="pl-pds">&gt;</span></span>

<span class="pl-k">void</span> <span class="pl-en">test</span>() {
    <span class="pl-c1">cv::dnn::readNetFromCaffe</span>(..., ...);
}

<span class="pl-k">int</span> <span class="pl-en">main</span>() {
    std::vector&lt;std::thread&gt; threads;

    <span class="pl-k">for</span> (<span class="pl-c1">size_t</span> i = <span class="pl-c1">0</span>; i &lt; <span class="pl-c1">1000</span>; ++i) {
        threads.<span class="pl-c1">emplace_back</span>(test);
    }

    <span class="pl-k">for</span> (<span class="pl-k">auto</span>&amp; thread : threads) {
        thread.<span class="pl-c1">join</span>();
    }
}</pre></div>
<p dir="auto">Helgrind finds some issues from the application:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Possible data race during write of size 8 at 0x51EB5E8 by thread #2
Locks held: none
   at 0x4FA8F9E: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x492C0B2: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x5036473: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49CFF8B: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49D0477: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49C05AD: cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x1092DD: test() (in /home/runner/segfaulttest/main)
   by 0x10AE5B: void std::__invoke_impl&lt;void, void (*)()&gt;(std::__invoke_other, void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10ADFF: std::__invoke_result&lt;void (*)()&gt;::type std::__invoke&lt;void (*)()&gt;(void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10AD9D: void std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt;::_M_invoke&lt;0ul&gt;(std::_Index_tuple&lt;0ul&gt;) (in /home/runner/segfaulttest/main)
   by 0x10AD5E: std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt;::operator()() (in /home/runner/segfaulttest/main)
   by 0x10AD33: std::thread::_State_impl&lt;std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt; &gt;::_M_run() (in /home/runner/segfaulttest/main)

This conflicts with a previous read of size 8 by thread #3
Locks held: none
   at 0x492C047: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x5036473: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49CFF8B: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49D0477: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49C05AD: cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x1092DD: test() (in /home/runner/segfaulttest/main)
   by 0x10AE5B: void std::__invoke_impl&lt;void, void (*)()&gt;(std::__invoke_other, void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10ADFF: std::__invoke_result&lt;void (*)()&gt;::type std::__invoke&lt;void (*)()&gt;(void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
 Address 0x51eb5e8 is in the BSS segment of /usr/lib/libopencv_dnn.so.4.1.2

----------------------------------------------------------------

Possible data race during read of size 8 at 0x51EB5E8 by thread #3
Locks held: none
   at 0x4FA8FB6: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x492C0B2: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x5036473: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49CFF8B: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49D0477: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49C05AD: cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x1092DD: test() (in /home/runner/segfaulttest/main)
   by 0x10AE5B: void std::__invoke_impl&lt;void, void (*)()&gt;(std::__invoke_other, void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10ADFF: std::__invoke_result&lt;void (*)()&gt;::type std::__invoke&lt;void (*)()&gt;(void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10AD9D: void std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt;::_M_invoke&lt;0ul&gt;(std::_Index_tuple&lt;0ul&gt;) (in /home/runner/segfaulttest/main)
   by 0x10AD5E: std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt;::operator()() (in /home/runner/segfaulttest/main)
   by 0x10AD33: std::thread::_State_impl&lt;std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt; &gt;::_M_run() (in /home/runner/segfaulttest/main)

This conflicts with a previous write of size 8 by thread #2
Locks held: none
   at 0x4FA8F9E: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x492C0B2: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x5036473: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49CFF8B: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49D0477: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49C05AD: cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x1092DD: test() (in /home/runner/segfaulttest/main)
   by 0x10AE5B: void std::__invoke_impl&lt;void, void (*)()&gt;(std::__invoke_other, void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
 Address 0x51eb5e8 is in the BSS segment of /usr/lib/libopencv_dnn.so.4.1.2

..."><pre class="notranslate"><code class="notranslate">Possible data race during write of size 8 at 0x51EB5E8 by thread #2
Locks held: none
   at 0x4FA8F9E: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x492C0B2: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x5036473: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49CFF8B: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49D0477: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49C05AD: cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x1092DD: test() (in /home/runner/segfaulttest/main)
   by 0x10AE5B: void std::__invoke_impl&lt;void, void (*)()&gt;(std::__invoke_other, void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10ADFF: std::__invoke_result&lt;void (*)()&gt;::type std::__invoke&lt;void (*)()&gt;(void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10AD9D: void std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt;::_M_invoke&lt;0ul&gt;(std::_Index_tuple&lt;0ul&gt;) (in /home/runner/segfaulttest/main)
   by 0x10AD5E: std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt;::operator()() (in /home/runner/segfaulttest/main)
   by 0x10AD33: std::thread::_State_impl&lt;std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt; &gt;::_M_run() (in /home/runner/segfaulttest/main)

This conflicts with a previous read of size 8 by thread #3
Locks held: none
   at 0x492C047: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x5036473: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49CFF8B: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49D0477: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49C05AD: cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x1092DD: test() (in /home/runner/segfaulttest/main)
   by 0x10AE5B: void std::__invoke_impl&lt;void, void (*)()&gt;(std::__invoke_other, void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10ADFF: std::__invoke_result&lt;void (*)()&gt;::type std::__invoke&lt;void (*)()&gt;(void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
 Address 0x51eb5e8 is in the BSS segment of /usr/lib/libopencv_dnn.so.4.1.2

----------------------------------------------------------------

Possible data race during read of size 8 at 0x51EB5E8 by thread #3
Locks held: none
   at 0x4FA8FB6: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x492C0B2: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x5036473: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49CFF8B: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49D0477: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49C05AD: cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x1092DD: test() (in /home/runner/segfaulttest/main)
   by 0x10AE5B: void std::__invoke_impl&lt;void, void (*)()&gt;(std::__invoke_other, void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10ADFF: std::__invoke_result&lt;void (*)()&gt;::type std::__invoke&lt;void (*)()&gt;(void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
   by 0x10AD9D: void std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt;::_M_invoke&lt;0ul&gt;(std::_Index_tuple&lt;0ul&gt;) (in /home/runner/segfaulttest/main)
   by 0x10AD5E: std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt;::operator()() (in /home/runner/segfaulttest/main)
   by 0x10AD33: std::thread::_State_impl&lt;std::thread::_Invoker&lt;std::tuple&lt;void (*)()&gt; &gt; &gt;::_M_run() (in /home/runner/segfaulttest/main)

This conflicts with a previous write of size 8 by thread #2
Locks held: none
   at 0x4FA8F9E: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x492C0B2: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x5036473: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49CFF8B: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49D0477: ??? (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x49C05AD: cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) (in /usr/lib/libopencv_dnn.so.4.1.2)
   by 0x1092DD: test() (in /home/runner/segfaulttest/main)
   by 0x10AE5B: void std::__invoke_impl&lt;void, void (*)()&gt;(std::__invoke_other, void (*&amp;&amp;)()) (in /home/runner/segfaulttest/main)
 Address 0x51eb5e8 is in the BSS segment of /usr/lib/libopencv_dnn.so.4.1.2

...
</code></pre></div>
<p dir="auto">Here is also a gdb backtrace of the segmentation fault. Unfortunately I didn't have opencv symbols enabled, when I managed to reproduce the crash with gdb. It seems that running the application in gdb makes the bug very rare:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="#0  0x00007fd9ce450470 in free () at /usr/lib/libc.so.6
#1  0x00007fd9d28584bc in  () at /usr/lib/libopencv_dnn.so.4.1
#2  0x00007fd9d285a528 in  () at /usr/lib/libopencv_dnn.so.4.1
#3  0x00007fd9d285c604 in cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) () at /usr/lib/libopencv_dnn.so.4.1"><pre class="notranslate"><code class="notranslate">#0  0x00007fd9ce450470 in free () at /usr/lib/libc.so.6
#1  0x00007fd9d28584bc in  () at /usr/lib/libopencv_dnn.so.4.1
#2  0x00007fd9d285a528 in  () at /usr/lib/libopencv_dnn.so.4.1
#3  0x00007fd9d285c604 in cv::dnn::dnn4_v20190902::readNetFromCaffe(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;) () at /usr/lib/libopencv_dnn.so.4.1
</code></pre></div>
<h5 dir="auto">System information (version)</h5>

<ul dir="auto">
<li>OpenCV =&gt; 4.1.2</li>
<li>Operating System / Platform =&gt; Gentoo Linux</li>
<li>Compiler =&gt; gcc (Gentoo 8.3.0-r1 p1.1) 8.3.0</li>
</ul>
<h5 dir="auto">Detailed description</h5>
<p dir="auto">With OpenCV-4.1.2 I've started to get random segfaults in multi-threaded program. I've managed to reproduce the problem with the very basic application, 2 threads where each of them just creates a Mat.</p>
<h5 dir="auto">Steps to reproduce</h5>
<div class="highlight highlight-source-c++ notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#include &lt;opencv2/core.hpp&gt;
#include &lt;thread&gt;

using namespace std;
using namespace cv;

void thread1() {
    Mat(10, 10, CV_16U, Scalar(0));
}

void thread2() {
    Mat(10, 10, CV_16U, Scalar(0));
}

int main() {
    thread th1(thread1);
    thread th2(thread2);
    th1.join();
    th2.join();
    return 0;
}"><pre class="notranslate">#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>opencv2/core.hpp<span class="pl-pds">&gt;</span></span>
#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>thread<span class="pl-pds">&gt;</span></span>

<span class="pl-k">using</span> <span class="pl-k">namespace</span> <span class="pl-en">std</span><span class="pl-k">;</span>
<span class="pl-k">using</span> <span class="pl-k">namespace</span> <span class="pl-en">cv</span><span class="pl-k">;</span>

<span class="pl-k">void</span> <span class="pl-en">thread1</span>() {
    <span class="pl-c1">Mat</span>(<span class="pl-c1">10</span>, <span class="pl-c1">10</span>, CV_16U, <span class="pl-c1">Scalar</span>(<span class="pl-c1">0</span>));
}

<span class="pl-k">void</span> <span class="pl-en">thread2</span>() {
    <span class="pl-c1">Mat</span>(<span class="pl-c1">10</span>, <span class="pl-c1">10</span>, CV_16U, <span class="pl-c1">Scalar</span>(<span class="pl-c1">0</span>));
}

<span class="pl-k">int</span> <span class="pl-en">main</span>() {
    thread <span class="pl-smi">th1</span>(thread1);
    thread <span class="pl-smi">th2</span>(thread2);
    th1.<span class="pl-c1">join</span>();
    th2.<span class="pl-c1">join</span>();
    <span class="pl-k">return</span> <span class="pl-c1">0</span>;
}</pre></div>
<p dir="auto">When compiled with:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="g++ -g $(pkg-config --libs --cflags opencv4) -lpthread test-crash-412.cpp -o test"><pre class="notranslate">g++ -g <span class="pl-s"><span class="pl-pds">$(</span>pkg-config --libs --cflags opencv4<span class="pl-pds">)</span></span> -lpthread test-crash-412.cpp -o <span class="pl-c1">test</span></pre></div>
<p dir="auto">Will randomly crash or exit normally when run. To get a more stable repro, please run several times:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="while true; do ./test; done"><pre class="notranslate"><span class="pl-k">while</span> <span class="pl-c1">true</span><span class="pl-k">;</span> <span class="pl-k">do</span> ./test<span class="pl-k">;</span> <span class="pl-k">done</span></pre></div>
<p dir="auto">Running the same binary (without recompilation) against OpenCV-4.1.1 works fine without any crashes.</p>
<p dir="auto">This is the stack trace I see:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Stack trace of thread 19341:
#0  0x00007f07d1dd9b50 cfree (libc.so.6)
#1  0x00007f07d256a5b9 n/a (/home/pro/projects/opencv-lib/opencv-4.1/install/lib64/libopencv_core.so.4.1.2)
#2  0x000055e3320da48c n/a (/tmp/test)
#3  0x000055e3320da2b8 n/a (/tmp/test)
#4  0x000055e3320da9ff n/a (/tmp/test)
#5  0x000055e3320da7f9 n/a (/tmp/test)
#6  0x000055e3320daf02 n/a (/tmp/test)
#7  0x000055e3320daec3 n/a (/tmp/test)
#8  0x000055e3320dae98 n/a (/tmp/test)
#9  0x00007f07d2159cae execute_native_thread_routine (libstdc++.so.6)
#10 0x00007f07d2288458 start_thread (libpthread.so.0)
#11 0x00007f07d1e546ef __clone (libc.so.6)"><pre class="notranslate"><code class="notranslate">Stack trace of thread 19341:
#0  0x00007f07d1dd9b50 cfree (libc.so.6)
#1  0x00007f07d256a5b9 n/a (/home/pro/projects/opencv-lib/opencv-4.1/install/lib64/libopencv_core.so.4.1.2)
#2  0x000055e3320da48c n/a (/tmp/test)
#3  0x000055e3320da2b8 n/a (/tmp/test)
#4  0x000055e3320da9ff n/a (/tmp/test)
#5  0x000055e3320da7f9 n/a (/tmp/test)
#6  0x000055e3320daf02 n/a (/tmp/test)
#7  0x000055e3320daec3 n/a (/tmp/test)
#8  0x000055e3320dae98 n/a (/tmp/test)
#9  0x00007f07d2159cae execute_native_thread_routine (libstdc++.so.6)
#10 0x00007f07d2288458 start_thread (libpthread.so.0)
#11 0x00007f07d1e546ef __clone (libc.so.6)
</code></pre></div>