Bug 141181 - pthread_self() does not work correctly
Summary: pthread_self() does not work correctly
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 2
Hardware: i686
OS: Linux
medium
high
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Brian Brock
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2004-11-29 19:52 UTC by jozef CERNAK
Modified: 2007-11-30 22:10 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2004-11-29 21:28:21 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description jozef CERNAK 2004-11-29 19:52:55 UTC
Description of problem: phthread_self() produces incorrect results

Version-Release number of selected component (if applicable):
kernel-2.6.9-1.6_FC2
glibc-2.3.3-27.1

How reproducible: I compiled program from 
http://web.umr.edu/~ercal/284/thread_ex1F.c

gcc thread_ex1F.c -lpthread
or with -D_REENTRANT
after
./a.out

/**************************************************************************/
/*   PROGRAM DESCRIPTION:                                            
    */
/*   The main() uses thr_create() to create as many as thread_num
threads.*/
/*   Then the main() waits for the termination of the threads using  
    */
/*   thr_join() and displays the message/value returned from two
threads. */
/*   In the thread routine, it displays the message passed from main()
   */
/*   It also displays the value of a global variable which varies from
   */
/*   1 to thread_num. At last, thread routine uses thr_exit() to
return   */
/*   an integer to main(). The value of the integer is 2 times the
thread */
/*   ID.                                                             
    */
/*                                                                   
    */
/*   During the change/display of the global variable, thr_yield() is
    */
/*   used to cause the current thread to yield its execution to
another   */
/*   thread.                                                         
    */
/*                                                                 */
/* COMPILATION: gcc -o program program.c -lpthread      (*LINUX*)  */
/* COMPILATION: gcc -o program program.c -lpthread -lrt (*Solaris*)*/
/**************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h> /* POSIX threads */

#define thread_num 4

void *thread_routine(void *);	/* prototype of thread routine */
int sharedVar;			/* global variable */

int main ()
{	
    void *pRtnValue;	 /* pointer to void */
    pthread_t tid[thread_num]; /* thread id */
    pthread_t departed;

    /* strings to be passed to threads */
    int iValue[thread_num];
    int i; /* counter */
    sharedVar = 0;

    signal(SIGALRM, SIG_IGN);

    for (i = 0; i < thread_num; i++)
    {
        iValue[i] = i;
    }

    printf("main() process has PID= %d and PPID=%d.\n", getpid(),
getppid());

    /* create threads with passing strings */
    for (i = 0; i < thread_num; i++)
    {
        pthread_create(tid + i, NULL, thread_routine, iValue + i );
    }

    for (i = 0; i < thread_num; i++)
    {
        ++sharedVar; /* change the value of global variable */
        pthread_yield(); 	/*   For Solaris use: sched_yield();  */
    }

    system("ps -acefl | grep ercal");

    for (i = 0; i < thread_num; i++)
    {
        if( pthread_join(tid[i], &pRtnValue) == 0 )
        {
            /* display the thread id and return value */
            printf("main() joined with thread %d with return value %d.\n",
                   tid[i], *(int *)pRtnValue);
        }
        else
        {
            perror("pthread_join() failure.");
            exit(1);
        }
    }

    return(0);
}


void *thread_routine (void *arg)
{
    int pid, i; /* local counter */

    /* display the process id */
    printf("thread %d has processID= %d and PPID=%d.\n", 
                            pthread_self(), getpid(), getppid());

  pid = fork();
  if ( pid == 0 )  /* child code begins */
  {
    /* display the passed value */
    printf("Child (PID=%d) of thread %d received message from main()
of %d.\n", 
           getpid(), pthread_self(), *(int *)arg);

    for (i = 0; i < thread_num; i++)
    {
        /* display the value of the global variable */
        printf("Child (PID=%d) of thread %d: sharedVar now is %d.\n",
getpid(), pthread_self(), sharedVar);
        pthread_yield(); 	/*   For Solaris use: sched_yield();  */
    }

          printf("Child (PID=%d) of thread %d EXITING .....\n", 
getpid(), pthread_self()); 
          _exit(0);

      }
   if ( pid > 0 )  /* PARENT CODE */
   { 

    *(int *)arg = 2 * pthread_self();

    /* display the return value */
    printf("thread %d (PID=%d) will return an integer of %d.\n", 
           pthread_self(), getpid(), *(int *)arg);

    /* thread exit with an integer */
    pthread_exit (arg);
   }
}


