Project

General

Profile

Bug #1796

close carla patchbay plugin crashes zrythm (likely carla issue)

Added by Anonymous 16 days ago. Updated 11 days ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Plugins
Target version:
Start date:
07/22/2020
Due date:
% Done:

0%

Estimated time:

Description

Steps to reproduce

double click carla patchbay to create a track with it
close carla UI

What happens?

crash

What is expected?

no crash, make phat beats

Version

Zrythm 0.8.694-7-gdce51e0b+ (debugoptimized)
built with gcc 9.3.0
+carla
+jack

Other info

Context, distro, etc.

Backtrace

Error: Segmentation fault - Backtrace:
zrythm(backtrace_get+0xc0) [0x561f7ff7b5d0]
zrythm(+0x52c06) [0x561f7ff24c06]
/lib/x86_64-linux-gnu/libc.so.6(+0x46210) [0x7fb4177cd210]
/usr/lib/lv2/carla.lv2/carla.so(+0x9289f) [0x7fb3c5fb589f]
/usr/lib/lv2/carla.lv2/carla.so(+0xdc01a) [0x7fb3c5fff01a]
zrythm(+0xc010a) [0x561f7ff9210a]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x52a28) [0x7fb41a39fa28]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x14e) [0x7fb41a39ee8e]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x52240) [0x7fb41a39f240]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_iteration+0x33) [0x7fb41a39f2e3]
/lib/x86_64-linux-gnu/libgio-2.0.so.0(g_application_run+0x205) [0x7fb41a5b8fd5]
zrythm(main+0x7fe) [0x561f7ff24a5e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7fb4177ae0b3]
zrythm(_start+0x2e) [0x561f7ff24ace]

Log

