Bug#479952: libc6: Also in x86_64?
On Sat, Jul 25, 2009 at 03:32, Aurelien Jarno<aurelien@aurel32.net> wrote:
> On Sat, Jul 25, 2009 at 02:11:51AM -0400, Will Murnane wrote:
>> Package: libc6
>> Version: 2.9-21
>> Severity: normal
>>
>> I wrote a program that uses pthreads to accomplish work, and hit this bug in it. It works properly on Rhel5, so I'm pretty sure it's libc at fault.
>>
>> Full source code available on request. Basically, though, the problem comes when many threads are fighting for a mutex, and doing very little work between trying to obtain the lock.
>>
>
> If you have a small code to reproduce the problem, it will be highly
> appreciated.
Attached is break_pthreads.cpp. Compile with
g++ -g -Wall -Werror -pipe -O3 -Wno-deprecated break_pthreads.cpp -o
break_pthreads.o -c
g++ -g -pthread break_pthreads.o -o break_pthreads
Now run it and it crashes:
break_pthreads: pthread_mutex_lock.c:87: __pthread_mutex_lock:
Assertion `mutex->__data.__owner == 0' failed.
Aborted
Will
#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <vector>
#include <signal.h>
struct thread_data {
int tid;
};
struct work {
int i;
};
void clean_exit_on_sig(int sig_num)
{
std::cout << "Got signal " << sig_num << std::endl;
exit(1);
}
unsigned int NUM_THREADS;
#define WORKTOGET 5
std::vector<work> toDo;
pthread_mutex_t work_lock = PTHREAD_MUTEX_INITIALIZER;
void finishWork(work w)
{
}
void *worker(void *threadarg)
{
work workingOn[WORKTOGET];
while (true)
{
unsigned int workgot = 0;
pthread_mutex_lock(&work_lock);
if (toDo.empty())
{
pthread_mutex_unlock(&work_lock);
pthread_yield();
} else {
while (!toDo.empty() && (workgot < WORKTOGET))
{
workingOn[workgot] = toDo.back();
toDo.pop_back();
workgot++;
}
}
pthread_mutex_unlock(&work_lock);
for (unsigned int i = 0; i < workgot; i++)
{
finishWork(workingOn[i]);
}
}
return NULL;
}
int main( int argc, char **argv )
{
bool done=false;
/* Set up SIGSEGV handler */
signal(SIGSEGV, clean_exit_on_sig);
/* Set up pthreads stuff */
NUM_THREADS = sysconf(_SC_NPROCESSORS_CONF);
pthread_t *workers = (pthread_t*)malloc(NUM_THREADS * sizeof(pthread_t));
struct thread_data *children = (struct thread_data*)malloc(NUM_THREADS * sizeof(struct thread_data));
int rc;
pthread_attr_t attr;
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (unsigned int t = 0; t < NUM_THREADS; t++)
{
children[t].tid = t;
rc = pthread_create(&workers[t], &attr, &worker, (void *)&children[t]);
if (rc)
{
std::cerr << "ERROR: return code from pthread_create() is " << rc << std::endl;
exit(-1);
}
}
/* wait for events */
while ( !done )
{
}
return( 0 );
}
Reply to: