[Fix] DCS 2.9.27.24969 dedicated server crashes immediately on Wine (Linux) — msvcp140_atomic_wait.dll stub crash
Environment
- DCS World Server
2.9.27.24969(2026-06 時点の最新) - Linux 上で Wine + Docker (
aterfax/dcs-world-dedicated-server) を使用して起動 - 影響範囲: Wine ベースの Linux DCS サーバ全般 (DCSSB Option C / Linux-native 含む)
- 影響 Wine バージョン: wine-8.0 (Debian bookworm デフォルト)、wine-11.0 upstream も初期は未修正
Symptom
DCS 専用サーバ (DCS_server.exe) がログ出力なしに起動直後クラッシュ。Wine が以下を報告:
EXCEPTION_WINE_STUB: 0x80000100
WINEDEBUG=err+module を設定すると:
err:module:import_dll Library MSVCP140_ATOMIC_WAIT.dll (which is needed by DCS_server.exe) not found
err:module:loader_init Importing dlls for DCS_server.exe failed, status c0000135
サーバは dcs.log を書かず、Listening on port XXXXX にも到達しない。
Root Cause
DCS 2.9.27.24969 で msvcp140.dll の依存関係が更新され、msvcp140_atomic_wait.dll から
__std_tzdb_get_sys_info と __std_tzdb_delete_sys_info を 静的インポート するようになった。
これらは C++ STL の chrono タイムスタンプ書式化で使用するタイムゾーン DB クエリ関数。
wine-8.0 および wine-11.0 の msvcp140_atomic_wait.dll はこれらのエクスポートが @ stub のみで、
DCS が DLL ロード時に呼び出そうとすると EXCEPTION_WINE_STUB (0x80000100) が発生してアボートする。
関連する Microsoft STL ABI (_Sys_info 構造体):
struct tzdb_sys_info {
int32_t error; // offset 0 (0=success)
// 4 bytes padding
double begin; // offset 8 — range start (epoch ms)
double end; // offset 16 — range end (epoch ms)
int32_t offset; // offset 24 — UTC offset in ms
int32_t save; // offset 28 — DST offset in ms
char *abbrev; // offset 32 — timezone abbreviation
}; // total: 40 bytes (_CRT_PACKING=8)
Fix
wine-11.0 ソースから、問題の 2 関数を最小限実装したパッチ済み msvcp140_atomic_wait.dll をビルドして置き換える。
1. spec ファイルの編集 (dlls/msvcp140_atomic_wait/msvcp140_atomic_wait.spec)
2 つの stub エントリを実エクスポートに変更:
@ stdcall __std_tzdb_get_sys_info(ptr long double)
@ stdcall __std_tzdb_delete_sys_info(ptr)
また __std_atomic_*_indirect / __std_atomic_*_cmpxchg16b の @ stub エントリがあれば合わせて削除 (別のクラッシュ源)。
2. main.c に実装を追加
struct tzdb_sys_info {
enum tzdb_error error;
double begin;
double end;
int32_t offset;
int32_t save;
char *abbrev;
};
struct tzdb_sys_info * __stdcall __std_tzdb_get_sys_info(const char *name, size_t len, double sys)
{
struct tzdb_sys_info *info = calloc(1, sizeof(*info));
if (!info) return NULL;
info->error = TZDB_ERROR_SUCCESS;
info->begin = -1e15;
info->end = 1e15;
info->offset = 0;
info->save = 0;
info->abbrev = malloc(4);
if (info->abbrev) {
info->abbrev[0] = 'U';
info->abbrev[1] = 'T';
info->abbrev[2] = 'C';
info->abbrev[3] = 0;
}
return info;
}
void __stdcall __std_tzdb_delete_sys_info(struct tzdb_sys_info *info)
{
if (!info) return;
free(info->abbrev);
free(info);
}
3. ビルドとインストール
# Debian bookworm コンテナ内 (winehq-stable インストール済み):
apt-get source winehq-stable # または wine-11.0 ソースを tarball で取得
# 上記の編集を適用後:
./configure --without-x --without-freetype --enable-win64
cd dlls/msvcp140_atomic_wait && make
# インストール
cp .libs/msvcp140_atomic_wait.dll /opt/wine-stable/lib/wine/x86_64-windows/
cp .libs/msvcp140_atomic_wait.dll.so /opt/wine-stable/lib/wine/x86_64-unix/
4. Wine prefix の修正 (wine-8.0 から移行した場合)
wine-8.0 で初期化した prefix があるときは追加で 2 点の対処が必要:
# a) system32 内の旧 128KB native PE stub を wine-11.0 の 2KB fake PE stub に置換
cp /opt/wine-stable/lib/wine/x86_64-windows/msvcp140_atomic_wait.dll \
"$WINEPREFIX/drive_c/windows/system32/msvcp140_atomic_wait.dll"
# b) user.reg を修正 — wine-8.0 は DLL を "native" 登録しておりロードが壊れる
sed -i 's/"[*]msvcp140_atomic_wait"="native"/"*msvcp140_atomic_wait"="builtin"/' \
"$WINEPREFIX/user.reg"
Known Side Effect
DCS ログのタイムスタンプが UTC 固定になる (実装は常に UTC offset=0 を返す)。表示上のみの問題でゲームプレイへの影響なし。
Tested on
- DCS
2.9.27.24969、wine-stable11.0.0.0~bookworm-1 - Linux、Docker、DCSSB Option C (Linux-native bot が Wine DCS を管理)
- 3 サーバインスタンス全て
simulation started, state=ssRunningに到達することを確認