** Message: 19:01:27.834: (expose_to_jack:864): exposing port Carla-Patchbay/TP MIDI in to JACK
** Message: 19:01:27.836: (expose_to_jack:864): exposing port Carla-Patchbay/Stereo out L to JACK
** Message: 19:01:27.837: (expose_to_jack:864): exposing port Carla-Patchbay/Stereo out R to JACK
** Message: 19:01:27.837: (expose_to_jack:864): exposing port Carla-Patchbay/TP MIDI in to JACK
** Message: 19:01:27.861: (track_verify_identifiers:658): verifying Carla-Patchbay identifiers...
** Message: 19:01:27.861: (track_verify_identifiers:725): done
** Message: 19:01:27.861: (tracklist_insert_track:244): tracklist_insert_track: done
** Message: 19:01:27.861: (channel_add_plugin:1741): Inserting Instrument Carla-Patchbay at Carla-Patchbay:0
** Message: 19:01:27.861: (port_disconnect:1372): Disconnected port "TP MIDI out" from "Events Input"
** Message: 19:01:27.861: (port_connect:1318): Connected port "TP MIDI out" to "Events Input"
** Message: 19:01:27.861: (port_disconnect:1372): Disconnected port "Audio Output 1" from "Ch Pre-Fader in L"
** Message: 19:01:27.861: (port_connect:1318): Connected port "Audio Output 1" to "Ch Pre-Fader in L"
** Message: 19:01:27.861: (port_disconnect:1372): Disconnected port "Audio Output 2" from "Ch Pre-Fader in R"
** Message: 19:01:27.861: (port_connect:1318): Connected port "Audio Output 2" to "Ch Pre-Fader in R"
** Message: 19:01:27.861: (plugin_generate_automation_tracks:1082): generating automation tracks for Carla-Patchbay...
** Message: 19:01:27.861: (track_verify_identifiers:658): verifying Carla-Patchbay identifiers...
** Message: 19:01:27.862: (track_verify_identifiers:725): done
** Message: 19:01:27.862: (router_recalc_graph:127): Recalculating...
** Message: 19:01:27.862: (plugin_update_latency:864): Carla-Patchbay latency: 0 samples
** Message: 19:01:27.862: (router_recalc_graph:143): done
** Message: 19:01:27.862: (undoable_action_do:150): [DONE]: CREATE_TRACKS
** Message: 19:01:27.862: (undo_stack_push:151): pushed to undo/redo stack
** Message: 19:01:27.882: (balance_control_finalize:420): finalizing...
** Message: 19:01:27.882: (balance_control_finalize:426): done
** Message: 19:01:27.888: (on_plugin_visibility_changed:935): start - visible: 1
** Message: 19:01:27.888: (lv2_gtk_open_ui:1394): Instantiating external UI...
** Message: 19:01:29.720: (lv2_gtk_open_ui:1505): plugin window shown, adding idle timeout. Update frequency (Hz): 60.0
** Message: 19:01:29.720: (on_plugin_window_visibility_changed:891): start
** Message: 19:01:29.720: (on_plugin_window_visibility_changed:929): done
** Message: 19:01:29.720: (on_plugin_visibility_changed:943): done
** Message: 19:01:29.798: (on_plugin_visibility_changed:935): start - visible: 1
** Message: 19:01:29.798: (on_plugin_window_visibility_changed:891): start
** Message: 19:01:29.798: (on_plugin_window_visibility_changed:929): done
** Message: 19:01:29.798: (on_plugin_visibility_changed:943): done
** Message: 19:01:33.600: (lv2_state_save_to_file:153): Lilv state saved to Carla-Patchbay_B2V0N0
** Message: 19:01:33.607: (serialize_project_thread:1352): serializing project to yaml...
** Message: 19:01:33.615: (serialize_project_thread:1357): time to serialize: 8ms
** Message: 19:01:33.615: (_project_compress:101): using zstd v1.4.4
** Message: 19:01:33.615: (_project_compress:138): compressing project...
** Message: 19:01:33.615: (_project_compress:200): Compression : 254956 bytes -> 8747 bytes
** Message: 19:01:33.615: (serialize_project_thread:1388): serialize_project_thread: saving project file...
** Message: 19:01:33.616: (serialize_project_thread:1403): serialize_project_thread: successfully saved project
** Message: 19:01:33.630: (project_idle_saved_cb:1426): Backup saved.
** Message: 19:01:40.475: (segv_handler:89): Error: Segmentation fault - Backtrace:
zrythm(backtrace_get+0xc0) [0x561f7ff7b5d0]
zrythm(+0x52c06) [0x561f7ff24c06]
/lib/x86_64-linux-gnu/libc.so.6(+0x46210) [0x7fb4177cd210]
/usr/lib/lv2/carla.lv2/carla.so(+0x9289f) [0x7fb3c5fb589f]
/usr/lib/lv2/carla.lv2/carla.so(+0xdc01a) [0x7fb3c5fff01a]
zrythm(+0xc010a) [0x561f7ff9210a]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x52a28) [0x7fb41a39fa28]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x14e) [0x7fb41a39ee8e]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x52240) [0x7fb41a39f240]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_iteration+0x33) [0x7fb41a39f2e3]
/lib/x86_64-linux-gnu/libgio-2.0.so.0(g_application_run+0x205) [0x7fb41a5b8fd5]
zrythm(main+0x7fe) [0x561f7ff24a5e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7fb4177ae0b3]
zrythm(_start+0x2e) [0x561f7ff24ace]

History

#1 Updated by Alexandros Theodotou 11 days ago

  • Subject changed from close carla patchbay plugin crashes zrythm to close carla patchbay plugin crashes zrythm (likely carla issue)
  • Category set to Plugins
  • Target version set to 1.0.0

it crashes when trying to run() on the external UI after it's closed
ui_closed is not called before that

#2 Updated by Alexandros Theodotou 11 days ago

http://robin.linuxaudio.org/tmp/jalv_extui_v1.6.4.diff

From 2658fa6ce9a038156bae53c6017c64e760a314c0 Mon Sep 17 00:00:00 2001
From: Robin Gareus <robin@gareus.org>
Date: Sun, 5 Jan 2020 21:49:40 +0100
Subject: jalv.gtk externalUI support


