Ken Cunningham wrote: > That is not usually how this is done, although it might work and is suitably > simple. The problem I suppose is the function definition can change somewhat > over time. > > Usually, the SDK features automatically supply the weak import attribute > features, based on your SDK and your deployment target. > > What was traditionally done (before the @available() compiler feature came > out) is something like this, using as an example the function > “pthread_threadid_np()” which is defined in the MacOSX 10.6 SDK and available > in MacOSX version 10.6 and later. > > MAC_OS_X_VERSION_MAX_ALLOWED = the SDK you are building against > MAC_OS_X_VERSION_MIN_REQUIRED = the minimum system you are willing to support > > ========== > #if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 > native_id = pthread_mach_thread_np(pthread_self()); > #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1060 > if (&pthread_threadid_np) { > (void) pthread_threadid_np(NULL, &native_id); > } else { > native_id = pthread_mach_thread_np(pthread_self()); > } > #else > (void) pthread_threadid_np(NULL, &native_id); > #endif > ========
Thanks; this code snippet confirms what I had guessed by looking at other code. > The function is automatically weak-linked by the SDK features. That's not what I see with the 'proc_pidinfo' function. I need to declare it with WEAK_IMPORT_ATTRIBUTE, so that the compiler does not eliminate about the NULL test. I'm thus applying this patch. The extra #if around the NULL test are there, to disable compiler warnings ../../gllib/get_ppid_of.c:245:7: warning: comparison of function 'proc_pidinfo' not equal to a null pointer is always true [-Wtautological-pointer-compare] if (proc_pidinfo != NULL) /* at runtime Mac OS X >= 10.5 ? */ ^~~~~~~~~~~~ ~~~~ 2021-12-21 Bruno Haible <br...@clisp.org> get_ppid_of, get_progname_of: Fix runtime error on Mac OS X < 10.5. Reported by Evan Miller <emmil...@gmail.com> <https://lists.gnu.org/archive/html/bug-gnulib/2021-12/msg00081.html>. * lib/get_ppid_of.c (proc_pidinfo): Declare with WEAK_IMPORT_ATTRIBUTE. (get_ppid_of): Test whether the symbol declared weak evaluates to non-NULL before invoking it. * lib/get_progname_of (get_progname_of): Declare with WEAK_IMPORT_ATTRIBUTE. (get_ppid_of): Test whether the symbol declared weak evaluates to non-NULL before invoking it. diff --git a/lib/get_ppid_of.c b/lib/get_ppid_of.c index dd4e38129..636dfa344 100644 --- a/lib/get_ppid_of.c +++ b/lib/get_ppid_of.c @@ -39,6 +39,12 @@ # include <AvailabilityMacros.h> # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 # include <libproc.h> +# if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +/* Mac OS X versions < 10.5 don't have this function. Therefore declare it as + weak, in order to avoid a runtime error when the binaries are run on these + older versions. */ +extern int proc_pidinfo (int, int, uint64_t, void *, int) WEAK_IMPORT_ATTRIBUTE; +# endif # endif #endif @@ -236,11 +242,16 @@ get_ppid_of (pid_t pid) /* Mac OS X >= 10.7 has PROC_PIDT_SHORTBSDINFO. */ # if defined PROC_PIDT_SHORTBSDINFO - struct proc_bsdshortinfo info; +# if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + if (proc_pidinfo != NULL) /* at runtime Mac OS X >= 10.5 ? */ +# endif + { + struct proc_bsdshortinfo info; - if (proc_pidinfo (pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof (info)) - == sizeof (info)) - return info.pbsi_ppid; + if (proc_pidinfo (pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof (info)) + == sizeof (info)) + return info.pbsi_ppid; + } # endif # if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 @@ -249,10 +260,15 @@ get_ppid_of (pid_t pid) 32-bit and 64-bit environments, and the kernel of Mac OS X 10.5 knows only about the 32-bit 'struct proc_bsdinfo'. Fortunately all the info we need is in the first part, which is the same in 32-bit and 64-bit. */ - struct proc_bsdinfo info; +# if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + if (proc_pidinfo != NULL) /* at runtime Mac OS X >= 10.5 ? */ +# endif + { + struct proc_bsdinfo info; - if (proc_pidinfo (pid, PROC_PIDTBSDINFO, 0, &info, 128) == 128) - return info.pbi_ppid; + if (proc_pidinfo (pid, PROC_PIDTBSDINFO, 0, &info, 128) == 128) + return info.pbi_ppid; + } # endif # endif diff --git a/lib/get_progname_of.c b/lib/get_progname_of.c index bdda3c60d..a5b99c038 100644 --- a/lib/get_progname_of.c +++ b/lib/get_progname_of.c @@ -47,6 +47,12 @@ # include <AvailabilityMacros.h> # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 # include <libproc.h> +# if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +/* Mac OS X versions < 10.5 don't have this function. Therefore declare it as + weak, in order to avoid a runtime error when the binaries are run on these + older versions. */ +extern int proc_pidinfo (int, int, uint64_t, void *, int) WEAK_IMPORT_ATTRIBUTE; +# endif # endif #endif @@ -276,11 +282,16 @@ get_progname_of (pid_t pid) /* Mac OS X >= 10.7 has PROC_PIDT_SHORTBSDINFO. */ # if defined PROC_PIDT_SHORTBSDINFO - struct proc_bsdshortinfo info; +# if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + if (proc_pidinfo != NULL) /* at runtime Mac OS X >= 10.5 ? */ +# endif + { + struct proc_bsdshortinfo info; - if (proc_pidinfo (pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof (info)) - == sizeof (info)) - return strdup (info.pbsi_comm); + if (proc_pidinfo (pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof (info)) + == sizeof (info)) + return strdup (info.pbsi_comm); + } # endif # if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 @@ -289,10 +300,15 @@ get_progname_of (pid_t pid) 32-bit and 64-bit environments, and the kernel of Mac OS X 10.5 knows only about the 32-bit 'struct proc_bsdinfo'. Fortunately all the info we need is in the first part, which is the same in 32-bit and 64-bit. */ - struct proc_bsdinfo info; +# if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 + if (proc_pidinfo != NULL) /* at runtime Mac OS X >= 10.5 ? */ +# endif + { + struct proc_bsdinfo info; - if (proc_pidinfo (pid, PROC_PIDTBSDINFO, 0, &info, 128) == 128) - return strdup (info.pbi_comm); + if (proc_pidinfo (pid, PROC_PIDTBSDINFO, 0, &info, 128) == 128) + return strdup (info.pbi_comm); + } # endif # endif