This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Compilation with MacPorts - Plugins fail to load

0

I'm attempting to compile Wireshark from the GitHub repo on macOS Sierra using MacPorts. I know there's a macosx-setup.sh script for installing all the dependencies, but I'd rather not go this route since I have my dependencies fulfilled by MacPorts and I don't want duplicates strewn around my system. I can build and run Wireshark but none of the plugins load. They each fail with an error like the following:

Couldn't load module /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/ethercat.so: dlopen(/Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/ethercat.so, 2): initializer function 0x10fd09b92 not in mapped image for /opt/local/lib/libgpg-error.0.dylib

The initializer function address is different with each build of Wireshark that I make. The steps I use for building are:

mkdir build
cd build
cmake ..
make
make app_bundle

CMake doesn't report any required dependencies missing, and GPG itself is discovered as follows:

-- Found GCRYPT: /opt/local/lib/libgcrypt.dylib (found suitable version "1.7.6", minimum required is "1.4.2") 
-- GCRYPT FOUND
-- GCRYPT includes: /opt/local/include
-- GCRYPT libs: /opt/local/lib/libgcrypt.dylib;/opt/local/lib/libgpg-error.dylib

I notice that libgpg-error.0.dylib in the build output differs from the one MacPorts provides.

diff /opt/local/lib/libgpg-error.0.dylib /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/Frameworks/libgpg-error.0.dylib
Binary files /opt/local/lib/libgpg-error.0.dylib and /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/Frameworks/libgpg-error.0.dylib differ

It appears that some paths in the Application-local dylib are being remapped in the build process (from otool -l):

Load command 10
          cmd LC_LOAD_DYLIB
      cmdsize 72
         name @executable_path/../Frameworks/libintl.8.dylib (offset 24)

It seems to me, that the Application-local dylib (not the MacPorts one) should be loading. I don't have any of these environment variables set:

$DYLD_FRAMEWORK_PATH
$DYLD_FALLBACK_FRAMEWORK_PATH
$DYLD_VERSIONED_FRAMEWORK_PATH
$DYLD_LIBRARY_PATH
$DYLD_FALLBACK_LIBRARY_PATH
$DYLD_VERSIONED_LIBRARY_PATH
$DYLD_ROOT_PATH
$DYLD_INSERT_LIBRARIES

I would expect Wireshark's dlopen call to first look in the application package before searching the system. Has anyone else built on a MacPorts system and run into this?

EDIT:

I did some tracking of the module load process by turning on some DYLD environment variables. I just looked at the docsis.so plugin.

The applicable parts of the debug trace are as follows:

dyld: Main executable mapped /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/MacOS/Wireshark
        __PAGEZERO at 0x00000000->0x100000000
            __TEXT at 0x10636E000->0x1069B6000
            __DATA at 0x1069B6000->0x106A1E000
        __LINKEDIT at 0x106A1E000->0x106B7B9F8
dyld: loaded: /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/MacOS/Wireshark

dyld: re-using existing development shared cache mapping 0x7FFF8A27D000->0x7FFFA5009FFF read execute init=5, max=5 0x7FFFA900A000->0x7FFFADBE4FFF read write init=3, max=3 0x7FFFB1BE5000->0x7FFFB915CFFF read init=1, max=1 0x7FFF9EEE0000->0x7FFF9F3C0000 (code signature)

This is where we're loading all the shared libraries on startup. Notice that libgpg-error.0.dylib is first loaded from the application package.

dyld: Mapping /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/MacOS/../Frameworks/libgpg-error.0.dylib
            __TEXT at 0x10A4BA000->0x10A4C7FFF with permissions r.x
            __DATA at 0x10A4C8000->0x10A4C8FFF with permissions rw.
        __LINKEDIT at 0x10A4C9000->0x10A4CD1E7 with permissions r..
            __DATA prefetching 0x10A4C8000 -> 0x10A4C8FFF
dyld: loaded: /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/MacOS/../Frameworks/libgpg-error.0.dylib

Here's the binding of the initialization function:

dyld: bind: libgpg-error.0.dylib:0x10A4C84B8 = libgpg-error.0.dylib:_gpg_err_init, *0x10A4C84B8 = 0x10A4C3B92

Then, it's called.

dyld: calling initializer function 0x10a4c3b92 in /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/MacOS/../Frameworks/libgpg-error.0.dylib

This looks like a lazy bind of the initialization function again, but it starts with two underscores.

dyld: lazy bind: libgpg-error.0.dylib:0x10A4C8078 = libgpg-error.0.dylib:__gpg_err_init, *0x10A4C8078 = 0x10A4BC345

Now the docsis plugin is loaded.

