This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pthread_create()'s behavor?


Here is the complete and compile-able version:
#include <map>
#include <pthread.h>

class B {};

class A {
private:
??? std::map<size_t, B*> m_myMap;
public:
??? A() {
??? ??? m_myMap[0] = new B();
??? ??? pthread_t thread;
??? ??? pthread_attr_t attr;
??? ??? pthread_attr_init(&attr);
??? ??? pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
??? ??? pthread_create(&thread, &attr, startThread, this);
??? ??? //sleep(3);
??? }
??? ~A() {
??? ??? try {
??? ??? ??? while (!m_myMap.empty()) {
??? ??? ??? ??? B* b = m_myMap.begin()->second;
??? ??? ??? ??? m_myMap.erase(m_myMap.begin());
??? ??? ??? ??? delete b;
??? ??? ??? }
??? ??? } catch (...) {
??? ??? }
??? }

??? void doSomething() { printf("%s\n", __FUNCTION__); }

??? static void* startThread(void* ptr) {
??? ??? A& instance = *static_cast<A*>(ptr);
??? ??? // use m_myMap[0] here, will this new thread sees everything happens before it gets created (e.g. m_myMap[0] contains the valid value)?
??? ??? std::map<size_t, B*>::iterator iter = instance.m_myMap.find(0);
??? ??? if (instance.m_myMap.end() == iter) {
??? ??? ??? printf("not found\n");
??? ??? }
??? ??? else {
??? ??? ??? printf("found\n");
??? ??? }
??? ??? return 0;
??? }
};

int main() {
??? A a;
??? a.doSomething();
??? return 1;
}

I ran it with valgrind and I didn't see anything either.

I suspect that the new thread starts running before object a is completely constructed; hence, accessing the member variable m_map of the incomplete object a might result in undefined behavior/segfault.

Unfortunately, I am not be able to reproduce it (it segfaults only 1% of the time)....


Cheers,
Hei




----- Original Message -----
From: Ángel González <keisial@gmail.com>
To: Hei Chan <structurechart@yahoo.com>
Cc: "libc-help@sourceware.org" <libc-help@sourceware.org>
Sent: Tuesday, April 17, 2012 7:54 AM
Subject: Re: pthread_create()'s behavor?

On 16/04/12 07:56, Hei Chan wrote:
> Hi,
>
> I am using pthread library on CentOS 5.5.
>
> I have the following code:
>
> class B {};
>
> class A {
> private:
>? ? std::map<long, B*> m_myMap;
> public:
>? ? A::A() {
>? ? ? ? m_myMap[0] = new B();
>? ? ? ? pthread_t threadID;
>? ? ? ? pthread_create(&threadID, NULL, start, NULL);
>? ? }
>? ? static void* start(void*) {
>? ? ? ? // use m_myMap[0] here, will this new thread sees everything happens before it gets created (e.g. m_myMap[0] contains the valid value)?
>? ? ? ? m_myMap.find(0);
>? ? }
> }
>
> Sometimes (~1% chance), I got a segfault at m_myMap.find(0).? Is it true that pthread_create() won't try to enforce the memory barrier to ensure all the previous writes to be globally visible?
>
> Thanks in advance.
I'm not seeing with your code (after fixes) that behavior here (which
doesn't mean it would never fail for me), but I wonder if that's really
the code that fais for you.
Is m_myMap a static parameter? Are other threads reading/writing to it?
Another thread writing m_MyMap[5] could perfectly produce a segfault on
m_myMap.find(0), and that would be expected.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]