From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Alexander Turenko Subject: [PATCH] cmake: workaround GCC 7.2 segfault on v?sn?printf Date: Fri, 28 Dec 2018 07:48:54 +0300 Message-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit To: Vladimir Davydov Cc: Alexander Turenko , tarantool-patches@freelists.org List-ID: GCC 7.2.1 fails like so on our codebase: /tarantool/src/lib/json/json.c: In function ‘json_token_snprint’: /tarantool/src/lib/json/json.c:324:1: internal compiler error: Segmentation fault json_token_snprint(char *buf, int size, const struct json_token *token, ^~~~~~~~~~~~~~~~~~ The backtrace of cc1 is the following (failed to install compatible debuginfo on Fedora 26, so ??s): #0 0x0000000000d0320c in get_source_location_for_substring(cpp_reader*, string_concat_db*, unsigned int, cpp_ttype, int, int, int, unsigned int*) () #1 0x00000000005c0e79 in c_get_substring_location(substring_loc const&, unsigned int*) () #2 0x00000000007f8418 in format_warning_va(substring_loc const&, source_range const*, char const*, int, char const*, __va_list_tag (*) [1]) () #3 0x00000000007f838b in format_warning_at_substring(substring_loc const&, source_range const*, char const*, int, char const*, ...) () #4 0x0000000000c72c2d in ?? () #5 0x0000000000f6f308 in execute_one_pass(opt_pass*) () #6 0x0000000000787da6 in ?? () #7 0x00000000012ac338 in symbol_table::compile() () #8 0x0000000000de650f in symbol_table::finalize_compilation_unit() () #9 0x00000000012ee8df in ?? () #10 0x0000000000d3ba84 in toplev::main(int, char**) () #11 0x0000000000d3d35b in main () The issue in the GCC bugtracker: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83448 The idea of the commit is to check builtin snprintf with the code from GCC test suite and disable all related builtins if the compiler is GCC and the case fails. We also need to disable FORTIFY_SOURCES in the case, because it uses v?sn?printf builtins directly. --- no issue https://github.com/tarantool/tarantool/tree/Totktonada/workaround-gcc-7.2-snprintf-segfault Be attentive: I pushed DO NOT MERGE commit upward the commit I send here to enable full testing on the bugfix branch: [1] (hope it will pass). The topmost commit should NOT be pushed to 2.1. [1]: https://travis-ci.org/tarantool/tarantool/builds/472881226 cmake/compiler.cmake | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 4062d13ec..b471b0c38 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -333,6 +333,8 @@ if (NOT HAVE_BUILTIN_CTZ OR NOT HAVE_BUILTIN_CTZLL) HAVE_FFSL) check_c_source_compiles("#include \n#include \nint main(void) { return ffsll(0UL); }" HAVE_FFSLL) + set(CMAKE_REQUIRED_FLAGS "") + set(CMAKE_REQUIRED_DEFINITIONS "") endif() endif() @@ -343,3 +345,44 @@ else() set(CMAKE_HOST_C_COMPILER ${CMAKE_C_COMPILER}) set(CMAKE_HOST_CXX_COMPILER ${CMAKE_CXX_COMPILER}) endif() + +# Check for broken __builtin_v?sn?printf() in gcc-7.2. +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83448 + +# It is important for the test case to be compiled w/o any extra +# flags and with -O2. Say, -Wall allows the case be compiled +# successfully on gcc-7.2.1. +set(PREVIOUS_CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) +set(CMAKE_C_FLAGS "") +set(CMAKE_REQUIRED_DEFINITIONS "") +set(CMAKE_REQUIRED_INCLUDES "") +set(CMAKE_REQUIRED_LIBRARIES "") +set(CMAKE_REQUIRED_FLAGS "-O2") + +check_c_source_compiles(" +char *a; +int b; + +int +main(void) +{ + for (;;) { + if (b < 0) + main(); + __builtin_snprintf(a, b, \"%*s\", b, \"\"); + } + return 0; +}" HAVE_BUILTIN_SNPRINTF) + +set(CMAKE_REQUIRED_FLAGS "") +set(CMAKE_C_FLAGS ${PREVIOUS_CMAKE_C_FLAGS}) + +# /usr/include/stdio.h (bits/stdio2.h to be exact) uses builtin +# gcc v?sn?printf functions when fortify source is enabled. +if (CMAKE_COMPILER_IS_GNUCC AND NOT HAVE_BUILTIN_SNPRINTF) + add_compile_flags("C;CXX" "-Wp,-U_FORTIFY_SOURCE") + add_compile_flags("C;CXX" "-fno-builtin-sprintf") + add_compile_flags("C;CXX" "-fno-builtin-snprintf") + add_compile_flags("C;CXX" "-fno-builtin-vsnprintf") + add_compile_flags("C;CXX" "-fno-builtin-vsprintf") +endif() -- 2.20.1