简体   繁体   中英

segmentation fault (core dumped) with c++11 thread

I'm a newbie with c++, and I got a "segmentation fault (core dumped)" when playing with threads of c++11. I modified a piece of good code I used to write and got the error. The part I modified is

mutex m;
auto thread_f=[&](int i)
{
    for(int j=i; j<interval.size(); j+=Threads_Number)
    {
        vector<Permutation >::iterator it1=(interval.begin()+j);
        for(vector<Permutation >::iterator it2=it1; it2!=interval.end(); it2++)
        {
            if(!(*it1<*it2)) continue;
            IntervalToCheck x(*it1,*it2);
            m.lock();
            cout<<x;
            f<<x;
            m.unlock();
        }
    }
};

vector<thread> threads;
threads.clear();
for(int i=0; i<Threads_Number; i++)
    threads.push_back(thread(thread_f,i));
for(auto& th:threads)
    th.join();

where the varient "f" is an object of ofstream. and it's strange that when i set "Threads_Number" to 1 the program works well, and when i set "Threads_Number" other than 1, the program sometimes works well and sometimes not---just like the old time when i dont initialize an int and use it.

And this is my g++ version:

aalen@CFC:multiThreads> g++ --version                                            13-02-25 14:24
g++ (GCC) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.

i use the:

g++ -c main.cpp --std=c++11

g++ *.o -o work -lcln -lginac -pthread 

to compile my code. and thanks for your attention, sorry for my poor english.

It seems that because i use GiNaC in the class IntervalToCheck and it's not thread safe(as i googled GiNac and thread safe), because i got the message that

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff5340700 (LWP 3125)]
0x00000000004097cf in GiNaC::ptr<GiNaC::basic>::operator= (this=0x7fffec000cd0,   other=...) at /usr/include/ginac/ptr.h:88
88              delete p;

from gdb as nm suggested. maybe GiNaC is the problem. If anyone can provide an open tool for handling expression, it would be great. thx for reading.

If you look at the source code for where the segmentation fault is coming from, you can see it's from GiNaC's implementation of a reference counting pointer . The problem, from what I understand, is that it is possible for the pointer to be deleted prematurely while another thread is still using it. This is because increment and decrement operations on the counter are not atomic with regards to thread access. Therefore, you are trying to access deleted memory, which is undefined behavior (and therefore segfault-able).

Actually, it appears this problem has popped up in the past, and the concern was voiced on their mailing list .

GiNaC is not thread-safe, according to its maintainer.

Therefore, you simply cannot use GiNaC from more than one thread, as intended by the maintainer.

Theoretically, perhaps you could substitute ginac::ptr with something like std::shared_ptr , which is guaranteed to have no race conditions regarding its reference count mechanism. So the program would likely work if you could replace either the internal counter type with std::atomic<int> or something similar, or you could another implementation that has atomic reference counting.

As for the actual code that you wrote, it appears that it should work fine. Although the print statements can execute and interleave in order, they appear to be locked correctly in a critical block, although it is probably better to use the more idiomatic, RAII-enhanced std::scoped_lock in C++.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM