cosmo0920 / windows-pr

A collection of Windows functions, constants and macros predefined for you for win32-api
23 stars 9 forks source link

Resolve SEGV on Ruby 2.4 i386-mingw32 #21

Closed cosmo0920 closed 6 years ago

cosmo0920 commented 7 years ago

ref: https://ci.appveyor.com/project/cosmo0920/windows-pr/build/25/job/6j1e8n3mol61fc3f#L33

cosmo0920 commented 7 years ago

Using Ruby 2.5trunk also causes SEGV.

cosmo0920 commented 7 years ago

Using Ruby 2.3.4 i386 does not cause SEGV.

cosmo0920 commented 7 years ago

Ruby 2.5 binaries included gem : https://rubygems.org/gems/win32-api/versions/1.7.0.pre1-universal-mingw32

cosmo0920 commented 7 years ago
require 'windows/msvcrt/directory'

class Test
  include Windows::MSVCRT::Directory

  def test
    chdir('..')
  end
end

t = Test.new
t.test
(gdb) run test/tc_segv.rb
Starting program: C:\msys64\mingw32\bin\ruby.exe test/tc_segv.rb
[New Thread 8240.0x1298]
[New Thread 8240.0x35c8]
[New Thread 8240.0x2428]
[New Thread 8240.0xe7c]
[New Thread 8240.0x1d08]
[New Thread 8240.0x283c]

Thread 1 received signal SIGSEGV, Segmentation fault.
0x66b41b25 in api_call ()
   from C:\msys64\mingw32\lib\ruby\gems\2.4.0\gems\win32-api-1.7.0.pre1-universal-mingw32\lib\win32\ruby24_32\win32\api.so
(gdb) bt
#0  0x66b41b25 in api_call ()
   from C:\msys64\mingw32\lib\ruby\gems\2.4.0\gems\win32-api-1.7.0.pre1-universal-mingw32\lib\win32\ruby24_32\win32\api.so
#1  0x030de418 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

I've got very short stack trace. This problem is originated from win32-api?

cosmo0920 commented 7 years ago

Disassemble result:

66b4521f:   85 c0                   test   eax,eax
66b45221:   75 13                   jne    66b45236 <__fu2__rb_eArgError+0xb8>
         param.params[i] = FALSE;
66b45223:   8b 45 dc                mov    eax,DWORD PTR [ebp-0x24]
66b45226:   c7 84 85 64 ff ff ff    mov    DWORD PTR [ebp+eax*4-0x9c],0x0
66b4522d:   00 00 00 00 
66b45231:   e9 1f 01 00 00          jmp    66b45355 <__fu2__rb_eArgError+0x1d7>
      else
         switch(ptr->prototype[i]){
66b45236:   8b 45 d8                mov    eax,DWORD PTR [ebp-0x28]
66b45239:   8b 55 dc                mov    edx,DWORD PTR [ebp-0x24]
66b4523c:   8b 44 90 0c             mov    eax,DWORD PTR [eax+edx*4+0xc]
66b45240:   83 f8 05                cmp    eax,0x5
66b45243:   0f 87 f5 00 00 00       ja     66b4533e <__fu2__rb_eArgError+0x1c0>
66b45249:   8b 04 85 40 94 b4 66    mov    eax,DWORD PTR [eax*4+0x66b49440]
66b45250:   ff e0                   jmp    eax
            case _T_LONG:
               param.params[i] = NUM2SIZET(v_arg);
66b45252:   8b 45 b4                mov    eax,DWORD PTR [ebp-0x4c]
66b45255:   89 04 24                mov    DWORD PTR [esp],eax
66b45258:   e8 c7 c2 ff ff          call   66b41524 <_rb_num2ulong_inline>
66b4525d:   89 c2                   mov    edx,eax
66b4525f:   8b 45 dc                mov    eax,DWORD PTR [ebp-0x24]
66b45262:   89 94 85 64 ff ff ff    mov    DWORD PTR [ebp+eax*4-0x9c],edx
               break;
66b45269:   e9 e7 00 00 00          jmp    66b45355 <__fu2__rb_eArgError+0x1d7>
            case _T_INTEGER:
               param.params[i] = NUM2INT(v_arg);
66b4526e:   8b 45 b4                mov    eax,DWORD PTR [ebp-0x4c]
66b45271:   89 04 24                mov    DWORD PTR [esp],eax
66b45274:   e8 87 c2 ff ff          call   66b41500 <_rb_num2long_inline>
66b45279:   89 c2                   mov    edx,eax
66b4527b:   8b 45 dc                mov    eax,DWORD PTR [ebp-0x24]
66b4527e:   89 94 85 64 ff ff ff    mov    DWORD PTR [ebp+eax*4-0x9c],edx
               break;
   0x66b41b0d <+365>:   repz cmps BYTE PTR ds:[esi],BYTE PTR es:[edi]
   0x66b41b0f <+367>:   jne    0x66b41b40 <api_call+416>
   0x66b41b11 <+369>:   cmp    DWORD PTR [esp+0x64],0x1
   0x66b41b16 <+374>:   jne    0x66b41b40 <api_call+416>
   0x66b41b18 <+376>:   mov    eax,DWORD PTR [esp+0x5c]
   0x66b41b1c <+380>:   call   DWORD PTR [eax+0x4]
   0x66b41b1f <+383>:   mov    ebx,eax
   0x66b41b21 <+385>:   mov    eax,DWORD PTR [esp+0x5c]
=> 0x66b41b25 <+389>:   cmp    DWORD PTR [eax+0x8],0x5
   0x66b41b29 <+393>:   ja     0x66b41d35 <api_call+917>
   0x66b41b2f <+399>:   mov    eax,DWORD PTR [eax+0x8]
   0x66b41b32 <+402>:   jmp    DWORD PTR [eax*4+0x66b491ec]
   0x66b41b39 <+409>:   lea    esi,[esi+eiz*1+0x0]
   0x66b41b40 <+416>:   mov    eax,DWORD PTR [esp+0x64]
   0x66b41b44 <+420>:   cmp    eax,0x14
   0x66b41b47 <+423>:   ja     0x66b42815 <api_call+3701>
   0x66b41b4d <+429>:   jmp    DWORD PTR [eax*4+0x66b49204]
   0x66b41b54 <+436>:   mov    eax,DWORD PTR [ebx+0x10]

Full disassemble log: win32-api-disassemble-dump.zip

komainu8 commented 7 years ago

SEGVなので、Windowsがクラッシュダンプを生成していると思うのですが、そのクラッシュダンプをWindbgなどで解析すればもう少し、情報があるかもしれません。 クラッシュダンプをいただければ、解析してみます。お役に立てるかはわかりませんが。。。

nurse commented 7 years ago

引数はポインタのはずなのになんで case _T_LONG: を処理しているところでこけている…というかそんなところを処理しているのか謎です。思うに誰かがポインタをlongで受け取っているのではないでしょうか。 とりあえずwindows-prやwindows-prへの依存を外し、win32-apiだけで書き直したらその過程で何か分かるかもしれません。