Wine上のMery Ver 3.6.1 (64 ビット版) ポータブルが起動時にクラッシュする
-
Kuroさん、はじめまして。さがわと申します。趣味でWineの開発をしています。
仮想マシン上で動かしているUbuntu 22.04(64ビット版)でWine 8.18を用いてMery Ver 3.6.1 (64 ビット版) ポータブルを起動すると、「予期しないエラーが発生しました。詳細については、クラッシュレポートを参照してください。(以下省略)」というダイアログボックス(※)が表示され、そのダイアログで「OK」ボタンを押しても、Meryのメインウィンドウが表示されません。
※このダイアログはMS UI Gothicがないと文字化けしますが本題ではないので委細省略しますこの状態でWineタスクマネージャーでプロセス一覧を確認するとMery.exeのプロセスが引き続き存在するようです(ゾンビ?)。
Wine環境はサポート外となるとは思いますが、可能であればクラッシュしないよう対応をご検討いただけないでしょうか。Wineは https://wiki.winehq.org/Ubuntu の手順で入れたバイナリパッケージ(winehq-devel)を利用しています。また、起動の際は端末でポータブル版のZIPファイルを展開したディレクトリにカレントディレクトリを変更し、シェルに「wine Mery.exe &」と入力して、起動しています。上述の通り、エラーメッセージ表示後にMery.exeのプロセスが残るので、「wineserver -k」コマンドでWineの関連プロセスを一掃してから、再度Mery.exeを起動すると同様の事象が再現することを確認しています。
Meryのマクロやプラグインは利用していません。Errorディレクトリに出力されたクラッシュレポートをEnd of Stackまで引用すると以下の通りです。
---
*** Mery Crash Report ***
Message: モジュール 'Mery.exe' のアドレス 000000000047A0B3 でアドレス FFFFFFFFFF2AAF80 に対する書き込み違反がおきました。
ExceptionCode: 0x00000003 (EAccessViolation)
ExceptionFlags: 0x00000000
Version: 3.6.1 (x64)
ModulePath: C:\works\Mery\Mery.exe
DiskSpace: 5912 MB, PhysicalMemory: 1947 MB, PageFile: 2459 MB, MemoryLoad: 30%
DirectWrite: False, DarkMode: False
12th Gen Intel(R) Core(TM) i7-1260P
OSVersion: Windows 10 (Version 10.0, Build 18362, 64-bit Edition)
=== Stack ===
000000000047A0B3
000000000043ADD7
000000000043B64A
000000000040B169
00006FFFFFCB86D3
00006FFFFFCB8E17
00006FFFFFCB66AE
000000000047A0B3
000000000048A305
000000000078C422
000000000079287B
00000000005E07A5
00000000005E019E
000000000040A020
00000000005E0060
00000000005EF9F1
0000000000888194
00006FFFFFACA029
00006FFFFFCBEDF0
0000000000887460
000000007FFD0000
=== End of Stack ===
---
Wine開発の経験があるので、こちらでデバッグするのもやぶさかではありませんが、禁止事項に抵触する恐れがあるので、許諾がない状態でこれ以上調べるのは控えておきます。
なお、32ビット版で同様の事象は発生していません。以上よろしくお願いします。
| さがわ | 返信 -
はじめまして、Mery を開発している Kuro と申します。
ご報告いただき、ありがとうございます。
いただいた条件で現象を確認しました。おそらく、Mery の開発環境である Delphi の不具合が原因と考えられます(Wine はサポート外のため、厳密には不具合とは言えませんが…)。
具体的には、Delphi のフレームワーク内で INI ファイルを扱うライブラリに問題があるようで、INI ファイルからバイナリデータを読み込む処理で例外が発生していました。
Mery.ini を削除するか、Mery.ini 内の次の項目を削除すると、起動できるようになるかもしれません。
[Markers] Marker=00000000 ← これがバイナリデータです。
ただし、この項目は Mery の終了時に Mery.ini に書き込まれるため、再び起動しなくなってしまいます。
開発環境の内部の処理なので、対応できるかどうかは分かりませんが、対策について調査してみたいと思います。
また、上記の手順で起動させたとしても、[オプション] ダイアログを開こうとするとクラッシュしてしまいました。
さらに、[オプション] ダイアログを強制的に表示してみたところ、今度は [DirectWriteを有効にする] をクリックするとクラッシュが発生しました。
DirectWrite については、Wine のログに、「D3D10 interface emulation not fully implemented yet!」などのメッセージが表示されていたため、Wine 側の問題かもしれません。
おそらく、他にもさまざまな問題があると思われます。
Linux のデバッグ環境がないため、積極的な対応はできませんが、「こうやったら Wine でも動くよ」といった情報は大歓迎です。
というわけで、起動時のクラッシュと [オプション] ダイアログでのクラッシュについては調査してみますが、基本的に Wine への対応についてはサポート外とさせていただいてますので、ご了承ください。
| Kuro | 返信 -
Ubuntu上のWine環境を用意し、再現を確認していただいて、ありがとうございます。
手元ではMery.iniを消した状態でMery.exeを起動するとメインウィンドウが表示されることを確認しました。また、その状態で [オプション] のダイアログを開こうとするとクラッシュする事象について、こちらでも確認できました。
後者のクラッシュについては、エディットコントロールにEM_GETRECTメッセージをSendMessageW APIで送るところ(000000000062A3E7)で、lParamに指定したRECT型のポインタが不正となった結果、Wineのcomctl32内でアクセス違反が発生しているようです。これはWineの非互換といえるのかもしれませんが、Wine 8.18現在の実装ではMery.exeのローカル変数が保存されるスタック領域のアドレスが00007ffffe1fcce0のように32ビットでは現せない値になっています。このスタック領域のアドレス値を32ビットの符号付き整数で表現して、64ビット値に戻すとMessageに出てくるfffffffffe1fd5f0のような値になります。32ビット版Meryでは発生せず、...e1f...のあたりが似ているので、Mery.exe内部で上述のような計算をしていないか気になるところです。よって、Delphiでアドレスを計算している処理を見直すとWineで動くようにできるかもしれません。
さらに、Windows 10 22H2(64ビット)上でも以下のセキュリティ設定で高エントロピASLRを強制することで同様の現象(起動時のクラッシュと [オプション] ダイアログでのクラッシュ)が発生することを確認しました。このような設定をWindowsで行う例はまれと思われますが、Windowsでも発生させる手順を示すことで調査がしやすくなると思い、お知らせしておきます。
1. デスクトップ画面左下のWindowsロゴを右クリックして、「設定」を選択する
2. 「更新とセキュリティ」を選択する
3. Windowsセキュリティから「アプリとブラウザーの制御」を選択する
4. Exploit protectionの項目にある「Exploit Protection の設定」を選択する
5. 「プログラム設定」タブを選択する
6. プログラムを追加してカスタマイズの左にある「+」を選択する
7. 「プログラムの名前で追加」を選択し、表示されたウィンドウの入力欄に「Mery.exe」と入力し、「追加」ボタンを選択する
8. リスト中ほどにある「仮想メモリの割り当てをランダム化する(ボトムアップASLR)」の項目で、「システム設定の上書き」の左にあるチェックボックスを選択し、「オン」を選ぶ。(「高エントロピを使用しない」はチェックしない。)
9. 「適用」ボタンを選択し、UACダイアログに応答する。
10. Mery.exeを起動する。DirectWriteの不具合についてはWineの問題と思われるので、ご放念ください。
よろしくお願いいたします。
| さがわ | 返信 -
情報ありがとうございます。
> Delphiでアドレスを計算している処理を見直すとWineで動くようにできるかもしれません。
ご指摘のとおり、Delphi の内部で SendMessageW の戻り値や引数が、本来ポインター幅 (32 ビットまたは 64 ビット) で受け取るべき部分が、Longint 型 (Delphi の型で 32 ビット固定) になっている箇所が見つかりました。
これらをポインター幅に合った適切な型に修正することで、クラッシュが解消しました。
このような問題は他にも存在し、たとえば、Mery で複数のタブを開いた状態でタブをドラッグしようとすると、同様のクラッシュが発生しました。
これも先述の理由によるもので、修正可能なようです。
ちなみに、Mery の開発環境は Delphi XE2 ですが、これは Delphi が 64 ビットアプリの開発に対応した最初のバージョンであり、まだ 64 ビット化が不完全な部分があるのかもしれません。
> Windowsでも発生させる手順を示すことで調査がしやすくなると思い、お知らせしておきます。
情報ありがとうございます。いただいた手順で Windows でも現象を確認できました。
Delphi のフレームワークを完全に精査することは難しいため、Mery 側でできる対応としては、問題が発見された際に都度対処していくかたちになると思います。
また、私自身も普段使っている Windows で同じ設定をし、日常的に利用している Mery において、他に問題が発生する箇所がないか様子を見てみますね。
| Kuro | 返信 -
こんばんは。この度はご対応いただきありがとうございます。
フレームワークの改修によりいくつかのクラッシュを解消したと聞き安堵しています。当初Mery固有の問題と思い対応をお願いしたところでしたが、Dephiフレームワークの問題を都度対処する性質のもので、Kuroさんにご負担をおかけすることになり恐縮です。
他にもDelphiフレームワークが原因で64ビットのWine(や高エントロピASLRを有効にした環境)で動かないソフトがありそうなので、情報を集めてみようと思います。
| さがわ | 返信 -
こんばんは。ご返信ありがとうございます。
いえいえ、こちらこそ、貴重な情報をありがとうございました。
Wine に限らず、Windows でも高エントロピ オプションを有効にすると問題が発生するようですので、Mery としても対策が必要だと考えています。
高エントロピ オプションに関する問題ではありませんが、以前に Exploit Protection に関する報告があり、その際には [任意のコード ガード (ACG)] がオンになっていると Mery が起動しないという問題がありました。(現在でも起動しないようですが…)
当時、調査したところ、Mery に限らず、Delphi 製のアプリは同様の問題があるようでした。
このあたりは知識がないもので、また機会がありましたら情報をいただけると助かります。
それでは、ご不便をおかけしますが、次のバージョンのリリースまで、今しばらくお待ちくださいませ。
| Kuro | 返信 -
返信遅くなりましたが、Wine 8.19とポータブル版のMery (x64) Version 3.6.2の組み合わせで起動およびオプションダイアログの表示を確認しました。
対応ありがとうございました。| さがわ | 返信 -
ご確認ありがとうございます。
うまく動作しているようで、安心しました。
その後、私のほうでも日常的に高エントロピ オプションを有効にして使用していますが、現在のところ問題は発生していないようです。
また、何かお気づきの点などがありましたら、ご連絡いただけると助かります。
| Kuro | 返信