I've been having an issue with segmentation faults when accessing a class variable (an array of Qt::Actions), and I've been trying to whittle it down to a minimal code example that replicates the issue:
#!/usr/bin/ruby
require 'Qt4'
require 'rufus/scheduler'
app = Qt::Application.new(ARGV)
class ManagerWidget < Qt::Widget
    signals 'changed(int)'
    def initialize
        super(nil)
        max_index = 2
        next_index = 0
        scheduler = Rufus::Scheduler.start_new
        scheduler.every '10s' do
            emit changed(next_index)
            if next_index < max_index - 1
                next_index += 1
            else
                next_index = 0
            end
        end
    end
end
class Tray < Qt::Widget
    def initialize
        super(nil)
        tray = Qt::SystemTrayIcon.new
        manager_widget = ManagerWidget.new
        menu = Qt::Menu.new
        tray_icon = Qt::Icon.new("./icons/Gnome-Preferences-Desktop-Wallpaper-64.png")
        actions = []
        manager_widget.connect(SIGNAL('changed(int)')) do |i|
            puts "changed #{i}"
            actions[i].text = '...' if actions && actions[i]
        end
        2.times do |i|
            sub_menu = Qt::Menu.new("#{i + 1}")
            actions[i] = sub_menu.add_action('x')
            menu.add_menu(sub_menu)
        end
        tray.icon = tray_icon
        tray.context_menu = menu
        tray.show
    end
end
Tray.new
app.exec
The above code outputs:
"sni-qt/12147" WARN  14:35:48.326 void StatusNotifierItemFactory::connectToSnw() Invalid interface to SNW_SERVICE 
changed 0
changed 1
changed 0
changed 1
changed 0
changed 1
changed 0
changed 1
./min-code-example.rb:42: [BUG] Segmentation fault
ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]
[... snipped due to character limits on posting ...]
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
Aborted (core dumped)
Failed (134)
It seems to be necessary to use the sub-menus to trigger this issue - at least adding the actions to the tray menu itself runs for quite a while with no issue (I left it for more than 10 times as long as it took to get the error with the above code).
Ruby version: ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]
Qt version: 4.8.1
Bindings version: qtbindings (4.8.3.0)
Linux version: Ubuntu 12.04
Another odd behaviour is that the output from the puts call is sometimes displayed in the console immediately, other times it only prints once I mouse over the tray icon.
I'm not even sure where to start when it comes to tracking this down, so any input you have is much appreciated.
Update: I've left this for a while since I couldn't get any further. I've tried to start over with this but I'm still coming across the same problem. I've delved a little deeper in to the problem and since it said 'missing_method' I started by printing the class to make sure I was definitely looking at a Qt::Action (I am), and then which methods are available according to actions[0].methods.
.methods output:
[:setShortcut, :shortcut=, :qobject_cast, :inspect, :pretty_print, :className,
:class_name, :inherits, :findChildren, :find_children, :findChild, :find_child,
:connect, :method_missing, :const_missing, :dispose, :isDisposed, :disposed?,
:qVariantValue, :qVariantFromValue, :**, :+, :~, :-@, :-, :*, :/, :%, :>>,
:<<, :&, :^, :|, :<, :<=, :>, :>=, :==, :is_a?, :kind_of?, :methods,
:protected_methods, :public_methods, :singleton_methods, :qDebug, :qFatal,
:qWarning, :SIGNAL, :SLOT, :emit, :QT_TR_NOOP, :QT_TRANSLATE_NOOP, :nil?, :===,
:=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup,
:initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, :untrust,
:untrusted?, :trust, :freeze, :frozen?, :to_s, :private_methods,
:instance_variables, :instance_variable_get, :instance_variable_set,
:instance_variable_defined?, :instance_of?, :tap, :send, :public_send,
:respond_to?, :respond_to_missing?, :extend, :display, :method, :public_method,
:define_singleton_method, :object_id, :to_enum, :enum_for, :equal?, :!, :!=,
:instance_eval, :instance_exec, :__send__, :__id__, "blockSignals", "children",
"connect", "deleteLater", "disconnect", "dumpObjectInfo", "dumpObjectTree",
"dynamicPropertyNames", "event", "eventFilter", "inherits", "installEventFilter",
"widgetType?", "killTimer", "metaObject", "moveToThread", "objectName", "parent",
"property", "qt_metacall", "qt_metacast", "removeEventFilter", "objectName=",
"parent=", "setProperty", "setUserData", "signalsBlocked", "startTimer",
"thread", "userData", "actionGroup", "activate", "associatedGraphicsWidgets",
"associatedWidgets", "autoRepeat", "data", "font", "hover", "icon", "iconText",
"checkable?", "checked?", "enabled?", "iconVisibleInMenu?", "separator?",
"visible?", "menu", "menuRole", "parentWidget", "priority", "actionGroup=",
"autoRepeat=", "checkable=", "checked=", "data=", "disabled=", "enabled=",
"font=", "icon=", "iconText=", "iconVisibleInMenu=", "menu=", "menuRole=",
"priority=", "separator=", "shortcut=", "shortcutContext=", "shortcuts=",
"softKeyRole=", "statusTip=", "text=", "toolTip=", "visible=", "whatsThis=",
"shortcut", "shortcutContext", "shortcuts", "showStatusText", "softKeyRole",
"statusTip", "text", "toggle", "toolTip", "trigger", "whatsThis"]
In this case I was trying to do actions[0].enabled = true when the segmentation fault occurred, which is in the output as far as I understand it (6th line from the bottom, enabled=). I also tried setEnabled(true), set_enabled(true) and just about anything I could think of.
Even calling inspect on the action object is causing a segmentation fault, though doing this inside the loop that initially places the actions in the array is fine. I really don't get where this is going wrong.
Edit: In response to the suggestion to use QTimer instead I've attempted this and I'm still getting the same problem. The code is currently a fair bit more complicated than what is listed above, so I'll write some quick pseudo-code here to illustrate the flow:
def init_tray
    actions = []
    2.times do |i|
        actions[i] = ... # init and add to systray, store reference in array
    end
    update = Proc.new do |i|
        actions[i].setText('...') # update the text on one of the actions defined above
    end
    listener = ... # create a listener that can be called by Manager on certain events - will call the update Proc among other things.
    manager = Manager.new(..., listener)
end
The call to Manager.new initialises that object and at the end calls the listener with a state change, this in turn calls the update Proc, which accesses the actions array. This should all be in the same thread at this stage, none of these lines depend on QT apart from the actual creation of the Qt::Action. I've removed the Rufus scheduling and replaced it with QTimer, but it simply isn't getting far enough for that to be the issue.