diff options
| author | Jeff Carr <[email protected]> | 2025-08-17 13:37:55 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-08-17 22:55:02 -0500 |
| commit | 6c099ef51399cfc81a25434e92f60a8d809503cd (patch) | |
| tree | cb247368aeb9832970fd2e46dd4a0f540a4ca5f4 | |
| parent | e2783ce0699b0867209a8a024e7aa1f3d187b76f (diff) | |
work around GO plugin load failures not being cleaned up
| -rw-r--r-- | argv.go | 15 | ||||
| -rw-r--r-- | init.go | 8 | ||||
| -rw-r--r-- | plugin.go | 5 | ||||
| -rw-r--r-- | pluginCheck.go | 62 |
4 files changed, 56 insertions, 34 deletions
@@ -11,12 +11,11 @@ This struct can be used with the go-arg package. These are the generic default command line arguments for the 'GUI' package */ type ArgsGui struct { - NoGui bool `arg:"--no-gui" help:"ignore all these gui problems"` - GuiPlugin string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui,stdin]"` - GuiFile string `arg:"--gui-file" help:"Use a specific plugin.so file"` - GuiTest string `arg:"--gui-test" help:"test a specific plugin.so will load"` - GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"` - GuiCheck string `arg:"--gui-check-plugin" help:"used to check if the plugin loads"` + NoGui bool `arg:"--no-gui" help:"ignore all these gui problems"` + GuiPlugin string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui,stdin]"` + GuiFile string `arg:"--gui-file" help:"Use a specific plugin.so file"` + GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"` + GuiPluginHack string `arg:"--gui-check-plugin" help:"hack to verify GO plugins load"` } /* @@ -34,9 +33,9 @@ func ArgToolkit() string { func InitArg() { arg.Register(&argGui) - if argGui.GuiCheck != "" { + if argGui.GuiPluginHack != "" { // does os.Exec() and does not return - TestPluginAndExit() + testPluginAndExit() } } @@ -280,9 +280,9 @@ func New() *Node { // trapStdout() } */ - if argGui.GuiTest != "" { + if argGui.GuiPluginHack != "" { // does os.Exec() and does not return - TestPluginAndExit() + testPluginAndExit() } initNew() @@ -297,9 +297,9 @@ func NoGui() bool { func (n *Node) Default() *Node { var err error // used to check if plugins load or not - if argGui.GuiCheck != "" { + if argGui.GuiPluginHack != "" { // does os.Exec() and does not return - TestPluginAndExit() + testPluginAndExit() os.Exit(0) } @@ -8,7 +8,6 @@ package gui import ( "embed" "errors" - "fmt" "os" "path/filepath" "plugin" @@ -248,8 +247,8 @@ func initToolkit(name string, filename string) *aplug { plug, err := plugin.Open(filename) */ - if err := CheckPluginViaSubprocess(filename); err != nil { - fmt.Printf("initToolkit() subprocess load plugin failed: %v\n", err) + if err := checkPluginViaSubprocess(filename); err != nil { + log.Printf("initToolkit() subprocess load plugin failed: %v\n", err) return nil } diff --git a/pluginCheck.go b/pluginCheck.go index b7657f6..8e50ade 100644 --- a/pluginCheck.go +++ b/pluginCheck.go @@ -3,7 +3,6 @@ package gui import ( "debug/buildinfo" "errors" - "fmt" "os" "os/exec" "path/filepath" @@ -13,9 +12,11 @@ import ( "go.wit.com/log" ) -// CheckPluginCompatibility verifies that the plugin .so file was built +// this doesn't work with GO111MODULE=off so it's mostly worthless +// TODO: fix the GO binary so this works +// verifies that the plugin .so file was built // with the same Go version and dependency versions as the host binary. -func CheckPluginCompatibility(pluginPath string) error { +func checkPluginCompatibility(pluginPath string) error { pluginInfo, err := buildinfo.ReadFile(pluginPath) if err != nil { return log.Errorf("failed to read plugin build info: %w", err) @@ -55,66 +56,89 @@ func CheckPluginCompatibility(pluginPath string) error { log.Printf("DEP HASH: version %s: plugin=%s, host=%s\n", dep.Path, dep.Version, hostVer) } + log.Info("CHECK FINAL OK:", pluginPath) return nil } // tests the plugin file will load func testPluginOld() { - _, err := plugin.Open(argGui.GuiTest) + _, err := plugin.Open(argGui.GuiPluginHack) if err != nil { - log.Log(PLUG, "plugin.Open() FAILED =", argGui.GuiTest, err) + log.Log(PLUG, "plugin.Open() FAILED =", argGui.GuiPluginHack, err) os.Exit(-1) } - log.Log(PLUG, "plugin.Open() SUCCESS loading plugin =", argGui.GuiTest) + log.Log(PLUG, "plugin.Open() SUCCESS loading plugin =", argGui.GuiPluginHack) os.Exit(0) } +func CheckPlugin() string { + if argGui.GuiPluginHack != "" { + // does os.Exec() and does not return + testPluginAndExit() + } + return "boo" +} + // loads the plugin, then exits with 0 or -1 -func TestPluginAndExit() { - log.Log(WARN, "TEST plugin START", argGui.GuiCheck) +func testPluginAndExit() { + log.Log(WARN, "TEST plugin START", argGui.GuiPluginHack) - absPath, err := filepath.Abs(argGui.GuiCheck) + absPath, err := filepath.Abs(argGui.GuiPluginHack) if err != nil { - log.Log(WARN, "TEST plugin FAILED", argGui.GuiCheck, absPath, err) + log.Log(WARN, "TEST plugin FAILED", argGui.GuiPluginHack, absPath, err) os.Exit(-1) } - log.Log(WARN, "TEST plugin START abs:", absPath, argGui.GuiCheck) + log.Log(WARN, "TEST plugin START abs:", absPath, argGui.GuiPluginHack) plug, err := checkPlug(absPath) if plug == nil { - log.Log(WARN, "TEST plugin failed (returned nil):", argGui.GuiCheck, absPath, err) + log.Log(WARN, "TEST plugin failed (returned nil):", argGui.GuiPluginHack, absPath, err) + log.Sleep(1) os.Exit(-1) } if err == nil { - log.Log(WARN, "TEST plugin probably worked", argGui.GuiCheck, absPath) + log.Log(WARN, "TEST plugin probably worked", argGui.GuiPluginHack, absPath) + log.Log(WARN, "os.Exit(0)") os.Exit(0) } - log.Log(WARN, "TEST plugin failed", argGui.GuiCheck, absPath, err) + log.Log(WARN, "TEST plugin failed", argGui.GuiPluginHack, absPath, err) + log.Sleep(1) os.Exit(-1) } -func CheckPluginViaSubprocess(path string) error { +func checkPluginViaSubprocess(path string) error { exe, err := os.Executable() if err != nil { - return fmt.Errorf("failed to get executable path: %w", err) + return log.Errorf("failed to get executable path: %w", err) } resolved, err := filepath.EvalSymlinks(exe) if err != nil { - return fmt.Errorf("failed to resolve executable symlink: %w", err) + return log.Errorf("failed to resolve executable symlink: %w", err) } - cmd := exec.Command(resolved, "--gui-check-plugin", path) + argv := []string{resolved, "--gui-check-plugin", path, "--no-port"} + log.Warn("RUNNING:", argv) + // cmd := exec.Command(resolved, "--gui-check-plugin", path, "--no-port") + cmd := exec.Command(argv[0], argv[1:]...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() } +// retuns true if +func IsGoPluginTestHack() bool { + if argGui.GuiPluginHack == "" { + return false + } + return true +} + func checkPlug(pluginPath string) (*plugin.Plugin, error) { // const pluginPath = "/tmp/gocui.so" // ../../../toolkits/gocui/gocui.so // /usr/lib/go-gui-toolkits/gocui.v0.22.46.so - if err := CheckPluginCompatibility(pluginPath); err != nil { + if err := checkPluginCompatibility(pluginPath); err != nil { log.Printf("Plugin check failed: %v\n", err) return nil, err } |
