Edited at

libstdc++-6.dll の競合

More than 1 year has passed since last update.

libstdc++-6.dllはMinGWのC++ランタイムライブラリです。

MinGWのg++でコンパイルされたプログラムは動作時にこのDLLを必要とします。

Windowsに移植されたLinux/Unix向けのソフトウェアにはしばしばこのDLLが含まれています。

複数のlibstdc++-6.dllがパスにあると問題が生じることがあります。


MSYS2

MSYS2のmingw-w64-x86_64-gccで次のコードをコンパイルします。

#include <string>

#include <iostream>

int main(){
std::string s;
s = "Hello World!";
std::cout << s << '\n';
}

実行ファイルとしてa.exeが吐き出されます。

これをMinGW-w64 Win64 Shellから実行すると、特に何の問題もなく実行されます。

しかし、それ以外の環境から実行すると問題が起きます。

MSYS2 Shell:出力のないまま終了

MinGW-w64 Win32 Shell:出力のないまま終了

コマンドプロンプト:以下のエラーで終了

<string>を使わなければ問題は起きないようなので、<string>を含むDLLに問題があるようです。


原因を調べる

objdump -pを使うと頭の方にThe Import Tablesというのがあって、どのDLLからどの関数等を使っているかが書いてあります。

The Import Tables (interpreted .idata section contents)

vma: Hint Time Forward DLL First
Table Stamp Chain Name Thunk
00008000 00008064 00000000 00000000 00008a08 0000828c

DLL Name: libgcc_s_seh-1.dll
vma: Hint/Ord Member-Name Bound-To
84b4 14 _Unwind_Resume

00008014 00008074 00000000 00000000 00008a48 0000829c

DLL Name: libstdc++-6.dll
vma: Hint/Ord Member-Name Bound-To
84c8 3850 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev
8504 3870 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev
8540 3873 _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEaSEPKc
8580 4421 _ZNSt8ios_base4InitC1Ev
859c 4423 _ZNSt8ios_base4InitD1Ev
85b8 4708 _ZSt4cout
85c4 4771 _ZSt9terminatev
85d8 4820 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c
8610 4828 _ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE
8678 5792 __cxa_begin_catch
868c 5828 __gxx_personality_seh0

00008028 000080d4 00000000 00000000 00008abc 000082fc

DLL Name: KERNEL32.dll
vma: Hint/Ord Member-Name Bound-To
86a8 216 DeleteCriticalSection
86c0 249 EnterCriticalSection
86d8 462 GetCurrentProcess
86ec 463 GetCurrentProcessId
8702 467 GetCurrentThreadId
8718 529 GetLastError
8728 549 GetModuleHandleA
873c 599 GetProcAddress
874e 628 GetStartupInfoA
8760 651 GetSystemTimeAsFileTime
877a 678 GetTickCount
878a 762 InitializeCriticalSection
87a6 844 LeaveCriticalSection
87be 958 QueryPerformanceCounter
87d8 1029 RtlAddFunctionTable
87ee 1030 RtlCaptureContext
8802 1037 RtlLookupFunctionEntry
881c 1044 RtlVirtualUnwind
8830 1187 SetUnhandledExceptionFilter
884e 1200 Sleep
8856 1214 TerminateProcess
886a 1221 TlsGetValue
8878 1234 UnhandledExceptionFilter
8894 1264 VirtualProtect
88a6 1266 VirtualQuery

0000803c 000081a4 00000000 00000000 00008b3c 000083cc

DLL Name: msvcrt.dll
vma: Hint/Ord Member-Name Bound-To
88b6 55 __C_specific_handler
88ce 78 __dllonexit
88dc 81 __getmainargs
88ec 82 __initenv
88f8 83 __iob_func
8906 90 __lconv_init
8916 96 __set_app_type
8928 98 __setusermatherr
893c 115 _acmdln
8946 122 _amsg_exit
8954 140 _cexit
895e 251 _fmode
8968 330 _initterm
8974 439 _lock
897c 611 _onexit
8986 819 _unlock
8990 1030 abort
8998 1047 calloc
89a2 1060 exit
89aa 1079 fprintf
89b4 1086 free
89bc 1097 fwrite
89c6 1145 malloc
89d0 1153 memcpy
89da 1183 signal
89e4 1204 strlen
89ee 1207 strncmp
89f8 1239 vfprintf

どうやらlibstdc++-6.dllに問題があってエラーが出たようです。


gnuplotが悪い(!?)

うちの環境にはWindows用のgnuplotが入っていました。

このソフトのフォルダにもlibstdc++-6.dllが入っていたのでした。

そして、MinGW-w64 Win64 Shell以外の環境ではgnuplotのフォルダの方をmsys2のフォルダより先に読みに行くので、こっちを読みに行った結果、うまく動かなかったようでした。


結論

Windows環境ではDLLの競合に注意