After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 788408 - Problems loading Geany plugins since commit a922291
Problems loading Geany plugins since commit a922291
Status: RESOLVED INVALID
Product: gtk-mac-bundler
Classification: Other
Component: General
unspecified
Other Mac OS
: Normal normal
: ---
Assigned To: GTK Mac Integration Maintainers
GTK Mac Integration Maintainers
Depends on:
Blocks:
 
 
Reported: 2017-10-01 22:40 UTC by Jiri Techet
Modified: 2019-02-22 05:07 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Jiri Techet 2017-10-01 22:40:08 UTC
We got the following bug report in Geany

https://github.com/geany/geany/issues/1555

where loading some plugins makes Geany freeze. When investigating, I finally found that it's caused by commit a922291 in gtk-mac-bundler. Here's a bundle created with the bundler from the a922291 commit

https://www.dropbox.com/s/fkj1sehiveofkbx/Geany-a9222.app.zip?dl=0

and here a bundle created by the bundler from the previous commit where the problem doesn't exist:

https://www.dropbox.com/s/bet6lrmlz6x4qnu/Geany-c7a02.app.zip?dl=0

To reproduce the issue, just launch Geany, from the Tools menu select the Plugin Manager and try to activate the Debugger plugin. With commit a922291 the whole application freezes, with the previous commit the plugin loads fine. Also when run from command-line without creating the bundle there's no problem loading the plugin.

I've diffed the two bundles and all the *.dylib files under Contents/Resources/lib differ. There are no other changes in the bundle apart from that.

Let me know if you need more information - I don't quite understand what changes in the libraries the bundler does and I didn't study the particular commit.
Comment 1 Jiri Techet 2017-10-01 22:44:42 UTC
One more piece of information - these bundles were created without any signing so app signing doesn't seem to be the issue here.
Comment 2 John Ralls 2017-10-02 01:25:04 UTC
Actually neither bundle opens because it can't find /Users/jhbuild/gtk/inst/share/geany/geany.glade. I got around that by creating the requisite directory and copying the share directory from one of the bundles, but the next problem is that there don't seem to be any plugins: Tools>Plugin Manager is empty. Got around *that* by coping Resources/lib to /Users/jhbuild/gtk/inst as well. With that I can reproduce the problem.

Interestingly bypassing the launcher-script on the commandline (Geany-a9222.app/Contents/MacOS/geany-bin) runs without the freeze).


With that established I was able to restore operation of a9222 by removing line  41 (export DYLD_LIBRARY_PATH="$bundle_lib") from the launcher script.

The difference in the dylibs between the two bundles is that the older bundle leaves the id of the dylib as its autotools-installed path (/Users/jhbuild/gtk/inst/lib in this case) while the new one changes the id to @executable_path/../Resources/lib. This is necessary for the Xcode-8 versions of codesign becuase when the id points out of the bundle it thinks the binary shouldn't be in the bundle and refuses to sign it. 

Please verify that that fixes it for you.
Comment 3 Jiri Techet 2017-10-02 10:01:20 UTC
Thanks John for looking into this.

While the hang doesn't happen any more, it doesn't quite fix the problem. What happens now is that the VTE terminal isn't loaded (notice the missing terminal tab at the bottom of the window). The original problem was actually somehow VTE-related - those plugins that used to hang did hang when they called some functions from VTE so now when VTE isn't loaded, the hang doesn't happen.
Comment 4 John Ralls 2017-10-02 14:08:08 UTC
I thought from the Geany bug report that the problem was that they were trying to load a second instance of libvte.

How exactly are you loading plugins and how are they linking (or loading) vte? 

BTW, why are there two copies of libvte (libvte.dylib and libvte.9.dylib) in the bundle?
Comment 5 Jiri Techet 2017-10-03 21:06:19 UTC
VTE is loaded in Geany here (dynamically based on the vte library availability):

https://github.com/geany/geany/blob/master/src/vte.c#L289

and plugins here:

https://github.com/geany/geany/blob/master/src/plugins.c#L615

The hang happens when Geany has loaded VTE (not when Geany is started without terminal e.g. with geany -t) and when the plugin calls vte_terminal_new() such as here:

https://github.com/geany/geany-plugins/blob/master/debugger/src/debug.c#L1044

At this moment the following is printed to the console when started through command-line:

(geany-bin:63535): GLib-GObject-WARNING **: cannot register existing type 'VteTerminal'

(geany-bin:63535): GLib-CRITICAL **: g_once_init_leave: assertion 'result != 0' failed

