Valgrind hlásí data race v boost::thread

asd

Valgrind hlásí data race v boost::thread
« kdy: 10. 12. 2011, 13:47:50 »
Caute,

Kód: [Vybrat]
#include <iostream>
#include <boost/thread.hpp>

using namespace std;
using namespace boost;

void worker()
{
cout << "hello from thread\n";
}

int main()
{
thread workerThread(worker);
workerThread.join();

return 0;
}

program vytvori thread, ktory vola funkciu worker a joine thread

vystup valgrindu:

Kód: [Vybrat]
$ valgrind --leak-check=full --show-reachable=yes ./thrd
==5341== Memcheck, a memory error detector
==5341== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==5341== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==5341== Command: ./thrd
==5341==
hello from thread
==5341==
==5341== HEAP SUMMARY:
==5341==     in use at exit: 8 bytes in 1 blocks
==5341==   total heap usage: 7 allocs, 6 frees, 808 bytes allocated
==5341==
==5341== 8 bytes in 1 blocks are still reachable in loss record 1 of 1
==5341==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5341==    by 0x4E40ED9: boost::detail::get_once_per_thread_epoch() (in /usr/lib/libboost_thread.so.1.46.1)
==5341==    by 0x4E39DCF: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5341==    by 0x4E3A098: boost::detail::get_current_thread_data() (in /usr/lib/libboost_thread.so.1.46.1)
==5341==    by 0x4E3B80A: boost::thread::join() (in /usr/lib/libboost_thread.so.1.46.1)
==5341==    by 0x403073: main (thrd.cpp:15)
==5341==
==5341== LEAK SUMMARY:
==5341==    definitely lost: 0 bytes in 0 blocks
==5341==    indirectly lost: 0 bytes in 0 blocks
==5341==      possibly lost: 0 bytes in 0 blocks
==5341==    still reachable: 8 bytes in 1 blocks
==5341==         suppressed: 0 bytes in 0 blocks
==5341==
==5341== For counts of detected and suppressed errors, rerun with: -v
==5341== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

vystup valgrindu-helgrind:

