Dear,

I am trying to debug a posix application and I noticed what I think is a bug in the method pthread_cond_wait (). it returns EPERM when the application is started with gdb.
Could you please help me to understand what is wrong or locate the bug?

Best regards.

Pierre Quélin

------------------------------------
Configuration
------------------------------------
Ubuntu 10.10
Linux xenomai 2.6.35.7-core2xeon-adeos-2.8-00 #1 SMP PREEMPT Mon Dec 6 13:37:41 CET 2010 i686 GNU/Linux

Gnu C 4.4.4-14ubuntu5)
GNU gdb (GDB) 7.2-ubuntu
Gnu make 3.81
util-linux ng 2.17.2)
mount ng 2.17.2 (with libblkid and selinux support)
module-init-tools 3.12
e2fsprogs 1.41.12
Linux C Library 2.12.1
Dynamic linker (ldd) 2.12.1
Procps 3.2.8
Net-tools 1.60
Kbd 1.15
Sh-utils 8.5
Modules Loaded ip6table_filter ip6_tables binfmt_misc ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack ipt_REJECT xt_tcpudp iptable_filter ip_tables x_tables bridge stp kvm_intel kvm parport_pc ppdev arc4 rt73usb crc_itu_t rt2x00usb rt2x00lib led_class i3200_edac edac_core mac80211 lp psmouse serio_raw cfg80211 parport hed floppy e1000 e1000e

------------------------------------
Code
------------------------------------
#include <sys/mman.h> /* line 0 */
#include <pthread.h>

void* bodyA(void*)
{
pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_mutexattr_t attr;
int res;

res = pthread_mutexattr_init( &attr );
res = pthread_mutexattr_setprotocol( &attr, PTHREAD_PRIO_INHERIT );
res = pthread_mutex_init( &mutex, &attr );
res = pthread_mutexattr_destroy( &attr );
res = pthread_cond_init( &cond, NULL );

bool state = false;
res = pthread_mutex_lock( &mutex );
while ( !state )
{
res = pthread_cond_wait( &cond, &mutex );
if ( 0 != res )
{
res = pthread_mutex_unlock( &mutex );
return (void*)-1;
}
else
{
(void)res;
}
}
state = true;
res = pthread_mutex_unlock( &mutex );

return 0;
};

void* bodyB(void*)
{
pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_mutexattr_t attr;
int res;

res = pthread_mutexattr_init( &attr );
res = pthread_mutexattr_setprotocol( &attr, PTHREAD_PRIO_INHERIT );
res = pthread_mutex_init( &mutex, &attr );
res = pthread_mutexattr_destroy( &attr );
res = pthread_cond_init( &cond, NULL );

bool state = false;
res = pthread_mutex_lock( &mutex );
while ( !state )
{
res = pthread_cond_wait( &cond, &mutex );
if ( 0 != res )
{
res = pthread_mutex_unlock( &mutex );
return (void*)-1;
}
else
{
(void)res;
}
}
state = true;
res = pthread_mutex_unlock( &mutex );

return 0;
};

#define DEFAULT_PRIORITY 100
#define HIGHEST_PRIORITY 2
#define LOWEST_PRIORITY 255

#define wind_normalized_prio(prio, sched_type) \
({ int __p = sched_get_priority_min(sched_type) + ( ( ( LOWEST_PRIORITY - (prio) ) * ( sched_get_priority_max(sched_type) - sched_get_priority_min(sched_type) ) ) / LOWEST_PRIORITY ); __p; })

int main()
{
mlockall(MCL_CURRENT | MCL_FUTURE);

struct sched_param parA;
parA.sched_priority = wind_normalized_prio(DEFAULT_PRIORITY, SCHED_FIFO);
pthread_t threadA;
pthread_attr_t pthread_attrA;
int res;

res = pthread_attr_init(&pthread_attrA);
res = pthread_attr_setinheritsched (&pthread_attrA, PTHREAD_EXPLICIT_SCHED);
res = pthread_attr_setschedpolicy (&pthread_attrA, SCHED_FIFO);
res = pthread_attr_setschedparam( &pthread_attrA, &parA );
res = pthread_create( &threadA, &pthread_attrA, bodyA, NULL );
#ifdef __XENO__
pthread_set_name_np( threadA, "threadA" );
#endif
res = pthread_attr_destroy( &pthread_attrA );



struct sched_param parB;
parB.sched_priority = wind_normalized_prio(DEFAULT_PRIORITY, SCHED_FIFO);
pthread_t threadB;
pthread_attr_t pthread_attrB;

res = pthread_attr_init(&pthread_attrB);
res = pthread_attr_setinheritsched (&pthread_attrB, PTHREAD_EXPLICIT_SCHED);
res = pthread_attr_setschedpolicy (&pthread_attrB, SCHED_FIFO);
pthread_attr_setschedparam( &pthread_attrB, &parB );
res = pthread_create( &threadB, &pthread_attrB, bodyB, NULL );
#ifdef __XENO__
pthread_set_name_np( threadB, "threadB" );
#endif
res = pthread_attr_destroy( &pthread_attrB );


pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_mutexattr_t attr;

res = pthread_mutexattr_init( &attr );
res = pthread_mutexattr_setprotocol( &attr, PTHREAD_PRIO_INHERIT );
res = pthread_mutex_init( &mutex, &attr );
res = pthread_mutexattr_destroy( &attr );
res = pthread_cond_init( &cond, NULL );

bool state = false;
res = pthread_mutex_lock( &mutex );
while ( !state )
{
res = pthread_cond_wait( &cond, &mutex );
if ( 0 != res )
{
res = pthread_mutex_unlock( &mutex );
return -1;
}
else
{
(void)res;
}
}
state = true;
res = pthread_mutex_unlock( &mutex );

return 0;
}

