Hi,
after running in circles I finally found the real issue of my crashes.
It's based on FXTreeList.
## Crash
~~~
F:\Projects\TMP\fxruby_bugs>treelist_dialog.rb
Dialog Canceled
F:/Projects/TMP/fxruby_bugs/treelist_dialog.rb: [BUG] Segmentation fault
ruby 1.9.3p448 (2013-06-27) [i386-mingw32]
-- Control frame information -----------------------------------------------
c:0001 p:0000 s:0002 b:0002 l:00051c d:00051c TOP
-- C level backtrace information -------------------------------------------
C:\Windows\SysWOW64\ntdll.dll(ZwWaitForSingleObject+0x15) [0x77d6f8d1]
C:\Windows\syswow64\kernel32.dll(WaitForSingleObjectEx+0x43) [0x76561194]
C:\Windows\syswow64\kernel32.dll(WaitForSingleObject+0x12) [0x76561148]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_vm_bugreport+0xf9) [0x62e5bec5]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_name_err_mesg_new+0x17a) [0x62d3a87a]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_bug+0x2f) [0x62d3b557]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_check_safe_str+0x194) [0x62dee898]
[0x004011e6]
C:\Program Files\ThinkPad\Bluetooth
Software\SysWOW64\BtMmHook.dll(SetAndWaitBtM
mHook+0xfac9) [0x10013989]
C:\Windows\SysWOW64\ntdll.dll(RtlKnownExceptionFilter+0xb7) [0x77dc74ff]
~~~
## Analysis
The crash happens only when
* `myelements=` is called
* `appendItem` is called with a FXTreeItem object -> [2]
* a minimum of '4' num_root_nodes are used -> [3]
## Script
~~~
require 'fox16'
include Fox
class CheckBoxTreeList < FXTreeList
def myelements=(x)
clearItems
begin
x.each do |e|
node = nil
levels = e[:name].split('|')
levels.each_with_index do |l,i|
item = findItem(l, node, SEARCH_FORWARD|SEARCH_IGNORECASE)
if item.nil? then
new_item = FXTreeItem.new( l )
# [1]
# crash occurs when appendItem is called with a FXTreeItem
object
item = appendItem(node, new_item)
# [2]
# no crash when simple appendItem is used
#item = appendItem(node, i.to_s)
end
node = item
end
end
rescue => bang
puts bang
puts bang.backtrace
end
end
def initialize(parent)
@parent = parent
super(parent, :opts =>
LAYOUT_FILL_X|LAYOUT_FILL_Y|TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES|TREELIST_ROOT_BOXES)#|TREELIST_MULTIPLESELECT)
end
end
class TestGui < FXMainWindow
class TreeDlg < FXDialogBox
include Responder
def initialize(parent, project=nil, prefs={} )
super(parent, "CheckBox Dialog", DECOR_ALL, :width => 300, :height
=> 400)
frame = FXVerticalFrame.new(self, :opts =>
LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE)
elements = []
# [3]
num_root_nodes = 10
max_child_nodes = 2
num_root_nodes.times do |ri|
max_child_nodes.times do |si|
name = "root#{ri}|sub#{si}"
data = name + "-data"
e = { :name => name, :enabled => false, :data => data }
elements << e
end
end
@cbtree = CheckBoxTreeList.new(frame)
# [4]
@cbtree.myelements = elements
@cancel_btn = FXButton.new(frame, "Cancel" , :target => self,
:selector => FXDialogBox::ID_CANCEL, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
@accept_btn = FXButton.new(frame, "Accept" ,
:target => self, :selector => FXDialogBox::ID_ACCEPT,
:opts => BUTTON_NORMAL|LAYOUT_RIGHT)
end
def onAccept(sender, sel, event)
getApp().stopModal(self, 1)
self.hide()
1
end
end
def initialize(app)
super(app, "Test Application", :width => 800, :height => 600)
frame = FXVerticalFrame.new(self,
LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE)
FXButton.new(frame, "Open TreeDialog",:opts =>
FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT).connect(SEL_COMMAND){
dlg = TreeDlg.new(self)
if dlg.execute != 0 then
puts "* Dialog Finished"
else
puts "Dialog Canceled"
end
}
FXButton.new(frame, "Exit",:opts =>
FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT).connect(SEL_COMMAND){
leave }
end
def create
super # Create the windows
show(PLACEMENT_SCREEN) # Make the main window appear
end
def leave
getApp().exit(0)
end
end
application = FXApp.new('LayoutTester', 'FoxTest')
TestGui.new(application)
application.create
application.run
~~~
I appreciate any help,
Andy