レジストリで設定する。Debugger_*は例なので、Debuggerキーに変える。
sprintfっぽい文法です。
で設定。
で設定。V2系列では、OllyDebugの設定から行える。
いくつかの理由(ntdll内RaiseExceptionとか)により、トラップ時にはまず使い物にならない。 MinGWビルドでなおかつgdbではじめから走らせる場合はそうでもないようだが。
foobar2000など、例外時にログとミニダンプを残すものがある。それらも含めて簡単に見てみる。
Windows標準でついてきますし、意外に使えます。
わかっているので、先に述べておくと、原因は、classをインライン化したためにメンバ関数の オフセット/スタックがalignment不定となっておきるようになったSSE movapsのalignmentエラーによるもので、 MinGW 4.1以降で採用された__attribute__((force_align_arg_pointer))をclass宣言時に使用するようにして解決しました。
にどんどん追加される設定だと探すのがちょっと面倒かもしれません。フォールト ->という部分を 探せば原因がわかります。
*----> スレッド Id 0xa00 の状態のダンプ <----* eax=00000000 ebx=012eba80 ecx=000001e0 edx=00000000 esi=012ebb08 edi=012ebaa4 eip=66a6c233 esp=0289fb1c ebp=0289fb94 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 *** ERROR: Symbol file could not be found. Defaulted to export symbols for \ C:\Program Files\YAMAHA\Vstplugins\Wind\Freeverb3VST_Impulser2.dll - ファンクション: Freeverb3VST_Impulser2 66a6c20c 90 nop 66a6c20d 90 nop 66a6c20e 90 nop 66a6c20f 90 nop 66a6c210 0f57c0 xorps xmm0,xmm0 66a6c213 c783bc00000000000000 mov dword ptr [ebx+0xbc],0x0 66a6c21d 0f2e83b4000000 ucomiss xmm0,dword ptr [ebx+0xb4] 66a6c224 f30f100d689dbd66 movssx xmm1,dword ptr [Freeverb3VST_Impulser2+0x399d68 (66bd9d68)] 66a6c22c 727b jb Freeverb3VST_Impulser2+0x22c2a9 (66a6c2a9) 66a6c22e f30f1155b8 movssx dword ptr [ebp-0x48],xmm2 フォールト ->66a6c233 0f295dc8 movaps oword ptr [ebp-0x38],xmm3 \ ss:0023:0289fb5c=7c8024b77c94da2a0000000300000180 66a6c237 f30f1165a8 movssx dword ptr [ebp-0x58],xmm4 66a6c23c f30f110424 movssx dword ptr [esp],xmm0 66a6c241 e8ca710000 call Freeverb3VST_Impulser2+0x233410 (66a73410) 66a6c246 d95da4 fstp dword ptr [ebp-0x5c] 66a6c249 f30f106da4 movssx xmm5,dword ptr [ebp-0x5c] 66a6c24e f30f1083c0000000 movssx xmm0,dword ptr [ebx+0xc0] 66a6c256 f30f108bc4000000 movssx xmm1,dword ptr [ebx+0xc4] 66a6c25e 0f28f5 movaps xmm6,xmm5 66a6c261 f30f5ef0 divss xmm6,xmm0 66a6c265 f30f59c8 mulss xmm1,xmm0 ≪以降はobjdump -Sで得られる内容で、静的なコードなら↑と同じはずです。≫ ≪c++filtを通すと、C++ demangleできます。≫ 66a6c20f: 90 nop 66a6c210: 0f 57 c0 xorps %xmm0,%xmm0 66a6c213: c7 83 bc 00 00 00 00 movl $0x0,0xbc(%ebx) 66a6c21a: 00 00 00 66a6c21d: 0f 2e 83 b4 00 00 00 ucomiss 0xb4(%ebx),%xmm0 66a6c224: f3 0f 10 0d 68 9d bd movss 0x66bd9d68,%xmm1 66a6c22b: 66 66a6c22c: 72 7b jb 66a6c2a9 \ <__ZN3fv312limitmodel_f14processreplaceEPfS1_S1_S1_l+0x449> 66a6c22e: f3 0f 11 55 b8 movss %xmm2,-0x48(%ebp) 66a6c233: 0f 29 5d c8 movaps %xmm3,-0x38(%ebp) 66a6c237: f3 0f 11 65 a8 movss %xmm4,-0x58(%ebp) 66a6c23c: f3 0f 11 04 24 movss %xmm0,(%esp) 66a6c241: e8 ca 71 00 00 call 66a73410 <_logf> 66a6c246: d9 5d a4 fstps -0x5c(%ebp) 66a6c249: f3 0f 10 6d a4 movss -0x5c(%ebp),%xmm5 66a6c24e: f3 0f 10 83 c0 00 00 movss 0xc0(%ebx),%xmm0 66a6c255: 00 66a6c256: f3 0f 10 8b c4 00 00 movss 0xc4(%ebx),%xmm1 66a6c25d: 00 66a6c25e: 0f 28 f5 movaps %xmm5,%xmm6 66a6c261: f3 0f 5e f0 divss %xmm0,%xmm6 66a6c265: f3 0f 59 c8 mulss %xmm0,%xmm1 66a6c269: f3 0f 10 83 c8 00 00 movss 0xc8(%ebx),%xmm0 66a6c270: 00 66a6c271: f3 0f 58 c6 addss %xmm6,%xmm0 66a6c275: f3 0f 5e c8 divss %xmm0,%xmm1 66a6c279: f3 0f 10 83 cc 00 00 movss 0xcc(%ebx),%xmm0 66a6c280: 00 66a6c281: f3 0f 5c c1 subss %xmm1,%xmm0 66a6c285: f3 0f 5c c5 subss %xmm5,%xmm0 66a6c289: f3 0f 11 04 24 movss %xmm0,(%esp) 66a6c28e: e8 ad 71 00 00 call 66a73440 <_expf> 66a6c293: f3 0f 10 65 a8 movss -0x58(%ebp),%xmm4 66a6c298: f3 0f 10 55 b8 movss -0x48(%ebp),%xmm2 66a6c29d: 0f 28 5d c8 movaps -0x38(%ebp),%xmm3 66a6c2a1: d9 5d a4 fstps -0x5c(%ebp) 66a6c2a4: f3 0f 10 4d a4 movss -0x5c(%ebp),%xmm1 66a6c2a9: 0f 2e e1 ucomiss %xmm1,%xmm4 66a6c2ac: 0f 86 ae 02 00 00 jbe 66a6c560 \ <__ZN3fv312limitmodel_f14processreplaceEPfS1_S1_S1_l+0x700> 66a6c2b2: f3 0f 11 8b 14 01 00 movss %xmm1,0x114(%ebx)
ebp=0289fb94で、movaps %xmm3,-0x38(%ebp)だと、アクセス先である289EB5Cはalignment不整合なので、 Segmentation Faultになります。movupsだとOKなんですがね。
foobar2000\crash reportsにlog(Log)とdmp(User Mini Dump)が残る。
結論から言うと、明示的に認められるまで解放してはいけないクラスを 不定の状態にしたままVST構造体内に保持していた上に、ポインタへのポインタを 書くべきところをただのポインタと間違って書いていたために、突然のアクセスによって Segmentation Faultとなったものです。ちょっとわかりにくいです。ログの大事なところは下の通りです。
Illegal operation: Code: C0000005h, flags: 00000000h, address: 77BF60B4h Access violation, operation: write, address: 6687C2DDh Registers: EAX: 6687C2DD, EBX: 6687C240, ECX: 66B8AA1B, EDX: 00395E20 ESI: 00000002, EDI: 6687C2DD, EBP: 02E2F6B0, ESP: 02E2F690 Crash location: Module: msvcrt Offset: 360B4h Symbol: "strcat" (+74h) Stack dump analysis: Address: 668449A3h (Freeverb3VST_Impulser2+49A3h) Address: 6687C2DDh (Freeverb3VST_Impulser2+3C2DDh) Address: 66B8AA1Ah (Freeverb3VST_Impulser2+34AA1Ah)
残念ながら、MinGWシンボルはWindows非互換なので、objdump -Sなりで見つかる関数のアドレス をソースと対応させる作業が必要になります。Visual C++だとそんな必要はないです。 foobar2000はダンプファイル(*.dmp)も残してくれるので、使ってみましょう。WinDBGで読み込めます。 Disassemblyでコードを見られます。msvcrt内で起きたので、MSVCRTのバグかと 誤認するかもしれませんが、そうではありません。
77bf60a5 f7c103000000 test ecx,3 77bf60ab 7419 je msvcrt!strcat+0x86 (77bf60c6) 77bf60ad 8a11 mov dl,byte ptr [ecx] 77bf60af 41 inc ecx 77bf60b0 84d2 test dl,dl 77bf60b2 7464 je msvcrt!strcat+0xd8 (77bf6118) 77bf60b4 8817 mov byte ptr [edi],dl 77bf60b6 47 inc edi 77bf60b7 f7c103000000 test ecx,3 77bf60bd 75ee jne msvcrt!strcat+0x6d (77bf60ad) 77bf60bf eb05 jmp msvcrt!strcat+0x86 (77bf60c6) 77bf60c1 8917 mov dword ptr [edi],edx 77bf60c3 83c704 add edi,4 77bf60c6 bafffefe7e mov edx,7EFEFEFFh 77bf60cb 8b01 mov eax,dword ptr [ecx] 77bf60cd 03d0 add edx,eax
77bf60b4でediに書き込むのですが、その書き込み先は6687C2DDで、 関数のオフセットで、あからさまにおかしいですね。&(アドレス演算子)を足して解決しました。 関数の型チェックは重要です。
結論から言うと、上の方でのべたSSE alignmentエラーと同じです。重要なところはWinDBGを含めて以下の通りです。
Illegal operation: Code: C0000005h, flags: 00000000h, address: 64B6AEF8h Access violation, operation: read, address: FFFFFFFFh Registers: EAX: 00000001, EBX: 040503B0, ECX: 0012F390, EDX: 7C94E514 ESI: 040503EC, EDI: 040503B0, EBP: 0012F490, ESP: 0012F408 Crash location: Module: Freeverb3VST_WindCompressor Offset: 22AEF8h Loaded modules: (中略) Freeverb3VST_WindCompressor loaded at 64940000h - 64E22000h Stack dump analysis: Address: 6497B681h (Freeverb3VST_WindCompressor+3B681h) Address: 77EDED69h (GDI32+ED69h), symbol: "CreateFontIndirectA" (+46h)
WinDBG Disassembly 64940000+22AEF8 (=OffsetとDllのロードアドレスで計算) 64b6aebe e88d88e0ff call Freeverb3VST_WindCompressor+0x33750 (64973750) 64b6aec3 8b83ac000000 mov eax,dword ptr [ebx+0ACh] 64b6aec9 8b550c mov edx,dword ptr [ebp+0Ch] 64b6aecc 89442404 mov dword ptr [esp+4],eax 64b6aed0 891424 mov dword ptr [esp],edx 64b6aed3 e8a887e0ff call Freeverb3VST_WindCompressor+0x33680 (64973680) 64b6aed8 0f57c0 xorps xmm0,xmm0 64b6aedb c745c000000000 mov dword ptr [ebp-40h],0 64b6aee2 c745cc00000000 mov dword ptr [ebp-34h],0 64b6aee9 8db42600000000 lea esi,[esi] 64b6aef0 f30f100d4828c764 movss xmm1,dword ptr [Freeverb3VST_WindCompressor+0x332848 (64c72848)] ここ≫64b6aef8 0f2945a8 movaps xmmword ptr [ebp-58h],xmm0 64b6aefc f30f594dcc mulss xmm1,dword ptr [ebp-34h] 64b6af01 f30f5c0d3c28c764 subss xmm1,dword ptr [Freeverb3VST_WindCompressor+0x33283c (64c7283c)] 64b6af09 f30f110c24 movss dword ptr [esp],xmm1 64b6af0e f30f114d98 movss dword ptr [ebp-68h],xmm1 64b6af13 e858f3ddff call Freeverb3VST_WindCompressor+0xa270 (6494a270) 64b6af18 f30f104d98 movss xmm1,dword ptr [ebp-68h] 64b6af1d f30f110c24 movss dword ptr [esp],xmm1 64b6af22 d95dd0 fstp dword ptr [ebp-30h] 64b6af25 e846f3ddff call Freeverb3VST_WindCompressor+0xa270 (6494a270) 64b6af2a 0f2845a8 movaps xmm0,xmmword ptr [ebp-58h] 64b6af2e d95d94 fstp dword ptr [ebp-6Ch] 64b6af31 f30f105594 movss xmm2,dword ptr [ebp-6Ch] 64b6af36 0f28ca movaps xmm1,xmm2 64b6af39 0f540d5028c764 andps xmm1,xmmword ptr [Freeverb3VST_WindCompressor+0x332850 (64c72850)] 64b6af40 0f2f0d6028c764 comiss xmm1,dword ptr [Freeverb3VST_WindCompressor+0x332860 (64c72860)]
計算すると、alignmentがあいませんね。これも先ほど同じ解法で解決しました。
エラーの箇所がわかっても、その原因の場所が異なっていたりして、気付くまでは結構骨がおれるものです。 Windowsバイナリは特別の理由がないかぎりVC++でビルドしたほうがよいですね。MinGWを使っていると、 例外をDLL外に出してはいけなくなったり、DLL間ではExceptionはやりとりできなくなったり(正確には、 共有ライブラリを利用すればできないことはないけれど、ユーザにインストールさせるのが面倒だとか)だとか、 重箱の隅的な内容が増えてしまいます。
OllyDbg Q&A (Digital Travesia)
Digital Travesia 〜 でじたる とらべしあ 〜 推薦図書/パッケージソフト一覧
速習講座: クラッシュを分析してアプリケーションにおけるセキュリティの脆弱性を検出する
Question: if a website crashes in the middle of the night and there are no support people to roll in the crash cart, will anyone hear it play C:\WINNT\Media\Windows 2003 Critical Stop.wav to call the nurse, or does it wait till morning for the doctors' rounds? -- Ira Abramov -- Linux-IL Message: "Re: Bank Leumi site finalls works from Linux" ( http://www.mail-archive.com/linux-il@cs.huji.ac.il/msg54167.html ) Q: Are we not men? A: We are Vaxen.