1
0
Fork 0
go_plugin_demo/README.md
Frédéric G. MARAND be1f9236e0 Code and findings updated for go 1.27.3.
tl;dr:
- Linux debugging works
- macOS running works, debugging doesn't.
2026-11-02 17:17:20 +01:00

5.6 KiB

Démonstration des greffons Go

Un programme hôte, cmd/demo, charge deux greffons, plugins/foo et plugins/bar, par le paquet plugin, et leur confie du travail par une fonction de type Worker.

  • Écrit en 2020 pour Go 1.14.
  • Revérifié le 2026-11-02 avec Go 1.27.3 et Delve 1.27.0 : méthode et résultats dans VERIFICATION.md.

Utilisation

Depuis la racine du dépôt, car les greffons sont chargés par un chemin relatif :

make all                 # hôte et greffons, en mode déboguage
./cmd/demo
make FLAGS= clean all    # les mêmes, optimisés
go tool dlv exec ./cmd/demo

Delve est épinglé dans go.mod par la directive tool.

Déboguage des greffons

Sous Linux, Delve entre dans les greffons :

  • points d'arrêt, variables et pas à pas y fonctionnent ;
  • les valeurs renvoyées par plugin.Lookup s'inspectent sans conversion.

Sous macOS, Delve ne charge pas les informations de déboguage des greffons, bien qu'elles soient présentes (go-delve/delve#1628).

  • Il ne peut ni s'arrêter dans un greffon, ni y avancer pas à pas, ni afficher une fonction qui en provient.
  • Il passe en revanche par-dessus un appel au greffon (next), et affiche les données renvoyées par plugin.Lookup.

Compilation pour le déboguage avec GoLand

Dans la configuration par défaut, dans un projet compilé avec GoLand, l'ouverture des greffons par plugin.Open échoue avec une valeur d'erreur de la forme :

plugin was built with a different version of package <un_paquet>

Avec Go 1.27, le paquet désigné est internal/abi.

La cause tient en deux points :

  • le chargement des greffons s'assure de la compatibilité entre l'appelant et le greffon, bien au-delà du simple chargement par dlopen(3), en vérifiant les versions internes et les drapeaux de compilation des fichiers en jeu1 ;
  • GoLand ne passe pas de drapeaux spécifiques aux compilations destinées à l'exécution, mais ajoute -gcflags="all=-N -l" à celles destinées au déboguage : les greffons, compilés à l'avance, le sont sans ces drapeaux, tandis que le client débogué est compilé avec.

La solution en découle, à deux niveaux :

  • compiler les greffons en mode déboguage avec ce même drapeau :
    • dans le champ Go tool arguments des configurations d'exécution qui les construisent, ou dans tout autre mécanisme de construction, comme le Makefile de ce dépôt ;
    • plus généralement, hôte et greffons doivent partager tous leurs réglages de compilation (-gcflags, -trimpath, -race, étiquettes de construction) et les mêmes versions de dépendances ;
  • prévoir deux constructions séparées, l'une pour le déboguage, l'autre pour la production, puisque ces drapeaux désactivent les optimisations (-N) et l'inlining (-l), ce qui réduit la performance du code.

Plateformes

Le paquet fonctionne sous Linux, macOS (darwin) et FreeBSD, avec cgo. En Go 1.27, les plateformes acceptées par -buildmode=plugin sont :

  • Linux : 386, amd64, arm, arm64, loong64, ppc64, ppc64le, riscv64, s390x ;
  • Android : 386, amd64 ;
  • macOS : amd64, arm64 ;
  • FreeBSD : amd64.

La liste fait foi dans la fonction BuildModeSupported de src/internal/platform/supported.go (src/cmd/internal/sys/supported.go jusqu'à Go 1.19).

Cette prise en charge a évolué depuis l'introduction du paquet en Go 1.8 :

Version Go Situation Linux macOS FreeBSD Commit
1.8beta1 Ajout du paquet plugin X 0cbb12f
Support macOS X X b444d43
1.8beta2 Retrait du support macOS X c1ada22
1.8 Annonce: paquet "early support" X
1.9beta1 Paquet documenté comme incomplet X 3717b42
1.9rc2 Paquet documenté comme bogué X ac29f30
1.10beta2 Support macOS X X 3f5c1ad
1.12beta1 Import possible sous Windows X X 4af4dc8
1.14beta1 Support FreeBSD/amd64 X X X 88ca80b
1.16beta1 Support macOS/arm64 X X X 7d6b304
1.20rc1 Section "Warnings" de la documentation X X X ee56b3c
1.21rc1 Retrait d'android/arm et android/arm64 X X X 56a14ad
1.22rc1 Support Linux/loong64 X X X d7fcb5c
1.24rc1 Avertissement sur le détecteur de compétition X X X 1443a3e
1.25rc1 Support Linux/riscv64 X X X cdc9560
1.27rc1 Support Linux/ppc64 (gros-boutiste) X X X 364de84

Importer le paquet plugin sous Windows, possible depuis Go 1.12, ne rend pas le mécanisme de greffons utilisable : le paquet y fournit des moignons (stubs), pour éviter une erreur de compilation sans étiquette de construction spécifique à Windows.


  1. Détails dans la fonction runtime.plugin_lastmoduleinit() du fichier src/runtime/plugin.go. ↩︎