(geany-bin:63535): GLib-GObject-CRITICAL **: g_object_new: assertion 'G_TYPE_IS_OBJECT (object_type)' failed

after which the application hangs.

---

Thanks for pointing me to the 2 vte libraries - I can remove the libvte.9 one. libvte.dylib is a symlink to libvte.9.dylib - in the bundle config file I specified libvte*.dylib but the bundler seems to copy the symlinked files and the 9 file isn't actually necessary.
Comment 6 John Ralls 2017-10-03 23:45:48 UTC
Simply telling me that you use g_module_open() would have been sufficient. 

No, you can't remove libvte.9.dylib because geany/debugger.so is linked to it by that name; I expect that the other two are as well.

So that "register existing type" problem comes from GModule finding the libvte symbols in debugger.so when it had already found them in libvte when is was g_module_opened. And that's the problem: They're different libraries. Change libvte.dylib to a link and it works because the linker now knows that they're the same symbol and doesn't try to load it twice. A better fix still would be to change the code at https://github.com/geany/geany/blob/master/src/vte.c#L282 to load the libvte.9.dylib.

Even better yet would be to use g_module_open correctly and let it find the right suffix to use. You can have configure determine the name of libvte via PKG_PROG_PKG_CONFIG --libs-only-l and set LIBVTE to that value, then do
    g_module_open (HAVE_VTE, G_MODULE_BIND_LAZY);
avoiding the fragile iteration through a list of possible names and the Gtk3 conditional.
Comment 7 Jiri Techet 2017-10-04 08:15:38 UTC
Thanks John for noticing that the plugins are linked to the other library - that explains it and I've tried to use libvte.9.dylib in Geany and it works. By the way any idea why it worked before commit a922291 in gtk-mac-bundler?

I noticed you committed

https://github.com/jralls/gtk-mac-bundler/commit/9938068b73f2e6d304137b94ece713890b96eaa2

Maybe it's not a good idea because without it dynamic loading like the one Geany does doesn't work because it doesn't find the library and it actually wasn't the source of the problem.

The reason I believe Geany does the loading this way is because it tries to work with whatever VTE version the user has installed regardless of which one was available at the configure time. The API of libvte-2.91 differs slightly from the API of libvte2_90 which again differs from the API of libvte 2.8 used for GTK2 and the code tries to handle all the different behaviours.
Comment 8 John Ralls 2017-10-04 13:54:58 UTC
Jiri,

Yes, I'll revert 99380.

No, I can't explain why it might have worked before.

Yes, of course the API from libvte2 differs from libvte, but so does Gtk3 differ from Gtk2 and that's fixed at compile time. If the vte folks have API--or even ABI--differences between v2.90 and v2.91 that's a major fail on their part. Such flexibility is rather pointless: debugger.so doesn't dlopen libvte, it links against it at compile time and if the installed version isn't ABI compatible with the one it's linked against it won't load and you'll be right where you started with this bug.
Comment 9 Jiri Techet 2017-10-04 15:16:31 UTC
Yes, VTE API is rather messy unfortunately (on linux you have separate packages for each API/ABI version such as libvte-2.91, libvte-2.90, libvte and then each of them has a version number such as 0.45 for libvte-2.91, 0.28 for libvte etc.).

Geany tries to work with all of these but doesn't take the responsibility for the plugins which are distributed separately from Geany (unless someone like me includes them in the macOS bundle to simplify things for users). Also Geany tries to avoid hard-dependencies on other libraries except GTK which is why VTE is loaded dynamically based on its availability.

Yes, you are right that there might be a clash of VTE versions in the case of the plugins which are hard-linked against certain version of VTE while Geany loads a different version but from the Geany perspective it's the responsibility of the plugin developers to fix that.

Thanks again for helping me with this issue.
Comment 10 Jiri Techet 2017-10-05 15:57:30 UTC
Sorry John for hijacking this thread but I have a related question - VTE is loaded correctly from the bundle now but when I run run Geany from the command-line from jhbuild shell, VTE doesn't load. I tried setting DYLD_LIBRARY_PATH but this just leads to some symbol clash of system libsqlite and jhbuild libsqlite and apparently isn't the right thing to do. I have a feeling it worked in the past - has there been any change related to this? Or is it related to SIP?
Comment 11 John Ralls 2017-10-05 16:20:33 UTC
It's at least partly related to SIP in that SIP strips DYLD_LIBRARY_PATH when forking what it considers critical programs, including /usr/bin/bash. But as I observed in comment 2, GModule is using the original installation path, /Users/jhbuild/gtk/inst. I don't remember offhand whether that's something GModule configures on its own or if the client application configures it, but I suspect that once you fix that it will work for you. A straightforward way is to use gtkosx_application_bundle* from gtk-mac-integration to find the right path and to use g_module_build_path() to get the correct filename that you then pass to g_module_open().
Comment 12 Jiri Techet 2017-10-11 11:03:17 UTC
But I'm trying to load it from the original installation path - for debugging purposes I just want to be able to run Geany from jhbuild shell after installation. I would expect that for jhbuild installed under

