c++中多线程操作 string 引发的 coredump,栈中比较奇怪的一点
源代码如下:
#include <iostream> #include <string> #include <vector> #include <thread> struct A { std::string name = "blacksmith"; int age = 100; }; struct B1 { std::string local_name = "jd-B1"; void func1(A* a) { while (true) { a->name = local_name; std::string key = local_name + "**"; } } }; struct B2 { std::string local_name = "jd-B2"; void func1(A* a) { while (true) { a->name = local_name; std::string key = local_name + "**"; } } }; int main() { /** * 探测是否支持 COW */ std::string* test = new std::string("blacksmith"); std::string name = *test; std::cout << "test:" << test->data() << ", name=" << name.data() << std::endl; if (test->data() == name.data()) { std::cout << "COW(Copy On Write) support!" << std::endl; } else { std::cout << "COW(Copy On Write) NOT support!" << std::endl; } delete test; /** * 多线程操作 */ std::vector<std::thread> th_vec; int thread_count = 4; A a; B1 b1; B2 b2; for (int i = 0; i < thread_count; i++) { th_vec.emplace_back([&](){ b1.func1(&a); }); th_vec.emplace_back([&](){ b2.func1(&a); }); } for (auto& item : th_vec) { item.join(); } std::cout << "=========END==========" << std::endl; return 0; }
编译:
g++ --std=c++11 string-test.cc -g -lpthread
查看 coredump 栈:
(gdb) bt #0 0x00007f5613350e20 in __memcpy_ssse3 () from /usr/lib64/libc.so.6 #1 0x00007f5613ba8650 in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) () from /usr/lib64/libstdc++.so.6 #2 0x00007f5613ba86d4 in std::string::reserve(unsigned long) () from /usr/lib64/libstdc++.so.6 #3 0x00007f5613ba893f in std::string::append(char const*, unsigned long) () from /usr/lib64/libstdc++.so.6 #4 0x0000000000402808 in std::operator+<char, std::char_traits<char>, std::allocator<char> > ( __lhs="jd-B2", ' 00' <repeats 11 times>, "! 00 00 00 00 00 00[email protected]@ 00 00 00 00 00(I213 71375177 00 00 60I213 71375177 00 00Q 02 00 00 00 00 00 00"", ' 00' <repeats 15 times>, " 01", ' 00' <repeats 15 times>, "377377377377377377377377 00 00 00 00 00 00 00 00377377377377377377377377", ' 00' <repeats 88 times>..., __rhs=0x40386a "**") at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:5917 #5 0x000000000040263f in B2::func1 (this=0x7ffd398b4920, a=0x7ffd398b4930) at string-test.cc:28 #6 0x0000000000401108 in <lambda()>::operator()(void) const (__closure=0x19a5368) at string-test.cc:62 #7 0x0000000000401fde in std::__invoke_impl<void, main()::<lambda()> >(std::__invoke_other, <lambda()> &&) (__f=...) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/invoke.h:60 #8 0x0000000000401cb0 in std::__invoke<main()::<lambda()> >(<lambda()> &&) (__fn=...) at /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/invoke.h:95 #9 0x0000000000402392 in std::thread::_Invoker<std::tuple<main()::<lambda()> > >::_M_invoke<0>(std::_Index_tuple<0>) (this=0x19a5368) at /opt/rh/devtoolset-7/root/usr/include/c++/7/thread:234 #10 0x000000000040233f in std::thread::_Invoker<std::tuple<main()::<lambda()> > >::operator()(void) (this=0x19a5368) at /opt/rh/devtoolset-7/root/usr/include/c++/7/thread:243 #11 0x00000000004022fe in std::thread::_State_impl<std::thread::_Invoker<std::tuple<main()::<lambda()> > > >::_M_run(void) (this=0x19a5360) at /opt/rh/devtoolset-7/root/usr/include/c++/7/thread:186 #12 0x000000000040343f in execute_native_thread_routine () #13 0x00007f5613df8dd5 in start_thread () from /usr/lib64/libpthread.so.0 #14 0x00007f5613302ead in clone () from /usr/lib64/libc.so.6
比较疑惑的一点是,多线程写 string,为什么不是在写入那一行 core,而是在后面拼接成员变量?
a->name = local_name; // 我理解应该是这一行报 core
std::string key = local_name + “**”; // 实际在操作 local_name 的时候 core,并且看栈,local_name 内存乱了
辛苦各位大佬,有时间的帮忙看看,很是疑惑。 谢谢。
不一定会在这里 上面的图不对 补一个图