Kód: [Vybrat]
$ valgrind --tool=helgrind ./thrd
==5355== Helgrind, a thread error detector
==5355== Copyright (C) 2007-2010, and GNU GPL'd, by OpenWorks LLP et al.
==5355== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==5355== Command: ./thrd
==5355==
==5355== Thread #1 is the program's root thread
==5355==
==5355== Thread #2 was created
==5355==    at 0x58B932E: clone (clone.S:77)
==5355==    by 0x5B6EDBF: T.124 (createthread.c:75)
==5355==    by 0x5B6F2BA: pthread_create@@GLIBC_2.2.5 (createthread.c:256)
==5355==    by 0x4C2889D: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5355==    by 0x4E3C48E: boost::thread::start_thread() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x404431: boost::thread::thread<void (*)()>(void (*)(), boost::disable_if<boost::is_convertible<void (*&)(), boost::detail::thread_move_t<void (*)()> >, boost::thread::dummy*>::type) (thread.hpp:204)
==5355==    by 0x403067: main (thrd.cpp:14)
==5355==
==5355== Possible data race during read of size 4 at 0x50479e8 by thread #1
==5355==    at 0x4E42EB4: boost::detail::get_once_per_thread_epoch() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3BDCF: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C098: boost::detail::get_current_thread_data() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3D80A: boost::thread::join() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x403073: main (thrd.cpp:15)
==5355==  This conflicts with a previous write of size 4 by thread #2
==5355==    at 0x5B7426B: pthread_key_create (pthread_key_create.c:44)
==5355==    by 0x5B7481F: pthread_once (pthread_once.S:104)
==5355==    by 0x4E42EB3: boost::detail::get_once_per_thread_epoch() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3BDCF: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C0B8: boost::detail::set_current_thread_data(boost::detail::thread_data_base*) (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C5AE: thread_proxy (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4C28A2D: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5355==    by 0x5B6EB3F: start_thread (pthread_create.c:304)
==5355==
==5355== Possible data race during read of size 4 at 0x50479e8 by thread #1
==5355==    at 0x4E42EDA: boost::detail::get_once_per_thread_epoch() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3BDCF: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C098: boost::detail::get_current_thread_data() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3D80A: boost::thread::join() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x403073: main (thrd.cpp:15)
==5355==  This conflicts with a previous write of size 4 by thread #2
==5355==    at 0x5B7426B: pthread_key_create (pthread_key_create.c:44)
==5355==    by 0x5B7481F: pthread_once (pthread_once.S:104)
==5355==    by 0x4E42EB3: boost::detail::get_once_per_thread_epoch() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3BDCF: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C0B8: boost::detail::set_current_thread_data(boost::detail::thread_data_base*) (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C5AE: thread_proxy (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4C28A2D: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5355==    by 0x5B6EB3F: start_thread (pthread_create.c:304)
==5355==
==5355== Possible data race during write of size 8 at 0x5047970 by thread #1
==5355==    at 0x4E3BE53: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C098: boost::detail::get_current_thread_data() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3D80A: boost::thread::join() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x403073: main (thrd.cpp:15)
==5355==  This conflicts with a previous read of size 8 by thread #2
==5355==    at 0x4E3BDC4: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C0B8: boost::detail::set_current_thread_data(boost::detail::thread_data_base*) (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C5AE: thread_proxy (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4C28A2D: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5355==    by 0x5B6EB3F: start_thread (pthread_create.c:304)
==5355==    by 0x58B936C: clone (clone.S:112)
==5355==
==5355== Possible data race during write of size 8 at 0x5047970 by thread #1
==5355==    at 0x4E3BE99: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C098: boost::detail::get_current_thread_data() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3D80A: boost::thread::join() (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x403073: main (thrd.cpp:15)
==5355==  This conflicts with a previous read of size 8 by thread #2
==5355==    at 0x4E3BDC4: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C0B8: boost::detail::set_current_thread_data(boost::detail::thread_data_base*) (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4E3C5AE: thread_proxy (in /usr/lib/libboost_thread.so.1.46.1)
==5355==    by 0x4C28A2D: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5355==    by 0x5B6EB3F: start_thread (pthread_create.c:304)
==5355==    by 0x58B936C: clone (clone.S:112)
==5355==
hello from thread
==5355==
==5355== For counts of detected and suppressed errors, rerun with: -v
==5355== Use --history-level=approx or =none to gain increased speed, at
==5355== the cost of reduced accuracy of conflicting-access information
==5355== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 36 from 36)

cize chcel by som sa spytat ci je toto bug v boost::thread a nevsimat si tieto hlasenia, alebo mam chybu vo svojom kode a ten thread by sa mal nejako specialne ukoncovat a nestaci mu len svoj vlastny destruktor?

pouzivam boost v1.46.1.1, valgrind v3.6.1

Diky za odpovede
« Poslední změna: 12. 12. 2011, 12:30:46 od Petr Krčmář »


asd

Re:boost::thread a valgrind hlasiaci data race
« Odpověď #1 kdy: 10. 12. 2011, 15:27:15 »
dokumentacia valgrindu - http://www.valgrind.org/docs/manual/hg-manual.html#hg-manual.data-races
tak som teda dal mutex:

Kód: [Vybrat]
#include <iostream>
#include <boost/thread.hpp>

using namespace std;
using namespace boost;

mutex g_mutex;

void worker()
{
mutex::scoped_lock lock(g_mutex);
cout << "HELLO THREAD\n";
}

int main()
{
thread workerThread(worker);
workerThread.join();

return 0;
}

a vysledok bol ten isty. Ked som ale z tela funkcie worker vsetko vymazal tak errory o data race-i zmizli takze asi vytvaram mutexi nespravne, ale ten leak tam je stale.

nhx

Re:boost::thread a valgrind hlasiaci data race
« Odpověď #2 kdy: 10. 12. 2011, 16:14:05 »
dokumentacia valgrindu - http://www.valgrind.org/docs/manual/hg-manual.html#hg-manual.data-races
tak som teda dal mutex:

Kód: [Vybrat]
#include <iostream>
#include <boost/thread.hpp>

using namespace std;
using namespace boost;

mutex g_mutex;

void worker()
{
mutex::scoped_lock lock(g_mutex);
cout << "HELLO THREAD\n";
}

int main()
{
thread workerThread(worker);
workerThread.join();

return 0;
}

a vysledok bol ten isty. Ked som ale z tela funkcie worker vsetko vymazal tak errory o data race-i zmizli takze asi vytvaram mutexi nespravne, ale ten leak tam je stale.

K cemu ma slouzit mutex uzamykany v jednom vlakne?

asd

Re:boost::thread a valgrind hlasiaci data race
« Odpověď #3 kdy: 10. 12. 2011, 16:22:49 »
no samozrejme v tomto pripade k nicomu
"A data race happens, or could happen, when two threads access a shared memory location without using suitable locks or other synchronisation to ensure single-threaded access."
cout je shared resource a samozrejme by mal byt uzamknuty ale kedze mam len 1 thread tak je to zbytocne...tak ci tak podla mna tam nema preco hadzat tie errory a ten mutex bol len pokus ci by to nahodou nevyriesilo tie chyby ktore vypisuje valgrind

asd

Re:boost::thread a valgrind hlasiaci data race
« Odpověď #4 kdy: 11. 12. 2011, 10:11:18 »
tak prehnal som to cez gdb:
moj posledny post je blbost z toho dovodu ze (ak sa mylim tak ma plz opravte) ked si vytvorim objekt thread tak jeho konstruktor uz rovno ten naozajstny thread aj vytvori a metoda join() ho synchronizuje s "master threadom". Cize teoreticky ak by som mal nejaky kod (napr by som pouzil ten cout) medzi vytvorenim threadu a volanim metody join tak by tam mohol vzniknut data race pretoze by poradie vykonavania cout v tom novom threade a v master threade zaviselo len od toho ktory z tychto 2 threadov sa vykona rychlejsie -> mal by som tam pouzit mutex (ale v tomto pripade to naozaj netreba). No a to gdb

Kód: [Vybrat]
(gdb) start
Temporary breakpoint 1 at 0x402f83: file thrd.cpp, line 13.
Starting program: /home/gman/docs/thread/thrd
[Thread debugging using libthread_db enabled]

Temporary breakpoint 1, main () at thrd.cpp:13
13 thread workerThrd(worker);
(gdb) n
[New Thread 0x7ffff6c7f700 (LWP 2527)]
14 workerThrd.join();
(gdb)
[Thread 0x7ffff6c7f700 (LWP 2527) exited]
16 return 0;
(gdb)
13 thread workerThrd(worker);
(gdb)
17 }
(gdb)
__libc_start_main (main=<optimized out>, argc=<optimized out>, ubp_av=<optimized out>, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe588) at libc-start.c:260
260 libc-start.c: Adresár alebo súbor neexistuje.
in libc-start.c
(gdb)
[Inferior 1 (process 2524) exited normally]

takze ako som hovoril, zbehne na riadok 13, vytvori sa novy thread, riadok 14 ho synchronizuje s master threadom, thread sa ukonci, ide na riadok 16 kde by mal byt uz koniec programu. Ale nieeeeee naco by sa to ukoncovalo ked moze ist na riadok 13!..toto by taktiez mozno vysvetlovalo ten leak ktory detekoval valgrind ale nechapem preco toto robi


Jarda123

Re:boost::thread a valgrind hlasiaci data race
« Odpověď #5 kdy: 11. 12. 2011, 13:21:04 »
Skok na řádek 13 je skok na destruktor workerThrd-u, nic víc.