I've spent the last couple days trying to figure out if I'm doing anything wrong, and I've checked over my code a dozen times, but cannot figure out what's causing this issue.
Here is a shortened version of the code which is guaranteed to generate the seg fault. I apologize for the size, but these structs are required to make a call to waveOutOpen:
require 'ffi'
class HWAVEOUT < FFI::Struct
layout :i, :int
end
class WAVEFORMATEX < FFI::Struct
def initialize
self[:wFormatTag] = 1
self[:nChannels] = 1
self[:nSamplesPerSec] = 44100
self[:wBitsPerSample] = 16
self[:cbSize] = 0
self[:nBlockAlign] = (self[:wBitsPerSample] >> 3) * self[:nChannels]
self[:nAvgBytesPerSec] = self[:nBlockAlign] * self[:nSamplesPerSec]
end
layout(
:wFormatTag, :ushort,
:nChannels, :ushort,
:nSamplesPerSec, :ulong,
:nAvgBytesPerSec, :ulong,
:nBlockAlign, :ushort,
:wBitsPerSample, :ushort,
:cbSize, :ushort
)
end
class WAVEHDR < FFI::Struct
layout(
:lpData, :pointer,
:dwBufferLength, :ulong,
:dwBytesRecorded, :ulong,
:dwUser, :ulong,
:dwFlags, :ulong,
:dwLoops, :ulong,
:lpNext, :pointer,
:reserved, :ulong
)
end
class Sound
extend FFI::Library
ffi_lib :winmm
callback :waveOutProc, [:pointer, :uint, :ulong, :ulong, :ulong], :void
attach_function :waveOutOpenCallback, :waveOutOpen, [:pointer, :uint, :pointer, :waveOutProc, :ulong, :ulong], :uint
attach_function :waveOutOpenNull, :waveOutOpen, [:pointer, :uint, :pointer, :ulong, :ulong, :ulong], :uint
WaveOutProc = Proc.new do |hwo, mMsg, dwCallback, dwParam1, dwParam2|
puts mMsg
return
end
end
hWaveOut = HWAVEOUT.new
wfx = WAVEFORMATEX.new
puts "waveOutOpen returns 0 (no error) if I don't use the callback form"
puts Sound.waveOutOpenNull(hWaveOut.pointer, -1, wfx.pointer,0,0,0)
puts "but if I use a callback, the moment it returns from the callback, there is a seg fault"
puts "note that the code inside the callback runs, as I am puts-ing the mMsg which is 955"
puts "for WOM_OPEN which tells us the device was opened."
puts "this is on ruby 1.9.3p484 (2013-11-22) [i386-mingw32] running 1.9.3 x86-mingw32 on"
puts "Windows 7"
puts Sound.waveOutOpenCallback(hWaveOut.pointer, -1, wfx.pointer,Sound::WaveOutProc,0,0x30000)
If you'd like it, here is the output of this code to my console:
waveOutOpen returns 0 (no error) if I don't use the callback form
0
but if I use a callback, the moment it returns from the callback, there is a seg fault
note that the code inside the callback runs, as I am puts-ing the mMsg which is 955
for WOM_OPEN which tells us the device was opened.
this is on ruby 1.9.3p484 (2013-11-22) [i386-mingw32] running 1.9.3 x86-mingw32 on
Windows 7
955
sound.rb:67: [BUG] Segmentation fault
ruby 1.9.3p484 (2013-11-22) [i386-mingw32]
-- Control frame information -----------------------------------------------
c:0004 p:---- s:0018 b:0018 l:000017 d:000017 CFUNC :waveOutOpenCallback
c:0003 p:0282 s:0009 b:0008 l:001144 d:0023d4 EVAL sound.rb:67
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:001144 d:001144 TOP
-- Ruby level backtrace information ----------------------------------------
sound.rb:67:in `<main>'
sound.rb:67:in `waveOutOpenCallback'
-- C level backtrace information -------------------------------------------
C:\Windows\SysWOW64\ntdll.dll(ZwWaitForSingleObject+0x15) [0x7721f8d1]
C:\Windows\syswow64\kernel32.dll(WaitForSingleObjectEx+0x43) [0x754f1194]
C:\Windows\syswow64\kernel32.dll(WaitForSingleObject+0x12) [0x754f1148]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_vm_bugreport+0xf9) [0x62e5cf51]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_name_err_mesg_new+0x17a) [0x62d3a862]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_bug+0x2f) [0x62d3b53f]
C:\Ruby193\bin\msvcrt-ruby191.dll(rb_check_safe_str+0x194) [0x62def0bc]
[0x004011e6]
C:\Windows\syswow64\kernel32.dll(GetProfileStringW+0x12d67) [0x75530303]
C:\Windows\SysWOW64\ntdll.dll(RtlKnownExceptionFilter+0xb7) [0x772774ff]
-- Other runtime information -----------------------------------------------
* Loaded script: sound.rb
* Loaded features:
0 enumerator.so
1 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/encdb.so
2 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/iso_8859_1.so
3 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/trans/transdb.so
4 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/rbconfig.rb
5 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/compatibility.rb
6 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/defaults.rb
7 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/deprecate.rb
8 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/errors.rb
9 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/version.rb
10 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/requirement.rb
11 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/platform.rb
12 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/basic_specification.rb
13 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/stub_specification.rb
14 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/util/stringio.rb
15 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/specification.rb
16 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/exceptions.rb
17 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/defaults/operating_system.rb
18 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_gem.rb
19 C:/Ruby193/lib/ruby/1.9.1/thread.rb
20 C:/Ruby193/lib/ruby/1.9.1/monitor.rb
21 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb
22 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems.rb
23 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/path_support.rb
24 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/utf_16le.so
25 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/trans/utf_16_32.so
26 C:/Ruby193/lib/ruby/1.9.1/i386-mingw32/enc/trans/single_byte.so
27 C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb
28 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/1.9/ffi_c.so
29 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/platform.rb
30 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/types.rb
31 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/library.rb
32 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/errno.rb
33 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/pointer.rb
34 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/memorypointer.rb
35 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/struct_layout_builder.rb
36 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/struct.rb
37 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/union.rb
38 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/managedstruct.rb
39 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/callback.rb
40 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/io.rb
41 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/autopointer.rb
42 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/variadic.rb
43 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/enum.rb
44 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/version.rb
45 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi/ffi.rb
46 C:/Ruby193/lib/ruby/gems/1.9.1/gems/ffi-1.9.3-x86-mingw32/lib/ffi.rb
[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
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Further evidence that this isn't my fault is that another library using the midiout functions results in the same segmentation fault behavior when using the midioutproc callback.
Any help or insight would be appreciated. If it helps, here are a couple links to the documentation for these functions:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd743869%28v=vs.85%29.aspxhttp://msdn.microsoft.com/en-us/library/windows/desktop/dd743866%28v=vs.85%29.aspxThanks,
- Dominic