mutil_thread append string cause core - c++

i use multi thread to update each item(string) of global vector
each thread update item(string) with different index
i think is a good way to avoid updating same data
but i still get core, i do not know why
extern vector<string> gTestVec;
#define NUM 10
void * worker(void * args) {
thread_data * p = (thread_data *)args;
int i = p->thread_id;
for (int j=0; j<100; j++) {
gTestVec[i] += "a";
}
return NULL;
}
void do_complete_stage_test::excute() {
int i = 0;
pthread_t thd[NUM];
thread_data data[NUM];
for (i=0; i<NUM; i++) {
gTestVec.push_back(format("%d", i));
data[i].thread_id = i;
if (0 != pthread_create(&(thd[i]), NULL, &worker, (void *)&data[i])) {
printf("pthread_create failed");
}
}
for (int i=0; i<NUM; i++) {
if (0 != pthread_join(thd[i], NULL)) {
printf("pthread_join failed");
}
}
}
when i run the code,sometimes get coredump
Starting program: /data/settle_script/isp_tran_collect/bin/isp_tran_collect -p 2134234
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff2623700 (LWP 6316)]
[New Thread 0x7fffefb0e700 (LWP 6317)]
[New Thread 0x7fffef30d700 (LWP 6318)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffef30d700 (LWP 6318)]
0x00007ffff6787d67 in ?? () from /lib64/libstdc++.so.6
(gdb) bt
#0 0x00007ffff6787d67 in ?? () from /lib64/libstdc++.so.6
#1 0x00007ffff678899b in std::string::reserve(unsigned long) () from /lib64/libstdc++.so.6
#2 0x00007ffff6788bbf in std::string::append(char const*, unsigned long) () from /lib64/libstdc++.so.6
#3 0x000000000044babe in append (__s=0x880492 "a", this=<optimized out>) at /usr/include/c++/4.8.2/bits/basic_string.h:1009
#4 operator+= (__s=0x880492 "a", this=<optimized out>) at /usr/include/c++/4.8.2/bits/basic_string.h:942
#5 worker (args=<optimized out>) at ../src/do_complete_stage_test.cpp:21
#6 0x00007ffff7bc6e25 in start_thread () from /lib64/libpthread.so.0
#7 0x00007ffff5ee635d in clone () from /lib64/libc.so.6
thanks for your help!!!

You are potentially changing the capacity of the vector after you already started some threads.
The easiest way to prevent the vector from re-allocating and moving its contents is to reserve the amount of space before you start the first worker thread.
So call
gTestVec.reserve(NUM);
Before your loop.

Related

gtk_init caused crash on ubuntu 16.04 if program run without sudo