------------------------------------
Linux without gdb : Ok
------------------------------------

------------------------------------
Linux with gdb : Ok
------------------------------------
Thread [3] 5111 (Suspended : Container)
__kernel_vsyscall() at 0xb7fe1424
pthread_cond_wait@domain.hid() at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/pthread_cond_wait.S:142 0xb7fbd4ad
bodyB() at /home/generation/Projets/PosixTest/src/Main.cpp:55 0x8048af1
start_thread() at pthread_create.c:304 0xb7fb8cc9
clone() at ../sysdeps/unix/sysv/linux/i386/clone.S:130 0xb7e1469e

Thread [2] 5110 (Suspended : Container)
__kernel_vsyscall() at 0xb7fe1424
pthread_cond_wait@domain.hid() at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/pthread_cond_wait.S:142 0xb7fbd4ad
bodyA() at /home/generation/Projets/PosixTest/src/Main.cpp:21 0x8048a01
start_thread() at pthread_create.c:304 0xb7fb8cc9
clone() at ../sysdeps/unix/sysv/linux/i386/clone.S:130 0xb7e1469e

Thread [1] 5106 (Suspended : Signal : SIGINT:Interrupt)
__kernel_vsyscall() at 0xb7fe1424
pthread_cond_wait@domain.hid() at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/pthread_cond_wait.S:142 0xb7fbd4ad
main() at /home/generation/Projets/PosixTest/src/Main.cpp:131 0x8048dfa

------------------------------------
Xenomai without gdb : Ok
------------------------------------
generation@domain.hid$ cat /proc/xenomai/sched
CPU PID CLASS PRI TIMEOUT TIMEBASE STAT NAME
0 0 idle -1 - master R ROOT/0
1 0 idle -1 - master R ROOT/1
0 5025 rt 0 - master W PosixTest
0 5026 rt 60 - master W threadA
0 5027 rt 60 - master W threadB

------------------------------------
Xenomai with gdb : Nok
------------------------------------

->Step 1 : (break point on pthread_cond_wait)

Thread [2] 5193 (Suspended : Breakpoint)
bodyA() at /home/generation/Projets/PosixTest/src/Main.cpp:21 0x8048b0f
0xb7fc30b2
start_thread() at pthread_create.c:304 0xb7fa4cc9
clone() at ../sysdeps/unix/sysv/linux/i386/clone.S:130 0xb7df869e

Thread [1] 5188 (Suspended : Container)
__kernel_vsyscall() at 0xb7fe1424
mmap() at ../sysdeps/unix/sysv/linux/i386/mmap.S:62 0xb7df4a88
allocate_stack() at allocatestack.c:489 0xb7fa563b
__pthread_create_2_1() at pthread_create.c:458 0xb7fa563b
__real_pthread_create() at 0xb7fca382
__wrap_pthread_create() at 0xb7fc2e2f
main() at /home/generation/Projets/PosixTest/src/Main.cpp:110 0x8048e7e

->Step 2 : break point after pthread_cond_wait. pthread_cond_wait retrun 1 (EPERM)

Thread [3] 5204 (Suspended : Container)
__kernel_vsyscall() at 0xb7fe1424
__lll_lock_wait_private() at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/lowlevellock.S:95 0xb7fac133
_L_lock_2466() at 0xb7fa5d2a
start_thread() at pthread_create.c:295 0xb7fa4ec1
clone() at ../sysdeps/unix/sysv/linux/i386/clone.S:130 0xb7df869e

Thread [2] 5193 (Suspended : Step)
bodyA() at /home/generation/Projets/PosixTest/src/Main.cpp:22 0x8048b24
0xb7fc30b2
start_thread() at pthread_create.c:304 0xb7fa4cc9
clone() at ../sysdeps/unix/sysv/linux/i386/clone.S:130 0xb7df869e

Thread [1] 5188 (Suspended : Container)