diff --git a/lv2_external_ui.h b/lv2_external_ui.h
new file mode 100644
index 0000000..2c9e6ee
--- /dev/null
+++ b/lv2_external_ui.h
@@ -0,0 +1,109 @@
+/*
+  LV2 External UI extension
+  This work is in public domain.
+
+  This file is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  If you have questions, contact Filipe Coelho (aka falkTX) <falktx@falktx.com>
+  or ask in #lad channel, FreeNode IRC network.
+*/
+
+/**
+   @file lv2_external_ui.h
+   C header for the LV2 External UI extension <http://kxstudio.sf.net/ns/lv2ext/external-ui>.
+*/
+
+#ifndef LV2_EXTERNAL_UI_H
+#define LV2_EXTERNAL_UI_H
+
+#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
+
+#define LV2_EXTERNAL_UI_URI     "http://kxstudio.sf.net/ns/lv2ext/external-ui"
+#define LV2_EXTERNAL_UI_PREFIX  LV2_EXTERNAL_UI_URI "#"
+
+#define LV2_EXTERNAL_UI__Host   LV2_EXTERNAL_UI_PREFIX "Host"
+#define LV2_EXTERNAL_UI__Widget LV2_EXTERNAL_UI_PREFIX "Widget"
+
+/** This extension used to be defined by a lv2plug.in URI */
+#define LV2_EXTERNAL_UI_DEPRECATED_URI "http://lv2plug.in/ns/extensions/ui#external"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * When LV2_EXTERNAL_UI__Widget UI is instantiated, the returned
+ * LV2UI_Widget handle must be cast to pointer to LV2_External_UI_Widget.
+ * UI is created in invisible state.
+ */
+typedef struct _LV2_External_UI_Widget {
+  /**
+   * Host calls this function regulary. UI library implementing the
+   * callback may do IPC or redraw the UI.
+   *
+   * @param _this_ the UI context
+   */
+  void (*run)(struct _LV2_External_UI_Widget * _this_);
+
+  /**
+   * Host calls this function to make the plugin UI visible.
+   *
+   * @param _this_ the UI context
+   */
+  void (*show)(struct _LV2_External_UI_Widget * _this_);
+
+  /**
+   * Host calls this function to make the plugin UI invisible again.
+   *
+   * @param _this_ the UI context
+   */
+  void (*hide)(struct _LV2_External_UI_Widget * _this_);
+
+} LV2_External_UI_Widget;
+
+#define LV2_EXTERNAL_UI_RUN(ptr)  (ptr)->run(ptr)
+#define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show(ptr)
+#define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide(ptr)
+
+/**
+ * On UI instantiation, host must supply LV2_EXTERNAL_UI__Host feature.
+ * LV2_Feature::data must be pointer to LV2_External_UI_Host.
+ */
+typedef struct _LV2_External_UI_Host {
+  /**
+   * Callback that plugin UI will call when UI (GUI window) is closed by user.
+   * This callback will be called during execution of LV2_External_UI_Widget::run()
+   * (i.e. not from background thread).
+   *
+   * After this callback is called, UI is defunct. Host must call LV2UI_Descriptor::cleanup().
+   * If host wants to make the UI visible again, the UI must be reinstantiated.
+   *
+   * @note When using the depreated URI LV2_EXTERNAL_UI_DEPRECATED_URI,
+   *       some hosts will not call LV2UI_Descriptor::cleanup() as they should,
+   *       and may call show() again without re-initialization.
+   *
+   * @param controller Host context associated with plugin UI, as
+   *                   supplied to LV2UI_Descriptor::instantiate().
+   */
+  void (*ui_closed)(LV2UI_Controller controller);
+
+  /**
+   * Optional (may be NULL) "user friendly" identifier which the UI
+   * may display to allow a user to easily associate this particular
+   * UI instance with the correct plugin instance as it is represented
+   * by the host (e.g. "track 1" or "channel 4").
+   *
+   * If supplied by host, the string will be referenced only during
+   * LV2UI_Descriptor::instantiate()
+   */
+  const char * plugin_human_id;
+
+} LV2_External_UI_Host;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LV2_EXTERNAL_UI_H */
diff --git a/src/jalv.c b/src/jalv.c
index adee072..82a6fee 100644
--- a/src/jalv.c
+++ b/src/jalv.c
@@ -402,6 +402,17 @@ jalv_ui_instantiate(Jalv* jalv, const char* native_ui_type, void* parent)
    const LV2_Feature idle_feature = {
        LV2_UI__idleInterface, NULL
    };