gtk_init caused crash on ubuntu 16.04 if run program without sudo. If run with sudo, then have not problem. On other ubuntu versions also have not problem with and without sudo.
Minimally reproducible example:
#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
gtk_init (&argc, &argv);
for (int i = 0; i < 10; ++i)
{
printf("%d\n", i);
usleep(1000 * 1000);
}
return 0;
}
Stacktrace:
Thread 2 "dconf worker" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb6567b40 (LWP 6735)]
0xb71bbfd0 in g_source_set_ready_time () from /lib/i386-linux-gnu/libglib-2.0.so.0
(gdb) bt
#0 0xb71bbfd0 in g_source_set_ready_time () from /lib/i386-linux-gnu/libglib-2.0.so.0
#1 0xb73e8bf4 in g_task_get_type () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#2 0xb744b6a0 in ?? () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#3 0xb743eb00 in ?? () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#4 0xb73bd0e9 in g_initable_init () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#5 0xb743f230 in g_bus_get_sync () from /usr/lib/i386-linux-gnu/libgio-2.0.so.0
#6 0xb668c314 in ?? () from /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#7 0xb668c423 in ?? () from /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#8 0x0807e22a in g_main_context_dispatch ()
#9 0x0807e638 in g_main_context_iterate.isra ()
#10 0x0807e700 in g_main_context_iteration ()
#11 0xb668c58b in ?? () from /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#12 0x0809eabd in g_thread_proxy ()
#13 0xb7aaf295 in start_thread (arg=0xb6567b40) at pthread_create.c:333
#14 0xb79d10ae in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:114
I tried to compare strace output with sudo and without - without sudo is being created problem thread dconf worker, but if run with sudo it thread is not being created and programm work correctly
What can be done to fix this problem?
UPD: Stacktrace with `libglib2.0-0-dbg
Thread 2 "dconf worker" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb6567b40 (LWP 3574)]
0xb71bbfd0 in g_source_set_ready_time (source=0xb5c09938, ready_time=-1)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./glib/gmain.c:1786
1786 /build/glib2.0-2aRhhS/glib2.0-2.48.2/./glib/gmain.c: No such file or directory.
(gdb) bt
#0 0xb71bbfd0 in g_source_set_ready_time (source=0xb5c09938, ready_time=-1)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./glib/gmain.c:1786
#1 0xb73e8bf4 in g_task_get_type () at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gtask.c:1907
#2 0xb73e8bf4 in g_task_get_type () at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gtask.c:590
#3 0xb744b6a0 in _g_dbus_worker_new () at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusprivate.c:227
#4 0xb744b6a0 in _g_dbus_worker_new () at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusprivate.c:267
#5 0xb744b6a0 in _g_dbus_worker_new (stream=0xb5c016c8, capabilities=G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING, initially_frozen=0, message_received_callback=0xb7438400 <on_worker_message_received>, message_about_to_be_sent_callback=0xb7435eb0 <on_worker_message_about_to_be_sent>, disconnected_callback=0xb74359c0 <on_worker_closed>, user_data=0xb5c04818)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusprivate.c:1649
#6 0xb743eb00 in initable_init (initable=0xb5c04818, cancellable=0x0, error=0xb6567068)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusconnection.c:2573
#7 0xb73bd0e9 in g_initable_init (initable=0xb5c04818, cancellable=0x0, error=0xb6567068)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/ginitable.c:112
#8 0xb743f230 in g_bus_get_sync (bus_type=G_BUS_TYPE_SESSION, cancellable=0x0, error=0xb6567068)
at /build/glib2.0-2aRhhS/glib2.0-2.48.2/./gio/gdbusconnection.c:7254
#9 0xb668c314 in () at /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#10 0xb668c423 in () at /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#11 0x0807e22a in g_main_context_dispatch ()
#12 0x0807e638 in g_main_context_iterate.isra ()
#13 0x0807e700 in g_main_context_iteration ()
#14 0xb668c58b in () at /usr/lib/i386-linux-gnu/gio/modules/libdconfsettings.so
#15 0x0809eabd in g_thread_proxy ()
#16 0xb7aaf295 in start_thread (arg=0xb6567b40) at pthread_create.c:333
#17 0xb79d10ae in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:114
Unset GTK2_MODULES, GTK_MODULES and GTK_IM_MODULE fixed this problem, but i don't understend why it work
#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
unsetenv("GTK2_MODULES");
unsetenv("GTK_MODULES");
unsetenv("GTK_IM_MODULE");
gtk_init (&argc, &argv);
for (int i = 0; i < 10; ++i)
{
printf("%d\n", i);
usleep(1000 * 1000);
}
return 0;
}

seg fault at boost::smart_pointer

I got the following segmentation fault:
Program terminated with signal 11, Segmentation fault.
#0 0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
145 dispose();
Missing separate debuginfos, use: debuginfo-install boost-filesystem- 1.41.0-11.el6_1.2.x86_64 boost-program-options-1.41.0-11.el6_1.2.x86_64 boost-system-1.41.0-11.el6_1.2.x86_64 bzip2-libs-1.0.5-7.el6_0.x86_64 glibc-2.12-1.80.el6.x86_64 libgcc-4.4.6-4.el6.x86_64 libstdc++-4.4.6-4.el6.x86_64 lzo-2.03-3.1.el6.x86_64
(gdb) bt
#0 0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
#1 boost::detail::shared_count::~shared_count (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:217
#2 0x00007f13fad83dab in boost::detail::set_tss_data(void const*, boost::shared_ptr<boost::detail::tss_cleanup_function>, void*, bool) ()
from /usr/local/lib/libboost_thread.so.1.40.0
#3 0x000000000042e191 in boost::thread_specific_ptr<infrastructure::tfeed::sequenced_data_queue_element_t::mem_prealloc>::release (this=<value optimized out>)
at /usr/local/include/boost/thread/tss.hpp:95
#4 0x000000000042ed43 in infrastructure::tfeed::sequenced_data_queue_element_t::operator new (size=16)
at ../../../infrastructure/include/tfeed/tfeed_multicast_defs.h:120
Also, I got a similar seg fault in another thread:
(gdb) thread 5
[Switching to thread 5 (Thread 0x7f122e1fe700 (LWP 7547))]
#0 0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
145 dispose();
(gdb) bt
#0 0x000000000040fbf6 in release (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:145
#1 boost::detail::shared_count::~shared_count (this=<value optimized out>, __in_chrg=<value optimized out>)
at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:217
#2 0x00007f13fad83dab in boost::detail::set_tss_data(void const*, boost::shared_ptr<boost::detail::tss_cleanup_function>, void*, bool) ()
from /usr/local/lib/libboost_thread.so.1.40.0
#3 0x000000000042e591 in release (q_elem=<value optimized out>) at /usr/local/include/boost/thread/tss.hpp:95
#4 infrastructure::tfeed::sequenced_data_queue_element_t::operator delete (q_elem=<value optimized out>)
at ../../../infrastructure/include/tfeed/tfeed_multicast_defs.h:144
this happened while using the boost's thread specific pointer at /usr/local/include/boost/thread/tss.hpp:95 at (set_tss_data() call below)
T* release()
{
T* const temp=get();
detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
return temp;
}
and futher at sp_counted_base_gcc_x86.hpp(at dispose())
void release() // nothrow
{
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
{
dispose();
weak_release();
}
}
I am using thread specific pointer while specialized new and delete calls for a datastructure(sequenced_data_queue_element_t). As this new and delete are called from multiple threads:
class sequenced_data_queue_element_t
{
public:
sequenced_data_queue_element_t() {
}
~sequenced_data_queue_element_t() {
delete data;
}
unsigned char* data;
uint32_t data_len;
typedef struct mem_prealloc
{
struct mem_prealloc* next;
} mem_prealloc_t;
static boost::thread_specific_ptr<mem_prealloc_t> mem_prealloc_q_head;
static void* operator new(size_t size)
{
mem_prealloc_t* q_elem;
if (UNLIKELY(mem_prealloc_q_head.get() == NULL))
{
/* allocate PREALLOC_BATCH elems at a time */
for (int i=0; i < MEM_PREALLOC_BATCH; i++)
{
q_elem = (mem_prealloc_t*)malloc(size);
q_elem->next = mem_prealloc_q_head.release();
mem_prealloc_q_head.reset(q_elem);
cur_mem_prealloced += size;
}
}
q_elem = mem_prealloc_q_head.release();
mem_prealloc_q_head.reset(q_elem->next);
return (void*)q_elem;
}
static void operator delete(void* q_elem)
{
/* C++ guarantees that an object's destructor
* is automatically called just before delete executes. */
/* next reuses the first pointer of sequenced_data_element_t */
((mem_prealloc_t*)q_elem)->next = mem_prealloc_q_head.release();
mem_prealloc_q_head.reset((mem_prealloc_t*)q_elem);
if (cur_mem_prealloced > MEM_PREALLOC_MAX_BYTES)
{
for (int i=0; i < MEM_PREALLOC_BATCH; i++)
{
mem_prealloc_t* qelem = mem_prealloc_q_head.release();
mem_prealloc_q_head.reset(qelem->next);
free(qelem);
cur_mem_prealloced -= sizeof(sequenced_data_queue_element_t);
if (mem_prealloc_q_head.get() == NULL)
break;
}
}
}
};
cur_mem_prealloced(uint64_t) is a global variable.
What could be the possible reason triggering this bug?
Further, the stack of some other threads of the program seems to be corrupted. Also, the core dump shows unexpected code paths for those other threads.
the kernel logs shows the following error message:
[7547]: segfault at 10 ip 000000000040fbf6 sp 00007f122e1fcd90 error 4
[7531]: segfault at 10 ip 000000000040fbf6 sp 00007fffc94bcca0 error 4 in tbt[400000+a0000] in tbt[400000+a0000]
Can these seg faults be triggered in case of stack corruption as well?

Thread name not shown in info thread command when using gdb 7.7

In some of the answers to related questions I could see that gdb 7.3 should support displaying thread names atleast with 'info threads' command .
But I am not even getting that luxury. please help me to understand what I am doing wrong.
My sample code used for testing:
#include <stdio.h>
#include <pthread.h>
#include <sys/prctl.h>
static pthread_t ta, tb;
void *
fx (void *param)
{
int i = 0;
prctl (PR_SET_NAME, "Mythread1", 0, 0, 0);
while (i < 1000)
{
i++;
printf ("T1%d ", i);
}
}
void *
fy (void *param)
{
int i = 0;
prctl (PR_SET_NAME, "Mythread2", 0, 0, 0);
while (i < 100)
{
i++;
printf ("T2%d ", i);
}
sleep (10);
/* generating segmentation fault */
int *p;
p = NULL;
printf ("%d\n", *p);
}
int
main ()
{
pthread_create (&ta, NULL, fx, 0);
pthread_create (&tb, NULL, fy, 0);
void *retval;
pthread_join (ta, &retval);
pthread_join (tb, &retval);
return 0;
}
Output( using core dump generated by segmentation fault)
(gdb) core-file core.14001
[New LWP 14003]
[New LWP 14001]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./thread_Ex'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
30 printf("%d\n",*p);
(gdb) info threads
Id Target Id Frame
2 Thread 0xb77d76c0 (LWP 14001) 0x00b95424 in __kernel_vsyscall ()
* 1 Thread 0xb6dd5b70 (LWP 14003) 0x08048614 in fy (param=0x0) at thread_Ex.c:30
(gdb) bt
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
#1 0x006919e9 in start_thread () from /lib/libpthread.so.0
#2 0x005d3f3e in clone () from /lib/libc.so.6
(gdb) thread apply all bt
Thread 2 (Thread 0xb77d76c0 (LWP 14001)):
#0 0x00b95424 in __kernel_vsyscall ()
#1 0x006920ad in pthread_join () from /lib/libpthread.so.0
#2 0x080486a4 in main () at thread_Ex.c:50
Thread 1 (Thread 0xb6dd5b70 (LWP 14003)):
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
#1 0x006919e9 in start_thread () from /lib/libpthread.so.0
#2 0x005d3f3e in clone () from /lib/libc.so.6
(gdb) q
As you can see I cant see any thread names that I have set. what could be wrong?
Note:
I am using gdb version 7.7 (Downloaded and compiled using no special options)
commands used to compile & install gdb : ./configure && make && make install
As far as I am aware, thread names are not present in the core dump.
If they are available somehow, please file a gdb bug.
I get thread name displayed on CentOS6.5, but not displayed on CentOS6.4 .

C++ program crashing for a string concatenation.

This is the line that is causing the crash :
if (size <= 0)
return;
if (data)
{
std::string sData = std::string((char*)data, size);
buffer += sData; <-- This is the line causing crash
processBuffer();
}
else
return;
Here is the stack trace:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1282016352 (LWP 27952)]
0x002b48ec in memcpy () from /lib/tls/libc.so.6
(gdb) bt
#0 0x002b48ec in memcpy () from /lib/tls/libc.so.6
#1 0x001fea31 in std::string::_Rep::_M_clone () from /usr/lib/libstdc++.so.6
#2 0x001fef2e in std::string::reserve () from /usr/lib/libstdc++.so.6
#3 0x001ff83d in std::string::append () from /usr/lib/libstdc++.so.6
#4 0x001ff9e2 in std::string::operator+= () from /usr/lib/libstdc++.so.6
#5 0x003fc6c8 in StreamDecoder::StreamDecoderEncoder::addData
at src/StreamDecoder.cpp:171
I have verified that data is not empty and buffer is a string declared as a private member variable of that class.
I do not know why there is a segfault on memcpy. What could have gone wrong here ?
I had this problem working on a school project a few months back... if a string gets massive, it can cause a segfault. Try using something like an ostringstream instead.

thread terminate called without an active exception

I've been doing threaded networking for a game, but the server dies randomly, while i've been testing the networking so that I have several clients connecting and sending bunch of packets and disconnecting then connecting back again.
I am using c++ with SFML/Network and SFML/System threads. I have thread which listens for connections in the server once connection is established it creates two new threads for sending and receiving packets. The event handler and the send/receive threads share data with two std::queues. I've been trying to debug the crash with gdb, but i'm not that experienced with this so i'm looking for help.
Here is gdb console input when the crash happens.
OUT: 10 1 HELLO
IN: 10 0 LOLOLOL
OUT: 10 1 HELLO
IN: 10 0 LOLOLOL
OUT: 10 1 HELLO
Out thread killed by in thread!
In thread died!
New client connected!
[Thread 0x34992b70 (LWP 16167) exited]
[New Thread 0x3118bb70 (LWP 16186)]
terminate called without an active exception
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x35193b70 (LWP 16166)]
0x00110416 in __kernel_vsyscall ()
Here is the backtrace:
(gdb) backtrace
#0 0x00110416 in __kernel_vsyscall ()
#1 0x46a0967f in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2 0x46a0afb5 in abort () at abort.c:92
#3 0x47b8af0d in __gnu_cxx::__verbose_terminate_handler () at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
#4 0x47b88c84 in __cxxabiv1::__terminate (handler=0x47b8adc0 <__gnu_cxx::__verbose_terminate_handler()>) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:40
#5 0x47b88cc0 in std::terminate () at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:50
#6 0x47b8878f in __cxxabiv1::__gxx_personality_v0 (version=1, actions=10, exception_class=890844228, ue_header=0x35193dc0, context=0x35192ea0)
at ../../../../libstdc++-v3/libsupc++/eh_personality.cc:669
#7 0x46bdbfbe in _Unwind_ForcedUnwind_Phase2 (exc=0x35193dc0, context=0x35192ea0) at ../../../gcc/unwind.inc:175
#8 0x46bdc3a9 in _Unwind_ForcedUnwind (exc=0x35193dc0, stop=0x46b76fc0 <unwind_stop>, stop_argument=0x35193444) at ../../../gcc/unwind.inc:207
#9 0x46b794e2 in _Unwind_ForcedUnwind (exc=0x35193dc0, stop=0x46b76fc0 <unwind_stop>, stop_argument=0x35193444) at ../nptl/sysdeps/pthread/unwind-forcedunwind.c:132
#10 0x46b77141 in __pthread_unwind (buf=<optimized out>) at unwind.c:130
#11 0x46b6f5bb in __do_cancel () at ../nptl/pthreadP.h:265
#12 sigcancel_handler (sig=<optimized out>, si=<optimized out>, ctx=<optimized out>) at nptl-init.c:202
#13 sigcancel_handler (sig=32, si=0x35192f7c, ctx=0x35192ffc) at nptl-init.c:155
#14 <signal handler called>
#15 0x08049930 in out (data=0xb761c798) at src/layer7.cpp:40
#16 0x0804b8d7 in sf::priv::ThreadFunctorWithArg<void (*)(networkdata*), networkdata*>::Run (this=0xb761c7c8) at /usr/local/include/SFML/System/Thread.inl:48
#17 0x00116442 in sf::Thread::Run() () from /home/toni/ProjectRepos/sfml/build/lib/libsfml-system.so.2
#18 0x001166df in sf::priv::ThreadImpl::EntryPoint(void*) () from /home/toni/ProjectRepos/sfml/build/lib/libsfml-system.so.2
#19 0x46b70c5e in start_thread (arg=0x35193b70) at pthread_create.c:305
#20 0x46ab4b4e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:133
Here is the thread code from src/layer7.cpp
void out(networkdata * data) {
bool running = true;
while(running) {
if(data->pipe_out->pipe_empty() == false) {
sf::Packet packet = data->pipe_out->pop_message();
if(data->socket->Send(packet) == sf::Socket::Disconnected) {
data->thread_in->Terminate();
std::cout << "In thread killed by out thread!" << std::endl;
running = false;
}
}
}
std::cout << "Out thread died!" << std::endl;
}
Line 40 is the first if keyword after the while(running).
The data->pipe_out->pipe_empty() is call to the queue->empty()
The data->pipe_out->pop_message() is call which pops the front from the queue.
Then it sends the packet and checks if the connection is not disconnected
if socket is disconnected it terminates the "in" thread and stops the own thread.
You need locks around data to protect against concurrent access to the same data structure from multiple threads.
One possible reason for is an exception: exception should be caught withing thread. Also, looks like data->thread_in->Terminate() sends cancelation request, make sure that all established cancellation handlers are working correctly in that case.