| Summary: | False positive in libstdc++ std::list::push_back | ||
|---|---|---|---|
| Product: | [Developer tools] valgrind | Reporter: | ewirch <wirch.eduard> |
| Component: | drd | Assignee: | Bart Van Assche <bart.vanassche+kde> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | ||
| Priority: | NOR | ||
| Version First Reported In: | 3.9.0.SVN | ||
| Target Milestone: | --- | ||
| Platform: | Ubuntu | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
| Attachments: | drd r13688 conflict trace for 0x64341a8 | ||
Can you tell me the version number of the Linaro distribution that you are using ? I'd like to install Linaro myself in order to reproduce this. So far I have not yet been able to reproduce this issue with the test program provided above neither on Ubuntu 13.04 nor on openSUSE 12.3. > lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 12.10
Release: 12.10
Codename: quantal
Ubuntu package versions:
gcc 4:4.7.2-1ubuntu2
g++ 4:4.7.2-1ubuntu2
libstdc++6 4.7.2-2ubuntu1
libc6 2.15-0ubuntu20.2
It looks like setlocale plays an important role. When I change the setlocale line in the test case to:
setlocale(LC_ALL, NULL);
OR
setlocale(LC_ALL, "C");
OR something invalid. DRD will not report any errors.
I found a second value, which will also trigger the error: "German". Both values are reported by
locale -a -v
in the "language" fields on my system. So maybe you first check the locales installed on your test system.
A candidate fix has been checked in on the trunk as r13679. Does that help ? Update: the real fix for this issue is in trunk r13686. Sorry, the same errors are being reported. Eduard, it would help a lot if you could do the following:
* Double check that your local copy of the Valgrind Subversion repository is up to date and that Valgrind has been rebuilt and reinstalled properly after the most recent update.
* Reproduce this issue.
* Copy the first address for which DRD reports a conflicting access.
* Rerun the test with the following additional DRD options (where ${addr} is the address that has been copied in the previous step): --read-var-info=yes --ptrace-addr=${addr}
* If the new run reports a conflicting access on the same address, store the DRD output in a text file and attach it to this bug ticket.
* If the new run reported a conflicting access on a different address, try a few times more until the first reported conflicting access is for the address specified via --ptrace-addr.
Created attachment 83073 [details]
drd r13688 conflict trace for 0x64341a8
Sure thing. I made sure I'm using the current code by invoking "svn status -u" and by modifying the version number in configure.ac. After building and installing valgrind --version reports: valgrind-3.9.0.SVN.r13688 Error reports strill occur. Created a trace and attached. Thanks. Apparently an stpcpy() intercept was missing in drd. Such an intercept has been added in r13694. Does that help ? Nice, errors are gone. For future bug reports: is a trace of the conflicting address is enough, or do you need a test case? A test case is preferred. The trick with --ptrace-addr only works if a false positive report is caused by a missing intercept. |
Valgrind r13670 Compiled using default configuration. GCC-Information: g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 Reproducible: 8 out of 10 runs Reproducible: Sometimes Steps to Reproduce: 1. Compile test case: g++ -std=c++11 -O0 -g test.cpp -lpthread -o test 2. Test it: valgrind --tool=drd ./test 3. Two errors are being reported: Actual Results: ==3334== Thread 2: ==3334== Conflicting store by thread 2 at 0x06433548 size 8 ==3334== at 0x401803: std::_List_node<int*>::_List_node<int*>(int*&&) (stl_list.h:115) ==3334== by 0x401786: _ZN9__gnu_cxx13new_allocatorISt10_List_nodeIPiEE9constructIS3_IS2_EEEvPT_DpOT0_ (in /home/factfinder/edu/ff-lib-test/test) ==3334== by 0x4016A1: std::_List_node<int*>* std::list<int*, std::allocator<int*> >::_M_create_node<int*>(int*&&) (stl_list.h:503) ==3334== by 0x40157B: void std::list<int*, std::allocator<int*> >::_M_insert<int*>(std::_List_iterator<int*>, int*&&) (stl_list.h:1533) ==3334== by 0x40137E: std::list<int*, std::allocator<int*> >::push_back(int*&&) (stl_list.h:1002) ==3334== by 0x40114D: SubTest::subTest() (test.cpp:25) ==3334== by 0x40129C: Test::func1() (test.cpp:49) ==3334== by 0x400D97: func1(void*) (test.cpp:62) ==3334== by 0x4C2EDA4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355) ==3334== by 0x4E48E99: start_thread (pthread_create.c:308) ==3334== by 0x566ACCC: clone (clone.S:112) ==3334== Address 0x6433548 is at offset 8 from 0x6433540. Allocation context: ==3334== at 0x4C2E30B: operator new(unsigned long) (vg_replace_malloc.c:319) ==3334== by 0x4017E0: __gnu_cxx::new_allocator<std::_List_node<int*> >::allocate(unsigned long, void const*) (new_allocator.h:94) ==3334== by 0x40173F: std::_List_base<int*, std::allocator<int*> >::_M_get_node() (stl_list.h:335) ==3334== by 0x401670: std::_List_node<int*>* std::list<int*, std::allocator<int*> >::_M_create_node<int*>(int*&&) (stl_list.h:500) ==3334== by 0x40157B: void std::list<int*, std::allocator<int*> >::_M_insert<int*>(std::_List_iterator<int*>, int*&&) (stl_list.h:1533) ==3334== by 0x40137E: std::list<int*, std::allocator<int*> >::push_back(int*&&) (stl_list.h:1002) ==3334== by 0x40114D: SubTest::subTest() (test.cpp:25) ==3334== by 0x40129C: Test::func1() (test.cpp:49) ==3334== by 0x400D97: func1(void*) (test.cpp:62) ==3334== by 0x4C2EDA4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355) ==3334== by 0x4E48E99: start_thread (pthread_create.c:308) ==3334== by 0x566ACCC: clone (clone.S:112) ==3334== Other segment start (thread 3) ==3334== at 0x4C39C82: pthread_rwlock_wrlock (drd_pthread_intercepts.c:1150) ==3334== by 0x55A35DC: setlocale (setlocale.c:208) ==3334== by 0x401237: Test::setUp() (test.cpp:40) ==3334== by 0x400DCA: func2(void*) (test.cpp:69) ==3334== by 0x4C2EDA4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355) ==3334== by 0x4E48E99: start_thread (pthread_create.c:308) ==3334== by 0x566ACCC: clone (clone.S:112) ==3334== Other segment end (thread 3) ==3334== at 0x4C3B242: pthread_rwlock_unlock (drd_pthread_intercepts.c:1237) ==3334== by 0x55A37C6: setlocale (setlocale.c:364) ==3334== by 0x401237: Test::setUp() (test.cpp:40) ==3334== by 0x400DCA: func2(void*) (test.cpp:69) ==3334== by 0x4C2EDA4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355) ==3334== by 0x4E48E99: start_thread (pthread_create.c:308) ==3334== by 0x566ACCC: clone (clone.S:112) ==3334== ==3334== Conflicting store by thread 2 at 0x06433548 size 8 ==3334== at 0x50CC8E7: std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17) ==3334== by 0x401592: void std::list<int*, std::allocator<int*> >::_M_insert<int*>(std::_List_iterator<int*>, int*&&) (stl_list.h:1534) ==3334== by 0x40137E: std::list<int*, std::allocator<int*> >::push_back(int*&&) (stl_list.h:1002) ==3334== by 0x40114D: SubTest::subTest() (test.cpp:25) ==3334== by 0x40129C: Test::func1() (test.cpp:49) ==3334== by 0x400D97: func1(void*) (test.cpp:62) ==3334== by 0x4C2EDA4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355) ==3334== by 0x4E48E99: start_thread (pthread_create.c:308) ==3334== by 0x566ACCC: clone (clone.S:112) ==3334== Address 0x6433548 is at offset 8 from 0x6433540. Allocation context: ==3334== at 0x4C2E30B: operator new(unsigned long) (vg_replace_malloc.c:319) ==3334== by 0x4017E0: __gnu_cxx::new_allocator<std::_List_node<int*> >::allocate(unsigned long, void const*) (new_allocator.h:94) ==3334== by 0x40173F: std::_List_base<int*, std::allocator<int*> >::_M_get_node() (stl_list.h:335) ==3334== by 0x401670: std::_List_node<int*>* std::list<int*, std::allocator<int*> >::_M_create_node<int*>(int*&&) (stl_list.h:500) ==3334== by 0x40157B: void std::list<int*, std::allocator<int*> >::_M_insert<int*>(std::_List_iterator<int*>, int*&&) (stl_list.h:1533) ==3334== by 0x40137E: std::list<int*, std::allocator<int*> >::push_back(int*&&) (stl_list.h:1002) ==3334== by 0x40114D: SubTest::subTest() (test.cpp:25) ==3334== by 0x40129C: Test::func1() (test.cpp:49) ==3334== by 0x400D97: func1(void*) (test.cpp:62) ==3334== by 0x4C2EDA4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355) ==3334== by 0x4E48E99: start_thread (pthread_create.c:308) ==3334== by 0x566ACCC: clone (clone.S:112) ==3334== Other segment start (thread 3) ==3334== at 0x4C39C82: pthread_rwlock_wrlock (drd_pthread_intercepts.c:1150) ==3334== by 0x55A35DC: setlocale (setlocale.c:208) ==3334== by 0x401237: Test::setUp() (test.cpp:40) ==3334== by 0x400DCA: func2(void*) (test.cpp:69) ==3334== by 0x4C2EDA4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355) ==3334== by 0x4E48E99: start_thread (pthread_create.c:308) ==3334== by 0x566ACCC: clone (clone.S:112) ==3334== Other segment end (thread 3) ==3334== at 0x4C3B242: pthread_rwlock_unlock (drd_pthread_intercepts.c:1237) ==3334== by 0x55A37C6: setlocale (setlocale.c:364) ==3334== by 0x401237: Test::setUp() (test.cpp:40) ==3334== by 0x400DCA: func2(void*) (test.cpp:69) ==3334== by 0x4C2EDA4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355) ==3334== by 0x4E48E99: start_thread (pthread_create.c:308) ==3334== by 0x566ACCC: clone (clone.S:112) ==3334== Expected Results: No errors reported. Test case: #include <locale.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h> #include <string> #include <sstream> #include <list> using namespace std; class SubTest { public: SubTest() { list<int *> ffList; ffList.push_back((int *) NULL); for (list<int*>::iterator ff = ffList.begin(); ff != ffList.end(); ff++) { usleep(1000); } } void subTest() { list<int *> ffList; ffList.push_back((int *) NULL); for (list<int*>::const_iterator ff = ffList.begin(); ff != ffList.end(); ff++) { usleep(1000); } } }; class Test { SubTest *subTest; public: void setUp() { subTest = new SubTest(); setlocale(LC_ALL, "English"); } void tearDown() { delete subTest; } void func1() { for (size_t i = 0; i < 10000; i++) { subTest->subTest(); usleep(1000); } } void func2() { usleep(1000); } }; void *func1(void *instance) { Test *casted = reinterpret_cast<Test*>(instance); casted->setUp(); casted->func1(); casted->tearDown(); return NULL; } void *func2(void *instance) { Test *casted = reinterpret_cast<Test*>(instance); casted->setUp(); casted->func2(); casted->tearDown(); return NULL; } int main(int argc, char* argv[]) { int err; pthread_t thread1; pthread_t thread2; Test instance1; Test instance2; // create err = pthread_create(&thread1, NULL, &func1, &instance1); if (err != 0) throw string("failed to create a thread."); err = pthread_create(&thread2, NULL, &func2, &instance2); if (err != 0) throw string("failed to create a thread."); // join err = pthread_join(thread1, NULL); if (err != 0) throw string("Thread::join(): failed to join."); err = pthread_join(thread2, NULL); if (err != 0) throw string("Thread::join(): failed to join."); }