dlopen(/Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/docsis.so, 0x00000002)
dyld: Mapping /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/docsis.so
            __TEXT at 0x114D47000->0x114D6DFFF with permissions r.x
            __DATA at 0x114D6E000->0x114D84FFF with permissions rw.
        __LINKEDIT at 0x114D85000->0x114DABBDB with permissions r..
dyld: loaded: /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/docsis.so

Then libgpg-error.0.dylib is loaded again! But this time it's from MacPorts and it's going into a different part of memory.

dyld: Mapping /opt/local/lib/libgpg-error.0.dylib
            __TEXT at 0x114F68000->0x114F75FFF with permissions r.x
            __DATA at 0x114F76000->0x114F76FFF with permissions rw.
        __LINKEDIT at 0x114F77000->0x114F7BA37 with permissions r..
dyld: loaded: /opt/local/lib/libgpg-error.0.dylib

The initialization function is bound again. It's bound to the same address as before, but this time from the memory location holding the MacPorts version of the library.

dyld: bind: libgpg-error.0.dylib:0x114F764B8 = libgpg-error.0.dylib:_gpg_err_init, *0x114F764B8 = 0x10A4C3B92

Then the lazy bind of the init function with two underscores again.

dyld: forced lazy bind: libgpg-error.0.dylib:0x114F76078 = libgpg-error.0.dylib:__gpg_err_init, *0x114F76078 = 0x10A4BC345

The glib initializer is called, and then docsis is considered unused? Huh.

dyld: calling initializer function 0x114dd66ae in /opt/local/lib/libglib-2.0.0.dylib
dlclose(), found unused image 0x7fa2d2c1f610 docsis.so
dlclose(), deleting 0x7fa2d2c1f610 docsis.so
dyld: unloaded: /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/docsis.so

Then one (the MacPorts one, I think) of the gpg lib's images is considered unused.

dlclose(), found unused image 0x60000015c1a0 libgpg-error.0.dylib

It's unloaded.

dlclose(), deleting 0x60000015c1a0 libgpg-error.0.dylib
dyld: unloaded: /opt/local/lib/libgpg-error.0.dylib

Now DYLD spits out the error about not finding the initialization function for gpg.

  dlopen() failed, error: 'dlopen(/Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/docsis.so, 2): initializer function 0x10a4c3b92 not in mapped image for /opt/local/lib/libgpg-error.0.dylib
'
dyld: lazy bind: libgmodule-2.0.0.dylib:0x10B78E0C8 = libdyld.dylib:_dlerror, *0x10B78E0C8 = 0x7FFFA4D89907
dlerror()

It makes sense that I'm having this problem given the output of otool on Wireshark versus the docsis plugin:

hostname:~ username$ otool -L ~/src/github/wireshark/build/run/Wireshark.app/Contents/MacOS/Wireshark 
/Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/MacOS/Wireshark:
    @executable_path/../Frameworks/libgpg-error.0.dylib (compatibility version 22.0.0, current version 22.0.0)

hostname:~ username$ otool -L ~/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/docsis.so /Users/username/src/github/wireshark/build/run/Wireshark.app/Contents/PlugIns/wireshark/docsis.so: /opt/local/lib/libgpg-error.0.dylib (compatibility version 22.0.0, current version 22.0.0)

However, I’m not sure why the docsis plugin looks in one location for libgpg while the Wireshark binary looks elsewhere.

asked 28 Apr ‘17, 10:20

watkipet's gravatar image

watkipet
21114
accept rate: 0%

edited 28 Apr ‘17, 16:47


One Answer:

0

The problem is that the relative path translation normally performed by packaging/macosx/osx-app.sh is not occurring. osx-app.sh:424 looks at the Mach headers (using otool -hv) to determine whether the file in question is an executable, dynamic library, or bundle. It then passes the otool output through sed and awk to pull out a specific token. It appears that in the past (or on some other machine / macOS version / installation configuration?) otool spit out 4 lines of output and thus the sed command looked at line 4. However, on my machine, otool spits out only three lines. Thus:

  1. rpath translation fails silently when running make app_bundle
  2. The plugins use the MacPorts versions of libraries instead of the Wireshark.app versions
  3. The main Wireshark app successfully uses the Wireshark.app versions of the libraries (not sure why it's different here)
  4. Two different versions of the same libraries are loaded at runtime
  5. DYLD now cannot call the proper library initialization function when attempting to load the plugins--thus the cryptic error

If I can figure out how to contribute a change to the source, I'll try to do that. However, I'm concerned that the 4 versus 3 line output of otool is something specific to my machine / configuration and I'd just be breaking things for others. Anyone else run into this?

answered 04 May '17, 09:05

watkipet's gravatar image

watkipet
21114
accept rate: 0%