+
+#ifdef WITH_EXTERNALUI
+   const LV2_Feature external_lv_feature = {
+       LV2_EXTERNAL_UI_DEPRECATED_URI, parent
+   };
+   const LV2_Feature external_kx_feature = {
+       LV2_EXTERNAL_UI__Host, parent
+   };
+   jalv->extuiptr = NULL;
+#endif
+
    const LV2_Feature* ui_features[] = {
        &jalv->features.map_feature,
        &jalv->features.unmap_feature,
@@ -411,6 +422,10 @@ jalv_ui_instantiate(Jalv* jalv, const char* native_ui_type, void* parent)
        &parent_feature,
        &jalv->features.options_feature,
        &idle_feature,
+#ifdef WITH_EXTERNALUI
+       &external_lv_feature,
+       &external_kx_feature,
+#endif
        NULL
    };

@@ -430,6 +445,16 @@ jalv_ui_instantiate(Jalv* jalv, const char* native_ui_type, void* parent)
        binary_path,
        ui_features);

+#ifdef WITH_EXTERNALUI
+   if (jalv->externalui) {
+       if (jalv->ui_instance) {
+           jalv->extuiptr = suil_instance_get_widget((SuilInstance*)jalv->ui_instance);
+       } else {
+           jalv->externalui = false;
+       }
+   }
+#endif
+
    lilv_free(binary_path);
    lilv_free(bundle_path);
 #endif
@@ -674,6 +699,12 @@ jalv_update(Jalv* jalv)
        }
    }

+#ifdef WITH_EXTERNALUI
+   if (jalv->externalui && jalv->extuiptr) {
+       LV2_EXTERNAL_UI_RUN(jalv->extuiptr);
+   }
+#endif
+
    return 1;
 }

@@ -891,6 +922,10 @@ jalv_open(Jalv* const jalv, int* argc, char*** argv)
    jalv->nodes.rsz_minimumSize        = lilv_new_uri(world, LV2_RESIZE_PORT__minimumSize);
    jalv->nodes.work_interface         = lilv_new_uri(world, LV2_WORKER__interface);
    jalv->nodes.work_schedule          = lilv_new_uri(world, LV2_WORKER__schedule);
+#ifdef WITH_EXTERNALUI
+   jalv->nodes.ui_externallv          = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#external");
+   jalv->nodes.ui_externalkx          = lilv_new_uri(world, "http://kxstudio.sf.net/ns/lv2ext/external-ui#Widget");
+#endif
    jalv->nodes.end                    = NULL;

    /* Get plugin URI from loaded state or command line */
@@ -984,6 +1019,27 @@ jalv_open(Jalv* const jalv, int* argc, char*** argv)
        jalv->ui = lilv_uis_get(jalv->uis, lilv_uis_begin(jalv->uis));
    }

+#ifdef WITH_EXTERNALUI
+   if (!jalv->ui) {
+       LILV_FOREACH(uis, u, jalv->uis) {
+           const LilvUI* ui = lilv_uis_get(jalv->uis, u);
+           const LilvNodes* types = lilv_ui_get_classes(ui);
+           LILV_FOREACH(nodes, t, types) {
+               const char * pt = lilv_node_as_uri(lilv_nodes_get(types, t));
+               if (!strcmp(pt, "http://kxstudio.sf.net/ns/lv2ext/external-ui#Widget")) {
+                   jalv->externalui = true;
+                   jalv->ui = ui;
+                   jalv->ui_type = jalv->nodes.ui_externalkx;
+               } else if (!strcmp(pt, "http://lv2plug.in/ns/extensions/ui#external")) {
+                   jalv->externalui = true;
+                   jalv->ui_type = jalv->nodes.ui_externallv;
+                   jalv->ui = ui;
+               }
+           }
+       }
+   }
+#endif
+
    /* Create ringbuffers for UI if necessary */
    if (jalv->ui) {
        fprintf(stderr, "UI:           %s\n",
diff --git a/src/jalv_gtk.c b/src/jalv_gtk.c
index 71259bd..bc5f78c 100644
--- a/src/jalv_gtk.c
+++ b/src/jalv_gtk.c
@@ -1153,6 +1153,15 @@ jalv_discover_ui(ZIX_UNUSED Jalv* jalv)
    return TRUE;
 }

+#ifdef WITH_EXTERNALUI
+void
+on_external_ui_closed(void* controller)
+{
+   Jalv* jalv = (Jalv*) controller;
+   jalv_close_ui(jalv);
+}
+#endif
+
 float
 jalv_ui_refresh_rate(Jalv* jalv)
 {
@@ -1171,14 +1180,29 @@ jalv_ui_refresh_rate(Jalv* jalv)
 int
 jalv_open_ui(Jalv* jalv)
 {
+#ifdef WITH_EXTERNALUI
+   LV2_External_UI_Host extui;
+#endif
+
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    jalv->window = window;

+#ifdef WITH_EXTERNALUI
+   jalv->has_ui = TRUE;
+   extui.ui_closed = on_external_ui_closed;
+#endif
+
    g_signal_connect(window, "destroy",
                     G_CALLBACK(on_window_destroy), jalv);

    set_window_title(jalv);

+#ifdef WITH_EXTERNALUI
+   LilvNode* name = lilv_plugin_get_name(jalv->plugin);
+   extui.plugin_human_id = jalv_strdup(lilv_node_as_string(name));
+   lilv_node_free(name);
+#endif
+
    GtkWidget* vbox = new_box(false, 0);
    gtk_window_set_role(GTK_WINDOW(window), "plugin_ui");
    gtk_container_add(GTK_CONTAINER(window), vbox);
@@ -1194,9 +1218,19 @@ jalv_open_ui(Jalv* jalv)

    /* Attempt to instantiate custom UI if necessary */
    if (jalv->ui && !jalv->opts.generic_ui) {
+#ifdef WITH_EXTERNALUI
+       if (jalv->externalui) {
+           jalv_ui_instantiate(jalv, lilv_node_as_uri(jalv->ui_type), &extui);
+       } else
+#endif
        jalv_ui_instantiate(jalv, jalv_native_ui_type(), alignment);
    }

+#ifdef WITH_EXTERNALUI
+   if (jalv->externalui && jalv->extuiptr) {
+       LV2_EXTERNAL_UI_SHOW(jalv->extuiptr);
+   } else
+#endif
    if (jalv->ui_instance) {
        GtkWidget* widget = (GtkWidget*)suil_instance_get_widget(
            jalv->ui_instance);
@@ -1230,6 +1264,9 @@ jalv_open_ui(Jalv* jalv)

    g_timeout_add(1000 / jalv->ui_update_hz, (GSourceFunc)jalv_update, jalv);

+#ifdef WITH_EXTERNALUI
+   if (!(jalv->externalui && jalv->extuiptr))
+#endif
    gtk_window_present(GTK_WINDOW(window));

    gtk_main();
diff --git a/src/jalv_internal.h b/src/jalv_internal.h
index 4d25109..7df1487 100644
--- a/src/jalv_internal.h
+++ b/src/jalv_internal.h
@@ -14,6 +14,8 @@
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

+#define WITH_EXTERNALUI 1
+
 #ifndef JALV_INTERNAL_H
 #define JALV_INTERNAL_H

@@ -49,6 +51,10 @@
 #    include <unistd.h>
 #endif

+#ifdef WITH_EXTERNALUI
+#    include "lv2_external_ui.h"
+#endif
+
 #ifdef __clang__
 #    define REALTIME __attribute__((annotate("realtime")))
 #else
@@ -244,6 +250,10 @@ typedef struct {
    LilvNode* rsz_minimumSize;
    LilvNode* work_interface;
    LilvNode* work_schedule;
+#ifdef WITH_EXTERNALUI
+   LilvNode* ui_externallv;
+   LilvNode* ui_externalkx;
+#endif
    LilvNode* end;  ///< NULL terminator for easy freeing of entire structure
 } JalvNodes;

@@ -336,6 +346,10 @@ struct Jalv {
    bool               has_ui;         ///< True iff a control UI is present
    bool               request_update; ///< True iff a plugin update is needed
    bool               safe_restore;   ///< Plugin restore() is thread-safe
+#ifdef WITH_EXTERNALUI
+   bool                    externalui;///< True iff plugin has an external-ui
+   LV2_External_UI_Widget* extuiptr;  ///< data structure used for external-ui
+#endif
    JalvFeatures       features;
    const LV2_Feature** feature_list;
 };

Also available in: Atom PDF