Clangのバグと戦うために173210氏に助けを求めた話
事の発端
https://github.com/yumetodo/string_split
C++で文字列をsplitするライブラリを作っていたが、7月11日
$ clang++ sample.cpp -v -o sample.out -O2 -Wall -Wextra -std=c++11
clang version 3.8.0 (tags/RELEASE_380/final)
Target: i686-w64-windows-gnu
Thread model: posix
InstalledDir: D:\msys64\mingw32\bin
"D:\\msys64\\mingw32\\bin\\clang++.exe" -cc1 -triple i686-w64-windows-gnu -emit-obj -disable-free -disable-llvm-verifier -main-file-name sample.cpp -mrelocation-model static -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -target-cpu pentium4 -momit-leaf-frame-pointer -v -dwarf-column-info -debugger-tuning=gdb -resource-dir "D:\\msys64\\mingw32\\bin\\..\\lib\\clang\\3.8.0" -internal-isystem "D:\\msys64\\mingw32\\i686-w64-mingw32\\include\\c++" -internal-isystem "D:\\msys64\\mingw32\\i686-w64-mingw32\\include\\c++\\i686-w64-mingw32" -internal-isystem "D:\\msys64\\mingw32\\i686-w64-mingw32\\include\\c++\\backward" -internal-isystem "D:\\msys64\\mingw32\\i686-w64-mingw32\\include\\c++\\5.4.0" -internal-isystem "D:\\msys64\\mingw32\\i686-w64-mingw32\\include\\c++\\5.4.0\\i686-w64-mingw32" -internal-isystem "D:\\msys64\\mingw32\\i686-w64-mingw32\\include\\c++\\5.4.0\\backward" -internal-isystem "D:\\msys64\\mingw32\\include\\c++\\5.4.0" -internal-isystem "D:\\msys64\\mingw32\\include\\c++\\5.4.0\\i686-w64-mingw32" -internal-isystem "D:\\msys64\\mingw32\\include\\c++\\5.4.0\\backward" -internal-isystem "D:\\msys64\\mingw32\\lib\\gcc\\i686-w64-mingw32\\5.4.0\\include\\c++" -internal-isystem "D:\\msys64\\mingw32\\lib\\gcc\\i686-w64-mingw32\\5.4.0\\include\\c++\\i686-w64-mingw32" -internal-isystem "D:\\msys64\\mingw32\\lib\\gcc\\i686-w64-mingw32\\5.4.0\\include\\c++\\backward" -internal-isystem "D:\\msys64\\mingw32\\bin\\..\\lib\\clang\\3.8.0\\include" -internal-isystem "D:\\msys64\\mingw32\\lib\\gcc\\i686-w64-mingw32\\5.4.0\\include" -internal-isystem "D:\\msys64\\mingw32\\i686-w64-mingw32/sys-root/mingw/include" -internal-isystem "D:\\msys64\\mingw32\\lib\\gcc\\i686-w64-mingw32\\5.4.0\\include-fixed" -internal-isystem "D:\\msys64\\mingw32\\i686-w64-mingw32\\include" -internal-isystem "D:\\msys64\\mingw32\\include" -O2 -Wall -Wextra -std=c++11 -fdeprecated-macro -fdebug-compilation-dir "D:\\user\\documents\\git\\string_split\\sample" -ferror-limit 19 -fmessage-length 203 -fno-use-cxa-atexit -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -vectorize-loops -vectorize-slp -o "D:\\msys64\\tmp\\sample-6463c7.o" -x c++ sample.cpp
clang -cc1 version 3.8.0 based upon LLVM 3.8.0 default target i686-w64-windows-gnu
ignoring nonexistent directory "D:\msys64\mingw32\i686-w64-mingw32\include\c++"
ignoring nonexistent directory "D:\msys64\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32"
ignoring nonexistent directory "D:\msys64\mingw32\i686-w64-mingw32\include\c++\backward"
ignoring nonexistent directory "D:\msys64\mingw32\i686-w64-mingw32\include\c++\5.4.0"
ignoring nonexistent directory "D:\msys64\mingw32\i686-w64-mingw32\include\c++\5.4.0\i686-w64-mingw32"
ignoring nonexistent directory "D:\msys64\mingw32\i686-w64-mingw32\include\c++\5.4.0\backward"
ignoring nonexistent directory "D:\msys64\mingw32\lib\gcc\i686-w64-mingw32\5.4.0\include\c++"
ignoring nonexistent directory "D:\msys64\mingw32\lib\gcc\i686-w64-mingw32\5.4.0\include\c++\i686-w64-mingw32"
ignoring nonexistent directory "D:\msys64\mingw32\lib\gcc\i686-w64-mingw32\5.4.0\include\c++\backward"
ignoring nonexistent directory "D:\msys64\mingw32\i686-w64-mingw32/sys-root/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
D:\msys64\mingw32\include\c++\5.4.0
D:\msys64\mingw32\include\c++\5.4.0\i686-w64-mingw32
D:\msys64\mingw32\include\c++\5.4.0\backward
D:\msys64\mingw32\bin\..\lib\clang\3.8.0\include
D:\msys64\mingw32\lib\gcc\i686-w64-mingw32\5.4.0\include
D:\msys64\mingw32\lib\gcc\i686-w64-mingw32\5.4.0\include-fixed
D:\msys64\mingw32\i686-w64-mingw32\include
D:\msys64\mingw32\include
End of search list.
#0 0x05e6779d
#1 0x0028dfd0
#2 0x00e054a1 (D:\msys64\mingw32\bin\clang++.exe+0xa054a1)
#3 0x779fe40c RtlInitUnicodeString (C:\Windows\SysWOW64\ntdll.dll+0x2e40c)
#4 0x779fe172 RtlAllocateHeap (C:\Windows\SysWOW64\ntdll.dll+0x2e172)
#5 0x779fe40c RtlInitUnicodeString (C:\Windows\SysWOW64\ntdll.dll+0x2e40c)
#6 0x779fe172 RtlAllocateHeap (C:\Windows\SysWOW64\ntdll.dll+0x2e172)
#7 0x761d9d45 malloc (C:\Windows\syswow64\msvcrt.dll+0x9d45)
#8 0x6fef6c7a (D:\msys64\mingw32\bin\libstdc++-6.dll+0xb6c7a)
#9 0x021d0c1d (D:\msys64\mingw32\bin\clang++.exe+0x1dd0c1d)
#10 0x6fef6c7a (D:\msys64\mingw32\bin\libstdc++-6.dll+0xb6c7a)
clang++.exe: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 3.8.0 (tags/RELEASE_380/final)
Target: i686-w64-windows-gnu
Thread model: posix
InstalledDir: D:\msys64\mingw32\bin
clang++.exe: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang++.exe: note: diagnostic msg:
********************
PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang++.exe: note: diagnostic msg: D:\msys64\tmp\sample-704744.cpp
clang++.exe: note: diagnostic msg: D:\msys64\tmp\sample-704744.sh
clang++.exe: note: diagnostic msg:
********************
msys2 mingw32 clang3.8.0でのみ再現するバグにぶち当たった
https://github.com/yumetodo/string_split/issues/1
のでllvmのbugzillaにバグレポを投げた
https://llvm.org/bugs/show_bug.cgi?id=28493
vit9696の指摘
https://github.com/Alexpux/MINGW-packages/issues/1669
これとおんなじバグじゃねーの?とのこと。バグの再現を試みたところ
#0 0x032f103b
#1 0x0303dfc0
#2 0x00e054a1 (D:\msys64\mingw32\bin\clang.exe+0xa054a1)
#3 0x0075788d (D:\msys64\mingw32\bin\clang.exe+0x35788d)
#4 0x0303e53c
#5 0xffffffffffffffff
#6 0xffffffffffffffff
#7 0xffffffffffffffff
#8 0xffffffffffffffff
#9 0xffffffffffffffff
#10 0xffffffffffffffff
#11 0xffffffffffffffff
#12 0xffffffffffffffff
#13 0xffffffffffffffff
#14 0xffffffffffffffff
#15 0xffffffffffffffff
#16 0xffffffffffffffff
#17 0xffffffffffffffff
#18 0xffffffffffffffff
#19 0xffffffffffffffff
#20 0xffffffffffffffff
#21 0x00a4ab6c (D:\msys64\mingw32\bin\clang.exe+0x64ab6c)
#22 0x00a4764d (D:\msys64\mingw32\bin\clang.exe+0x64764d)
#23 0x033084a8
#24 0x02e23cc0 (D:\msys64\mingw32\bin\clang.exe+0x2a23cc0)
ちょっと違うんじゃね?
173210氏に会う
それから2ヶ月が経ち、友人の173210氏に会ってこの件を見せた。
173210「直してみるか、いまからやる?(20:30ごろ)」
私「(そんなすぐ直せんのか、すげぇ)じゃあやるか」
173210「とりあえずclangをビルドするか」
ビルド待ち時間に気がついたこと
173210「あれ、これまずいかも」
私「といいますと?」
#0 0x05e6779d
#1 0x0028dfd0
#2 0x00e054a1 (D:\msys64\mingw32\bin\clang++.exe+0xa054a1)
#3 0x779fe40c RtlInitUnicodeString (C:\Windows\SysWOW64\ntdll.dll+0x2e40c)
#4 0x779fe172 RtlAllocateHeap (C:\Windows\SysWOW64\ntdll.dll+0x2e172)
#5 0x779fe40c RtlInitUnicodeString (C:\Windows\SysWOW64\ntdll.dll+0x2e40c)
#6 0x779fe172 RtlAllocateHeap (C:\Windows\SysWOW64\ntdll.dll+0x2e172)
#7 0x761d9d45 malloc (C:\Windows\syswow64\msvcrt.dll+0x9d45)
#8 0x6fef6c7a (D:\msys64\mingw32\bin\libstdc++-6.dll+0xb6c7a)
#9 0x021d0c1d (D:\msys64\mingw32\bin\clang++.exe+0x1dd0c1d)
#10 0x6fef6c7a (D:\msys64\mingw32\bin\libstdc++-6.dll+0xb6c7a)
173210「まずmalloc
関数の中でバグるっておかしい。ヒープ破壊の可能性がある」
私「なんでヒープ破壊するとバグるん?」
173210「実装にもよるけど、確保したメモリー空間の前後にメタ情報を書き込んでることが多いから、それが壊れるとバグることがある」
私「なるほど」
173210「それからこのログ、clang++
とlibstdc++
を行ったり来たりしてるからこのログ自体壊れてるかもしれん」
私「意外と大きいバグかもしれん・・・?」
カラオケでClang fix
カラオケでRe:ゼロから始まる異世界生活とかこの素晴らしい世界に祝福を!のOP/ED流しながらClangビルドしてた
coutの<<が引っ張ってこれるのがADLのおかげって言うのがまあADLの主張だけど、そもそもなんで<<でやる必要があるんだ…。
2016-09-16 02:36:03operator overlaodを悪用するため。ゆえに悪用しなくて良い世界が来ないとダメ。 遅延評価ほしい twitter.com/tanakh/status/…
2016-09-16 02:39:50なんでADLなんて必要なんだろう。ADLなんてなくても、何も不自由しないし、ADLがある言語C++も、ADLがあるせいでみんなstd::を全部書くから結局シンタクティックノイズ増えてるじゃん。完全に逆効果だと思うんだけど。
2016-09-16 02:34:33ADLの意義はopeartor overloadを悪用するためと言っても過言ではなく、また、opeartor overloadを悪用する理由はC#拡張メソッドのようなものが無かったり、遅延評価がないせい。
2016-09-16 02:40:56飯田橋のカラオケ屋に@173210 と@kagucho_kamioda と行ってClangのバグを探そうとしていたが、そもそもうまくビルドできず、またログをよく見たらヒープ破壊の疑いが出てるので辛い
2016-09-16 00:17:40一時撤退
Clangのビルドがうまく行かず、家にかえることに。
問題を引き起こすコードそのものの解説は
C++でPStade.Oven(pipeline)風味なstringのsplitを作ってみた - Qiita
で書いたしね
問題となってるのは github.com/yumetodo/strin… これね。mallocで失敗とかいう謎ログが出てて、@173210 はヒープ破壊を疑っている
2016-09-16 00:23:54173210氏の解析が始まる
clang on MinGW-w64, こちらでもビルドしてるけど普通にこけるし、まずはMinGW-w64直すところから始まりそう。
2016-09-16 11:59:03@173210 tripleが*-*-mingw*ならllvm/projects/libcxx/lib/builditで指定されるはず。
2016-09-16 13:17:39@173210 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32ってのはどっから来た?
2016-09-16 13:21:06