NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/54661: pthread_self() returns invalid value in some circumstances



>Number:         54661
>Category:       lib
>Synopsis:       pthread_self() returns invalid value in some circumstances
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Oct 30 06:10:00 +0000 2019
>Originator:     tgl%sss.pgh.pa.us@localhost
>Release:        NetBSD 8.1
>Environment:
System: NetBSD nuc1.sss.pgh.pa.us 8.1 NetBSD 8.1 (GENERIC) #0: Fri May 31 08:43:59 UTC 2019 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
pthread_self() sometimes returns an invalid pointer ((void *) -1),
as illustrated in How-To-Repeat.  Now, it could be argued that the
failing example is pilot error because I didn't link with -lpthread.
The reason I think this is a bug to be fixed is that the problem also
arises in a case where a dynamically loadable library links with
-lpthread and uses pthread_self(), but it is loaded into a main
executable that does neither.  Neither component is violating any
man page requirement, but nonetheless the library sees behavior
that is clearly contrary to both POSIX (which says that pthread_self
shall not fail, full stop) and NetBSD's own pthread_self man page,
which mentions nothing of such corner-case requirements.

For context, the given test case works as I expect, with or without
-lpthread, on FreeBSD 11.0, OpenBSD 6.4, and Fedora 30.  The real-world
use case underlying this is that libpython 3.7 fails when loaded into
postgresql on NetBSD 8.0 or 8.1, as discussed at

https://www.postgresql.org/message-id/4344.1572380716%40sss.pgh.pa.us

>How-To-Repeat:
$ cat test.c
/* this is stdio.h and pthread.h, not sure if send-pr will break the code */
#include <stdio.h>
#include <pthread.h>

int main()
{
  pthread_t id = pthread_self();

  printf("self = %p\n", id);
  return 0;
}
$ gcc test.c
$ ./a.out
self = 0xffffffffffffffff
$ gcc test.c -lpthread
$ ./a.out
self = 0x754ae5a2b800

I argue that I should get a valid result either way.

>Fix:
I haven't looked at the code, but I surmise that pthread_self()
per se is in libc (else this test case would fail at link time)
but it returns a bogus value unless libpthread initialized some
static storage, and that initialization fails to happen unless
libpthread was loaded *at program start*.

A minimum fix would be to arrange for said initialization to
happen when libpthread is loaded, even if that happens dynamically
as a result of dlopen().  That would be enough to solve my immediate
use case.  I note though that other modern systems seem to manage
to return a valid value even if libpthread is never loaded.
It's arguable that that's what POSIX requires: if the function is
there, it's not supposed to fail.



Home | Main Index | Thread Index | Old Index