/Users/jhbuild/gtk/inst

modules loaded with g_module_open() get loaded from

/Users/jhbuild/gtk/inst/lib

but this isn't the case.
Comment 13 Jiri Techet 2017-10-11 11:15:17 UTC
Ah, wait, it's probably because I created a patch to VTE which checks its path relative to the bundle. So I think VTE actually loads but doesn't find the files it needs and fails to initialize. I'll investigate.
Comment 14 Jiri Techet 2017-10-11 11:52:27 UTC
Back again - it wasn't the problem. I used the files tool from XCode instruments to see which files get open and apart from trying the current directory, /usr/lib, /usr/local/lib, it just tries /Users/jhbuild/lib/libvte9.dylib but nothing from /Users/jhbuild/gtk/inst so this one seems to be stripped away. It's possible to configure Geany also without the integration library so I can't use gtkosx_* functions and I don't want to add too many OS X specific hacks to Geany.

Anyway, this is mostly for my debugging purposes as users can use the bundle which works so it doesn't matter much. I can specify the path to VTE on Geany command-line which works so it's not a big issue. I was just reporting because I had a feeling it used to work in the past but it was probably in the pre-SIP era.
Comment 15 John Ralls 2017-10-11 13:40:20 UTC
> It's possible to configure Geany also without the integration library so I can't use gtkosx_* functions and I don't want to add too many OS X specific hacks to Geany.

You're looking at that the wrong way: The point of gtk-mac-bundler is the project team to create an  bundle for distribution to users, not for J. Random User to create his own. That means the project team's Mac maintainer, i.e. you, sets up a single configurattion for producing a bundle. You're trying to make the best possible UX for Mac users who install your app and bundling without mac integration isn't going to get you there.

That said you can use the launcher script's path detection to set useful environment variables, either ones used by ltdl or dlopen or ones that Geany itself reads and uses to construct paths.

Note too that SIP won't interfere with DYLD environment variables set in the launcher script as geany-bin isn't a protected executable.

This conversation is more of a support one than about a bug so let's please continue it on gtk-osx-users.
Comment 16 Jiri Techet 2017-10-11 14:27:56 UTC
I'll answer here as I don't need any support and there's really no reply needed and writing the below would lack context in the mailing list.

I understand it exactly the way you describe - I create a single bundle where everything is configured and which users can download. Absolutely no problem with that, VTE and everything works there, including the mac integration. You can just check the Geany's download page where you get it.

But I also want to be able to fix various OSX specific problems when needed and then I want to run Geany from the command-line and have VTE working without having to create bundle because it's time consuming and not really suitable for debugging. At the moment, VTE runs only when I set the path to VTE manually through a command-line parameter. Since this is really used by me only (or at least mostly), I don't want to add some additional hacks to Geany just to have VTE running when I start it from the command-line without bundle.

I also want to keep Geany buildable without the mac integration and bundle creation because Geany is also available through MacPorts and homebrew. The bundle is of course superior to these and normal users should use the bundle instead. But it's easier to get a development environment set up through homebrew and avoid the jhbuild nightmare (such as when sourceforge is down or there's some bug when updating OS X such as the one with bison or cmake this time) so I want to keep this option for potential Geany contributors.

So again, this wasn't a big issue for me, I can set the VTE path on geany command line when debugging, I was just asking in case I was overlooking something simple like some environment variable settings.
Comment 17 John Ralls 2017-10-11 23:36:49 UTC
Ah.

If you're running in a jhbuild shell with the same prefix that you used to build Geany and all of its dependencies then it should be exactly like a normal Unix build, i.e. the same as if you'd built with MacPorts.

If you're on 10.10 or later make a copy of /usr/bin/bash in ~/.local/bin and set $SHELL and $CONFIG_SHELL to point to the latter. That nicely works around SIP.
Comment 18 Jiri Techet 2017-10-12 07:35:02 UTC
Oh, setting SHELL to ~/.local/bin before running jhbuild shell really works. Interesting. Thanks!