CMake crash with exception when EXPORT_COMPILE_COMMANDS ON and <LANG>_DEFINES missing
Background
- Almost identical to #21471 (closed), which was fixed in !5521 (merged)
- Only possible when
CMAKE_EXPORT_COMPILE_COMMANDS
isON
(orEXPORT_COMPILE_COMMANDS
is set for a target)
Fault:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::replace: __pos (which is 18446744073709551615) > this->size() (which is 117)
Call stack:
#0 0x00007ffff6b78438 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6b7a03a in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff74bb84d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff74b96b6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff74b9701 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff74b9919 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff74e23f7 in std::__throw_out_of_range_fmt(char const*, ...) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff754c2ee in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::replace(unsigned long, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x00000000009901e6 in cmMakefileTargetGenerator::WriteObjectRuleFiles (this=0x1e506a0, source=...) at /home/logan/CMake/Source/cmMakefileTargetGenerator.cxx:930
#9 0x000000000098b335 in cmMakefileTargetGenerator::WriteTargetBuildRules (this=0x1e506a0) at /home/logan/CMake/Source/cmMakefileTargetGenerator.cxx:313
#10 0x00000000009a0fee in cmMakefileExecutableTargetGenerator::WriteRuleFiles (this=0x1e506a0) at /home/logan/CMake/Source/cmMakefileExecutableTargetGenerator.cxx:60
#11 0x000000000096fa41 in cmLocalUnixMakefileGenerator3::Generate (this=0x1ae10e0) at /home/logan/CMake/Source/cmLocalUnixMakefileGenerator3.cxx:164
#12 0x000000000091546c in cmGlobalGenerator::Generate (this=0x13050c0) at /home/logan/CMake/Source/cmGlobalGenerator.cxx:1513
#13 0x000000000093b097 in cmGlobalUnixMakefileGenerator3::Generate (this=0x13050c0) at /home/logan/CMake/Source/cmGlobalUnixMakefileGenerator3.cxx:139
#14 0x00000000005b2874 in cmake::Generate (this=0x7fffffffdd60) at /home/logan/CMake/Source/cmake.cxx:2294
#15 0x00000000005b260a in cmake::Run (this=0x7fffffffdd60, args=std::vector of length 5, capacity 8 = {...}, noconfigure=false) at /home/logan/CMake/Source/cmake.cxx:2274
#16 0x000000000041184e in (anonymous namespace)::do_cmake (ac=5, av=0x12c5c60) at /home/logan/CMake/Source/cmakemain.cxx:353
#17 0x0000000000415c36 in main (ac=5, av=0x12c5c60) at /home/logan/CMake/Source/cmakemain.cxx:981
(gdb) p langFlags
$1 = "$(ASM_FLAGS)"
In my example, CMAKE_ASM_COMPILE_OBJECT
is set to "<CMAKE_ASM_COMPILER> -c -plosgff <OBJECT> <SOURCE>"
, which is missing the <FLAGS>
field.
Proposed Fix
!5521 (merged) fixed this issue for <LANG>_DEFINES
and <LANG>_INCLUDES
but skipped <LANG>_FLAGS
. The code in question:
compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
this->GetFlags(lang, this->GetConfigName()));
Could be updated to match the pattern for DEFINES and INCLUDES:
std::string::size_type lfPos = compileCommand.find(langFlags);
if (lfPos != std::string::npos) {
compileCommand.replace(lfPos, langFlags.size(),
this->GetFlags(lang, this->GetConfigName()));
}