Hello, The purpose of this email is to report and document an issue in glibc with getpid; but I can submit a ticket to Savannah if necessary.
There's a window in which getpid won't work while the dynamic linker is binding symbols because the variable it relies on is not yet initialized. During startup the dynamic linker relocates itself, at _dl_start function, elf/rtld.c line 397. As a result, the getpid symbol is set to point to the implementation provided by the linker (sysdep/mach/hurd/dl-sysdep.c) which delegates to __proc_getpids. Later, in _dl_start_final, the full process of loading other libraries is started. At some point getpid is rebound to the libc implementation (sysdeps/mach/hurd/getpid.c) which returns the value cached in _hurd_pid. However, _hurd_pid is not initialized until later, when _dl_start_user is called to kick off the user program and eventually init_pids is executed. My first idea was to do like in the following patch: Index: glibc-2.22/sysdeps/mach/hurd/getpid.c =================================================================== --- glibc-2.22.orig/sysdeps/mach/hurd/getpid.c +++ glibc-2.22/sysdeps/mach/hurd/getpid.c @@ -24,7 +24,16 @@ pid_t __getpid (void) { /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock. */ - return _hurd_pid; + if (_hurd_pid != 0) + return _hurd_pid; + + { + pid_t pid, ppid; + int err, orphaned; + err = __USEPORT (PROC, + __proc_getpids (port, &pid, &ppid, &orphaned)); + return err ? -1 : pid; + } } libc_hidden_def (__getpid) weak_alias (__getpid, getpid) =================================================================== However, that wouldn't work either because _hurd_init, in charge of initializing _hurd_ports, required by __USEPORT, is not called yet. Actually, it's also called from _dl_start_user stage. Another option is to implement the fallback case as in dl-sysdep: Index: glibc-2.22/sysdeps/mach/hurd/getpid.c =================================================================== --- glibc-2.22.orig/sysdeps/mach/hurd/getpid.c +++ glibc-2.22/sysdeps/mach/hurd/getpid.c @@ -24,7 +24,17 @@ pid_t __getpid (void) { /* Assumes atomic word fetch and store, so doesn't lock _hurd_pid_lock. */ - return _hurd_pid; + if (_hurd_pid != 0) + return _hurd_pid; + + { + extern struct hurd_startup_data *_dl_hurd_data; + pid_t pid, ppid; + int err, orphaned; + err = __proc_getpids (_dl_hurd_data->portarray[INIT_PORT_PROC], + &pid, &ppid, &orphaned); + return err ? -1 : pid; + } } libc_hidden_def (__getpid) weak_alias (__getpid, getpid) =================================================================== I don't think it's a good idea (or possible at all?) to depend on hurdstartup.h, though. Right now, I don't see a proper solution. If anybody can think of one, just ping, I could allocate some time to work on it. Anyway, this is purely a cosmetic issue affecting only the output produced by the LD_DEBUG feature of the dynamic linker. At least, I'm not aware of any other glitches caused by this issue. It's probably a very low priority issue then. (that output being correct would be nice though :) Regards, Diego