Skip to content

プロセスの起動に失敗の対応 - #2548

Merged
berryzplus merged 2 commits into
sakura-editor:masterfrom
hpmy-dev:feature/process
Jul 23, 2026
Merged

プロセスの起動に失敗の対応#2548
berryzplus merged 2 commits into
sakura-editor:masterfrom
hpmy-dev:feature/process

Conversation

@hpmy-dev

Copy link
Copy Markdown
Contributor

新しいウィンドウを開くと「プロセスの起動に失敗しました」が表示される不具合を修正

PR 対象

アプリ(サクラエディタ本体)

カテゴリ

不具合修正

関連 issue / PR

PR の背景

タブバーを表示し「ウィンドウをまとめて表示」を有効にしている環境で、既存のエディタから「新しいウィンドウを開く」を実行すると、新しいウィンドウ自体は開くにもかかわらず、操作から約15秒後に「プロセスの起動に失敗しました。」のエラーダイアログが表示される。

  • 症状は Release ビルドで特に発現しやすい
  • 親側の WaitForMultipleObjects の戻り値は 258(WAIT_TIMEOUT)
  • 子プロセスは正常終了コード(exit code 0)で動作しており、実際には失敗していない

本症状は #2545 にて報告されている。当初 CControlTray::OpenNewEditorCREATE_SUSPENDED 順序不整合が原因と推測したが、PR #2546 で修正された内容を適用しても症状が再発することを確認。
以下、実測に基づく原因解析と修正内容です。

原因

CEditWnd::_AdjustInMonitor(sakura_core/window/CEditWnd.cpp)内で、他プロセスのウィンドウに対して同期版 ShowWindow を呼び出している箇所が真の原因である。

デッドロックのメカニズム

  1. 親エディタは CControlTray::OpenNewEditor 内で子プロセスを起動後、WaitForMultipleObjects(hEvent, hProcess, 15000) に入る。この時点で親の UI スレッドはメッセージポンプを停止して待機している
  2. 子は初期化を進め、CEditWnd::_AdjustInMonitor にて sTabGroupInfo.hwndTop(= タブグループの現在の先頭ウィンドウ = 親エディタのウィンドウ)に対し ::ShowWindow(hwndTop, SW_HIDE) を発行する
  3. 対象が異なるスレッド/プロセスのウィンドウの場合、ShowWindow は内部で cross-thread SendMessage(WM_SHOWWINDOW) として処理され、受信側スレッドが WndProc から return するまで送信元を無期限ブロックする
  4. 親スレッドはポンプ停止中のためメッセージを取り出せず、子は永久待機。子は初期化完了イベントをシグナルできない
  5. 15秒経過後に親の WaitForMultipleObjects がタイムアウト(戻り値 258)し、「プロセスの起動に失敗しました。」を表示。親がポンプ再開後、子の ShowWindow がようやく戻り、子は残りの初期化を完走してウィンドウが可視化される

これで観測されているすべての現象(操作の約15秒後にエラー・ウィンドウは開く・子は exit 0・タブまとめ設定時のみ発生・タイミング依存)が矛盾なく説明できる。

診断根拠

  • 子プロセスのミニダンプ2つを4秒間隔で取得し、全スレッドが完全に同一状態であることから真の stuck 状態を確認
  • Visual Studio でメインスレッドの呼び出し履歴を復元:wWinMain → CProcess::Run → CNormalProcess::InitializeProcess → CEditApp::Create → CEditWnd::Create → CEditWnd::_AdjustInMonitor → win32u syscall
  • Process Explorer のカーネル側スタックにも xxxSendNotifyMessage / xxxWindowEvent / Wow64KiUserCallbackDispatcher が並び、cross-thread メッセージ配信待ちであることと整合
  • 該当行を ShowWindowAsync へ置換したビルドで症状が再発しないことを確認

修正内容

::ShowWindow::ShowWindowAsync へ変更する。ShowWindowAsync は内部的に PostMessage(WM_SHOWWINDOW) 相当の実装で、受信側の応答を待たずに即座にリターンする。これにより送信元(子)は同期待機しなくなり、デッドロックが解消。

変更対象ファイル

  • sakura_core/window/CEditWnd.cppCEditWnd::_AdjustInMonitor

仕様・動作説明

修正前後の動作比較

# 段階 修正前(ShowWindow) 修正後(ShowWindowAsync)
1 親エディタの状態 WaitForMultipleObjects(15秒) でメッセージポンプ停止 変化なし
2 子から親ウィンドウへの操作 ::ShowWindow(hwndTop, SW_HIDE) ::ShowWindowAsync(hwndTop, SW_HIDE)
3 カーネル内部処理 cross-thread SendMessage(WM_SHOWWINDOW)。親の WndProc 応答まで送信元を無期限ブロック PostMessage(WM_SHOWWINDOW)。親のキューに積むだけで即座にリターン
4 子の初期化継続 上記の同期待機で子ブロック。初期化完了イベントをシグナルできない ブロックせず継続。InitializeProcess のスコープ終了時に初期化完了イベントをシグナル
5 親の待機解除 15秒経過で戻り値 258(WAIT_TIMEOUT)。エラーダイアログ表示 イベント発火で戻り値 0(WAIT_OBJECT_0)。正常復帰

ユーザーから見える結果

項目 修正前 修正後
エラーダイアログ 操作から約15秒後に表示 表示されない
新しいウィンドウの表示 15秒後のエラー表示前後に可視化 通常速度で可視化
旧先頭ウィンドウの非表示タイミング 15秒後 数〜数十ms 遅延で発生(視覚的差はほぼ認識不可)
「消えるアニメーション抑止」の意図 達成(が15秒のフリーズと引き換え) ほぼ達成(順序が数十ms 前後する可能性あり)

PR の影響範囲

  • 変更は CEditWnd::_AdjustInMonitor 内の1行のみ
  • 実行経路としては、共通設定「タブバーを表示する」ON かつ「ウィンドウを分離して表示」しない(まとめて表示)かつ sTabGroupInfo.hwndTop が有効、の条件下でのみ通る箇所。それ以外の起動経路(初回起動・タブ分離設定・タブバー非表示設定)には影響しない
  • 副作用は「旧先頭ウィンドウが非表示になるタイミングが送信直後から親のポンプ再開後へずれる可能性」のみ。既存コメントで意図されている「消えるアニメーションの抑止」は事実上維持される

テスト内容

以下を修正ビルドで確認済み。

  • タブバー表示 + まとめて表示の設定下で「新しいウィンドウを開く」を複数回実行し、エラーダイアログが表示されないことを確認
  • 子プロセスが正常にウィンドウを表示することを確認
  • タブバー非表示・タブ分離設定でも従来どおり新規ウィンドウが開くことを確認(該当経路自体を通らないため回帰なし)

@berryzplus berryzplus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

対応ありがとうございます。

@github-actions

Copy link
Copy Markdown

Test Results

1 185 tests  ±0   1 185 ✅ ±0   3m 8s ⏱️ -26s
  107 suites ±0       0 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit f88abc8. ± Comparison against base commit aa2e9b2.

@sonarqubecloud

Copy link
Copy Markdown

@berryzplus

Copy link
Copy Markdown
Contributor

MinGWでビルドエラー出てますが、無関係なのでマージしてしまいます。

image

@berryzplus
berryzplus merged commit 3d4f76d into sakura-editor:master Jul 23, 2026
15 of 19 checks passed
@hpmy-dev
hpmy-dev deleted the feature/process branch July 23, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants