At Thu, 17 Mar 2022 12:10:16 -0700, "Greg A. Woods" <woods%planix.ca@localhost> wrote: Subject: Re: pkg_delete crashing due to invalid glob(3) result on macOS 12.1 > > For my test program the call to glob() is converted to glob$INODE64(), > while in pkg_delete, it's still just calling plain glob() (and > apparently libSystem's plain glob() is broken!) Indeed -- but not broken, just not compatible with nbcompat/glob.h. Packages using libnbcompat, of which pkg_install is one, expect to use the libnbcompat glob(), and have been compiled against nbcompat/glob.h. However on macOS, 12.1 at least, the libSystem.dylib includes a plain glob() as well, and it is what was getting linked and called in my build: Process 45670 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 frame #0: 0x00007ff80927e1a0 libsystem_c.dylib`glob libsystem_c.dylib`glob: -> 0x7ff80927e1a0 <+0>: pushq %rbp 0x7ff80927e1a1 <+1>: movq %rsp, %rbp 0x7ff80927e1a4 <+4>: andl $0x7ffffeff, %esi ; imm = 0x7FFFFEFF 0x7ff80927e1aa <+10>: movl %esi, 0x18(%rcx) Target 0: (pkg_delete) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 * frame #0: 0x00007ff80927e1a0 libsystem_c.dylib`glob frame #1: 0x0000000100004234 pkg_delete`remove_files(path="/opt/pkg/.pkgdb/yajl-2.1.0nb1", pattern="+*") at file.c:255:9 frame #2: 0x0000000100001bfd pkg_delete`remove_pkg(pkg="yajl-2.1.0nb1") at pkg_delete.c:633:9 frame #3: 0x0000000100000d5d pkg_delete`main(argc=0, argv=0x00007ff7bfeff2f0) at pkg_delete.c:791:7 frame #4: 0x00000001000394fe dyld`start + 462 (lldb) However I found that if I manually re-link with an explicit reference to the libnbcompat.a file (i.e. instead of using -lnbcompat), then it gets the right glob(), and it works A-OK: Process 46347 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 frame #0: 0x000000010000b654 pkg_delete`glob(pattern="/opt/pkg/.pkgdb/yajl-2.1.0nb1/+*", flags=32, errfunc=0x0000000000000000, pglob=0x00007ff7bfefec68) at __glob13.c:200:2 197 int c; 198 Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; 199 -> 200 _DIAGASSERT(pattern != NULL); 201 202 patnext = (const unsigned char *) pattern; 203 if (!(flags & GLOB_APPEND)) { Target 0: (pkg_delete) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 * frame #0: 0x000000010000b654 pkg_delete`glob(pattern="/opt/pkg/.pkgdb/yajl-2.1.0nb1/+*", flags=32, errfunc=0x0000000000000000, pglob=0x00007ff7bfefec68) at __glob13.c:200:2 frame #1: 0x0000000100004954 pkg_delete`remove_files(path="/opt/pkg/.pkgdb/yajl-2.1.0nb1", pattern="+*") at file.c:255:9 frame #2: 0x000000010000231d pkg_delete`remove_pkg(pkg="yajl-2.1.0nb1") at pkg_delete.c:633:9 frame #3: 0x000000010000147d pkg_delete`main(argc=0, argv=0x00007ff7bfeff2f0) at pkg_delete.c:791:7 frame #4: 0x00000001000554fe dyld`start + 462 (lldb) c Process 46347 resuming Process 46347 exited with status = 0 (0x00000000) (lldb) It turns out this is because I had added -lpthread to the LIBS settings for all pkg_install programs (in order to be able to static-link this package, e.g. on NetBSD), but I had put it before -lnbcompat (as I also had to add "@LIBS@")! So, if I relink but move -lnbcompat before -lpthread, then it links with the libnbcompat.a copy of glob() on Darwin and all is well. I'm surprised that the use of the system liblzma.dylib doesn't also do the same thing as it also depends on libSystem.dylib -- but libpthread.dylib is some special, and it links to MANY more dynamic libraries, and perhaps one of them might need to resolve glob() if libnbcompat.a doesn't do it first. # otool -L pkg_delete pkg_delete: /opt/pkg/lib/liblzma.5.dylib (compatibility version 8.0.0, current version 8.5.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0) # otool -L /opt/pkg/lib/liblzma.5.dylib /opt/pkg/lib/liblzma.5.dylib: /opt/pkg/lib/liblzma.5.dylib (compatibility version 8.0.0, current version 8.5.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0) I really wish (more) people would test with static linking! Here's a case where such additional dependencies can cause problems if mixing dynamic libraries and static libraries and _not_ having _all_ of the dynamic library's dependencies also properly listed, and in the right order, and with the knowledge that most dynamic libraries may pull in the system library immediately and thus prevent overriding system symbols with local ones. I guess this is also the reason why libtool prefers to use the libfoo.a filenames directly as opposed to "-L/local/dir -lfoo". So, the "fix" is approximately this (also note I've fixed the library lists so that they are consistent and complete too!): Index: pkgtools/pkg_install/files/add/Makefile.in =================================================================== RCS file: /cvs/master/m-NetBSD/main/pkgsrc/pkgtools/pkg_install/files/add/Makefile.in,v retrieving revision 1.34 diff -u -r1.34 Makefile.in --- pkgtools/pkg_install/files/add/Makefile.in 28 Oct 2020 16:52:43 -0000 1.34 +++ pkgtools/pkg_install/files/add/Makefile.in 17 Mar 2022 21:14:42 -0000 @@ -22,7 +22,7 @@ SSL_SUPPORT= @ssl_support@ .if empty(BOOTSTRAP) -LIBS= -linstall -lnetpgpverify -larchive -lbz2 -lz -lfetch +LIBS= -linstall -lnetpgpverify -larchive -lfetch -llzma -lbz2 -lz @LIBS@ -lpthread .if !empty(SSL_SUPPORT) LIBS+= -lssl -lcrypto CPPFLAGS+= -DHAVE_SSL Index: pkgtools/pkg_install/files/admin/Makefile.in =================================================================== RCS file: /cvs/master/m-NetBSD/main/pkgsrc/pkgtools/pkg_install/files/admin/Makefile.in,v retrieving revision 1.30 diff -u -r1.30 Makefile.in --- pkgtools/pkg_install/files/admin/Makefile.in 27 Dec 2015 12:18:20 -0000 1.30 +++ pkgtools/pkg_install/files/admin/Makefile.in 17 Mar 2022 21:15:09 -0000 @@ -30,7 +30,7 @@ CPPFLAGS= @CPPFLAGS@ -I. -I$(srcdir) -I../lib .if empty(BOOTSTRAP) -LIBS= -linstall -lnetpgpverify -larchive -lbz2 -lz -lfetch +LIBS= -linstall -lnetpgpverify -larchive -lfetch -llzma -lbz2 -lz @LIBS@ -lpthread .if !empty(SSL_SUPPORT) LIBS+= -lssl -lcrypto CPPFLAGS+= -DHAVE_SSL Index: pkgtools/pkg_install/files/create/Makefile.in =================================================================== RCS file: /cvs/master/m-NetBSD/main/pkgsrc/pkgtools/pkg_install/files/create/Makefile.in,v retrieving revision 1.30 diff -u -r1.30 Makefile.in --- pkgtools/pkg_install/files/create/Makefile.in 28 Oct 2020 16:52:43 -0000 1.30 +++ pkgtools/pkg_install/files/create/Makefile.in 17 Mar 2022 21:15:35 -0000 @@ -28,7 +28,7 @@ OBJS= main.o perform.o pl.o util.o build.o .if empty(BOOTSTRAP) -LIBS= -linstall -lnetpgpverify -larchive -lbz2 -lz -lfetch @LIBS@ +LIBS= -linstall -lnetpgpverify -larchive -lfetch -llzma -lbz2 -lz @LIBS@ -lpthread .if !empty(SSL_SUPPORT) LIBS+= -lssl -lcrypto .endif Index: pkgtools/pkg_install/files/delete/Makefile.in =================================================================== RCS file: /cvs/master/m-NetBSD/main/pkgsrc/pkgtools/pkg_install/files/delete/Makefile.in,v retrieving revision 1.24 diff -u -r1.24 Makefile.in --- pkgtools/pkg_install/files/delete/Makefile.in 7 Sep 2015 09:06:05 -0000 1.24 +++ pkgtools/pkg_install/files/delete/Makefile.in 17 Mar 2022 21:11:11 -0000 @@ -15,7 +15,7 @@ CC= @CC@ CCLD= $(CC) -LIBS= -linstall -lnetpgpverify -larchive -lbz2 -lz -lfetch @LIBS@ +LIBS= -linstall -lnetpgpverify -larchive -lfetch -llzma -lbz2 -lz @LIBS@ -lpthread .if !empty(SSL_SUPPORT) LIBS+= -lssl -lcrypto Index: pkgtools/pkg_install/files/info/Makefile.in =================================================================== RCS file: /cvs/master/m-NetBSD/main/pkgsrc/pkgtools/pkg_install/files/info/Makefile.in,v retrieving revision 1.31 diff -u -r1.31 Makefile.in --- pkgtools/pkg_install/files/info/Makefile.in 27 Dec 2015 12:18:20 -0000 1.31 +++ pkgtools/pkg_install/files/info/Makefile.in 17 Mar 2022 21:12:17 -0000 @@ -22,7 +22,7 @@ LDFLAGS= @LDFLAGS@ -L../lib .if empty(BOOTSTRAP) -LIBS= -linstall -lnetpgpverify -larchive -lbz2 -lz -lfetch @LIBS@ +LIBS= -linstall -lnetpgpverify -larchive -lfetch -llzma -lbz2 -lz @LIBS@ -lpthread .if !empty(SSL_SUPPORT) LIBS+= -lssl -lcrypto .endif Of course if pkgsrc were using Simon's mk-files then all the local libraries could be lib*.dylib's too and maybe none of this would be strictly necessary. -- Greg A. Woods <gwoods%acm.org@localhost> Kelowna, BC +1 250 762-7675 RoboHack <woods%robohack.ca@localhost> Planix, Inc. <woods%planix.com@localhost> Avoncote Farms <woods%avoncote.ca@localhost>
Attachment:
pgpkxCqAbox3T.pgp
Description: OpenPGP Digital Signature