I received incorret thread's ID

as is shown
[cernak@localhost c_programy]$ ./a.out
main() process has PID= 2678 and PPID=2581.
thread -151090256 has processID= 2678 and PPID=2581.
Child (PID=2683) of thread -151090256 received message from main() of 0.
Child (PID=2683) of thread -151090256: sharedVar now is 1.
thread -151090256 (PID=2678) will return an integer of -302180512.
thread -161580112 has processID= 2678 and PPID=2581.
Child (PID=2684) of thread -161580112 received message from main() of 1.
Child (PID=2684) of thread -161580112: sharedVar now is 1.
thread -161580112 (PID=2678) will return an integer of -323160224.
thread -172069968 has processID= 2678 and PPID=2581.
Child (PID=2685) of thread -172069968 received message from main() of 2.
Child (PID=2685) of thread -172069968: sharedVar now is 1.
thread -172069968 (PID=2678) will return an integer of -344139936.
thread -182559824 has processID= 2678 and PPID=2581.
Child (PID=2686) of thread -182559824 received message from main() of 3.
Child (PID=2686) of thread -182559824: sharedVar now is 1.
thread -182559824 (PID=2678) will return an integer of -365119648.
Child (PID=2683) of thread -151090256: sharedVar now is 1.
Child (PID=2684) of thread -161580112: sharedVar now is 1.
Child (PID=2685) of thread -172069968: sharedVar now is 1.
Child (PID=2686) of thread -182559824: sharedVar now is 1.
Child (PID=2683) of thread -151090256: sharedVar now is 1.
Child (PID=2684) of thread -161580112: sharedVar now is 1.
Child (PID=2685) of thread -172069968: sharedVar now is 1.
Child (PID=2686) of thread -182559824: sharedVar now is 1.
Child (PID=2683) of thread -151090256: sharedVar now is 1.
Child (PID=2684) of thread -161580112: sharedVar now is 1.
Child (PID=2685) of thread -172069968: sharedVar now is 1.
Child (PID=2686) of thread -182559824: sharedVar now is 1.
Child (PID=2683) of thread -151090256 EXITING .....
Child (PID=2684) of thread -161580112 EXITING .....
Child (PID=2685) of thread -172069968 EXITING .....
Child (PID=2686) of thread -182559824 EXITING .....
0 S cernak    2687  2678 TS   21 -  1491 wait   20:07 pts/1   
00:00:00 sh -c ps -acefl | grep ercal
0 S cernak    2689  2687 TS   24 -  1129 pipe_w 20:07 pts/1   
00:00:00 grep ercal
main() joined with thread -151090256 with return value -302180512.
main() joined with thread -161580112 with return value -323160224.
main() joined with thread -172069968 with return value -344139936.
main() joined with thread -182559824 with return value -365119648.
[cernak@localhost c_programy]$

I tried more simple program with the same incorret thread ID.

I cannot deside what is going wrong.





Steps to Reproduce:
1.
2.
3.
  
Actual results:


Expected results:


Additional info:

Comment 1 Jakub Jelinek 2004-11-29 21:28:21 UTC
Nothing is wrong.  pthread_self () returns a pthread_t value.  It is a handle
for the current thread and it's meaning is completely implementation dependent.
For a program, it is just a magic cookie that can be get from pthread_self ()
or pthread__create, compared with pthread_equal, passed to pthread_join/pthread_detach/pthread_cancel and a couple of other functions.
If your program expects it to be small integer, it makes bad assumption.
For LinuxThreads it was a small integer, for NPTL it is a pointer, but that's
just implementation detail.


Note You need to log in before you can comment on or make changes to this bug.