Skip to content

Commit

Permalink
[NOT FOR COMMIT] Reproducer for mis-compiled exception handling
Browse files Browse the repository at this point in the history
The corresponding github issue has more detail on the problem.

This code is not in any meaningful state to be committed -- it contains a bunch of hacks I had to make to get the binary to build statically -- libunwind is linked in (via folly), and I had to make changes to include liblzma as well (which libunwind depends on) as well as fix some other unrelated cmake issues.

Reproduction instructions below.

First, build it with `python infra/helper.py build_fuzzers --sanitizer address proxygen`
Then, check the build (it will pass): `python infra/helper.py check_build proxygen`
Then, run the fuzzer: `python infra/helper.py run_fuzzer proxygen ProxygenHTTP1xFuzzer`

It will fail in about ~30 seconds with the below trace. If the fuzzer goes down another path, I've had it reproduce easily by pulling up the shell, running `base64 -d`, pushing that input to a file, and then running the fuzzer directly on that file.

```
terminating with uncaught exception of type folly::ConversionError: Non-digit character found: "OPY"
AddressSanitizer:DEADLYSIGNAL
=================================================================
==11==ERROR: AddressSanitizer: ABRT on unknown address 0x00000000000b (pc 0x7fc166eb7428 bp 0x000000000001 sp 0x7ffcff0a6c78 T0)
SCARINESS: 10 (signal)
    #0 0x7fc166eb7427 in gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35427)
    google#1 0x7fc166eb9029 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x37029)
    google#2 0x9ab7fa in abort_message (/out/ProxygenHTTP1xFuzzer+0x9ab7fa)
    google#3 0x9b009d in demangling_terminate_handler() (/out/ProxygenHTTP1xFuzzer+0x9b009d)
    google#4 0x9ab282 in std::__terminate(void (*)()) (/out/ProxygenHTTP1xFuzzer+0x9ab282)
    google#5 0x9adebd in __cxxabiv1::call_terminate(bool, _Unwind_Exception*) (/out/ProxygenHTTP1xFuzzer+0x9adebd)
    google#6 0x9ade60 in __cxxabiv1::scan_eh_tab(__cxxabiv1::(anonymous namespace)::scan_results&, _Unwind_Action, bool, _Unwind_Exception*, _Unwind_Context*) (/out/ProxygenHTTP1xFuzzer+0x9ade60)
    google#7 0x9ad5c6 in __gxx_personality_v0 (/out/ProxygenHTTP1xFuzzer+0x9ad5c6)
    google#8 0x7fc16725c262 in _Unwind_RaiseException (/lib/x86_64-linux-gnu/libgcc_s.so.1+0x10262)
    google#9 0x9acfd6 in __cxa_throw (/out/ProxygenHTTP1xFuzzer+0x9acfd6)
    google#10 0x5cedab in void folly::throw_exception<folly::ConversionError>(folly::ConversionError&&) /src/proxygen/proxygen/_build/deps/include/folly/lang/Exception.h:36:3
    google#11 0x5eea03 in _ZZN5folly2toItEENSt3__19enable_ifIXntsr3std7is_sameINS_5RangeIPKcEET_EE5valueES7_E4typeES6_ENKUlNS_14ConversionCodeEE_clESA_ /src/proxygen/proxygen/_build/deps/include/folly/Conv.h:1581:26
    google#12 0x5eea03 in _ZN5folly15expected_detail30expected_detail_ExpectedHelper14ExpectedHelper12thenOrThrow_IRNS0_15ExpectedStorageINS_5RangeIPKcEENS_14ConversionCodeELNS0_11StorageTypeE1EEENS_6detail18CheckTrailingSpaceEZNS_2toItEENSt3__19enable_ifIXntsr3std7is_sameIS8_T_EE5valueESI_E4typeES8_EUlS9_E_NS_8ExpectedINS_4UnitES9_EEvLb0ELi0EEET2_OSI_OT0_OT1_ /src/proxygen/proxygen/_build/deps/include/folly/Expected.h:610:5
    google#13 0x5ed846 in _ZNR5folly8ExpectedINS_5RangeIPKcEENS_14ConversionCodeEE11thenOrThrowINS_6detail18CheckTrailingSpaceEZNS_2toItEENSt3__19enable_ifIXntsr3std7is_sameIS4_T_EE5valueESD_E4typeES4_EUlS5_E_EEDTclclsr3stdE7declvalISD_EEclL_ZNSB_7declvalIRS4_EEDTclsr3std3__1E9__declvalISD_ELi0EEEvEEEEOSD_OT0_ /src/proxygen/proxygen/_build/deps/include/folly/Expected.h:1226:16
    google#14 0x5ed846 in _ZN5folly2toItEENSt3__19enable_ifIXntsr3std7is_sameINS_5RangeIPKcEET_EE5valueES7_E4typeES6_ /src/proxygen/proxygen/_build/deps/include/folly/Conv.h:1579:8
    google#15 0x5ed445 in proxygen::ParseURL::parseAuthority() /src/proxygen/proxygen/lib/utils/ParseURL.cpp:155:15
    google#16 0x5ec5e9 in proxygen::ParseURL::parseNonFully() /src/proxygen/proxygen/lib/utils/ParseURL.cpp:140:8
    google#17 0x5ea87a in proxygen::ParseURL::parse() /src/proxygen/proxygen/lib/utils/ParseURL.cpp:96:5
    google#18 0x59a99c in proxygen::ParseURL::init(folly::Range<char const*>) /src/proxygen/proxygen/lib/utils/ParseURL.h:34:5
    google#19 0x58add1 in proxygen::ParseURL::ParseURL(folly::Range<char const*>) /src/proxygen/proxygen/lib/utils/ParseURL.h:28:5
    google#20 0x58add1 in proxygen::ParseURL proxygen::HTTPMessage::setURL<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&) /src/proxygen/proxygen/lib/http/HTTPMessage.h:202:14
    google#21 0x5795f0 in proxygen::HTTP1xCodec::onHeadersComplete(unsigned long) /src/proxygen/proxygen/lib/http/codec/HTTP1xCodec.cpp:976:31
    google#22 0x58e2a3 in proxygen::HTTP1xCodec::onHeadersCompleteCB(proxygen::http_parser*, char const*, unsigned long) /src/proxygen/proxygen/lib/http/codec/HTTP1xCodec.cpp:1315:19
    google#23 0x5f2222 in proxygen::http_parser_execute(proxygen::http_parser*, proxygen::http_parser_settings const*, char const*, unsigned long) /src/proxygen/proxygen/external/http_parser/http_parser_cpp.cpp:1868:17
    google#24 0x577783 in proxygen::HTTP1xCodec::onIngress(folly::IOBuf const&) /src/proxygen/proxygen/lib/http/codec/HTTP1xCodec.cpp:200:26
    google#25 0x55b728 in unsigned long proxygen::parse<proxygen::HTTP1xCodec>(proxygen::HTTP1xCodec*, unsigned char const*, unsigned int, int, std::__1::function<bool ()>) /src/proxygen/proxygen/lib/http/codec/test/TestUtils.h:57:23
    google#26 0x55a6ef in LLVMFuzzerTestOneInput /src/proxygen/proxygen/fuzzers/ProxygenHTTP1xFuzzer.cpp:23:3
    google#27 0x460771 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:554:15
    google#28 0x45fe95 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/llvm/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:470:3
    google#29 0x462247 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:696:19
    google#30 0x462fe5 in fuzzer::Fuzzer::Loop(std::Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm/projects/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:832:5
    google#31 0x450dd8 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm/projects/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:825:6
    google#32 0x47b442 in main /src/llvm/projects/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
    google#33 0x7fc166ea282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    google#34 0x424468 in _start (/out/ProxygenHTTP1xFuzzer+0x424468)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: ABRT (/lib/x86_64-linux-gnu/libc.so.6+0x35427) in gsignal
==11==ABORTING
MS: 3 CrossOver-ChangeBit-EraseBytes-; base unit: 467e3fbf38770044dea566169b84c60cb269c89a
0x43,0x4f,0x50,0x59,0x20,0x43,0x3a,0x4f,0x50,0x59,0x2f,0x4f,0xff,0xa,0x43,0x4f,0x50,0x59,0x20,0x2f,0x4f,0xff,0xa,0x43,0x4f,0x50,0x59,0x20,0x2f,0x6f,0x20,0xff,0x50,0x59,0x0,0x43,0xcf,0x50,0x59,0xff,0x4f,0x50,0x33,
COPY C:OPY/O\xff\x0aCOPY /O\xff\x0aCOPY /o \xffPY\x00C\xcfPY\xffOP3
artifact_prefix='./'; Test unit written to ./crash-2cd12847d55ebf08ec2eaee4e814c52e545e7f92
Base64: Q09QWSBDOk9QWS9P/wpDT1BZIC9P/wpDT1BZIC9vIP9QWQBDz1BZ/09QMw==
```

This seems wrong to me since the code is inside a try/catch block: https://github.com/facebook/proxygen/blob/master/proxygen/lib/utils/ParseURL.cpp#L159-L164

I can confirm that the same input does not crash the fuzzer in the version being built on oss-fuzz trunk (and indeed it would have also reported this as a test-case by now given it's been running over a day)
  • Loading branch information
mhlakhani committed Sep 25, 2019
1 parent c511c7b commit 6ee029d
Show file tree
Hide file tree
Showing 5 changed files with 478 additions and 11 deletions.
4 changes: 4 additions & 0 deletions projects/proxygen/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,8 @@ RUN apt-get install patchelf
# Fetch source and copy over files
RUN git clone --depth 1 https://github.com/facebook/proxygen.git proxygen
WORKDIR proxygen
COPY patch.txt .
COPY folly_patch.txt ./proxygen/
COPY fizz_patch.txt ./proxygen/
RUN git apply ./patch.txt
COPY build.sh $SRC/
12 changes: 1 addition & 11 deletions projects/proxygen/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,8 @@

cd proxygen

# Link to, and copy over, libunwind
# We need to link to libunwind to ensure exception handling works
# See https://clang.llvm.org/docs/Toolchain.html#unwind-library
export LDFLAGS="-lunwind"
mkdir -p $OUT/lib
cp /usr/lib/x86_64-linux-gnu/libunwind.so.8 $OUT/lib/

# Build everything
./build.sh -m --no-install-dependencies --build-for-fuzzing

# Patch rpath so fuzzers can find libunwind
find ./_build/proxygen/fuzzers -type f -executable -exec patchelf --set-rpath '$ORIGIN/lib' {} \;

# Copy fuzzers over to the destination
find ./_build/proxygen/fuzzers -type f -executable -exec cp {} $OUT/ \;
find ./_build/proxygen/fuzzers -type f -executable -exec cp {} $OUT/ \;
297 changes: 297 additions & 0 deletions projects/proxygen/fizz_patch.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
diff --git a/fizz/CMakeLists.txt b/fizz/CMakeLists.txt
index 2ceaf70..5d55e1f 100644
--- a/fizz/CMakeLists.txt
+++ b/fizz/CMakeLists.txt
@@ -293,77 +293,78 @@ ELSE(CMAKE_CROSSCOMPILING)
ENDIF(CMAKE_CROSSCOMPILING)

SET(FIZZ_TEST_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
-if(BUILD_TESTS)
- enable_testing()

- find_package(GMock REQUIRED)
- if(NOT LIBGMOCK_FOUND)
- include(ExternalProject)
-
- # Download and install GoogleMock
- ExternalProject_Add(
- gtest
- GIT_REPOSITORY https://github.com/google/googletest.git
- GIT_TAG release-1.8.0
- PREFIX gtest
- # Disable install step
- INSTALL_COMMAND ""
- LOG_DOWNLOAD ON
- LOG_UPDATE 1
- LOG_CONFIGURE ON
- LOG_BUILD ON
- LOG_TEST 1
- LOG_INSTALL 1
- )
-
- # Create a libgmock target to be used as a dependency by test programs
- add_library(libgmock IMPORTED STATIC GLOBAL)
- add_dependencies(libgmock gtest)
- add_library(libgmock_main IMPORTED STATIC GLOBAL)
- add_dependencies(libgmock_main gtest)
-
- # Set gmock properties
- ExternalProject_Get_Property(gtest source_dir binary_dir)
- set_target_properties(libgmock PROPERTIES
- "IMPORTED_LOCATION" "${binary_dir}/googlemock/libgmock.a"
- "IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
- )
- set_target_properties(libgmock_main PROPERTIES
- "IMPORTED_LOCATION" "${binary_dir}/googlemock/libgmock_main.a"
- "IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
- )
- set(LIBGMOCK_LIBRARIES libgmock libgmock_main)
- set(LIBGMOCK_INCLUDE_DIR "${source_dir}/googlemock/include")
- set(LIBGTEST_INCLUDE_DIR "${source_dir}/googletest/include")
- endif()
+find_package(GMock REQUIRED)
+if(NOT LIBGMOCK_FOUND)
+include(ExternalProject)
+
+# Download and install GoogleMock
+ExternalProject_Add(
+gtest
+GIT_REPOSITORY https://github.com/google/googletest.git
+GIT_TAG release-1.8.0
+PREFIX gtest
+# Disable install step
+INSTALL_COMMAND ""
+LOG_DOWNLOAD ON
+LOG_UPDATE 1
+LOG_CONFIGURE ON
+LOG_BUILD ON
+LOG_TEST 1
+LOG_INSTALL 1
+)

- add_library(fizz_test_support
- crypto/aead/test/TestUtil.cpp
- crypto/test/TestUtil.cpp
- ${FIZZ_TEST_HEADERS})
+# Create a libgmock target to be used as a dependency by test programs
+add_library(libgmock IMPORTED STATIC GLOBAL)
+add_dependencies(libgmock gtest)
+add_library(libgmock_main IMPORTED STATIC GLOBAL)
+add_dependencies(libgmock_main gtest)
+
+# Set gmock properties
+ExternalProject_Get_Property(gtest source_dir binary_dir)
+set_target_properties(libgmock PROPERTIES
+"IMPORTED_LOCATION" "${binary_dir}/googlemock/libgmock.a"
+"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
+)
+set_target_properties(libgmock_main PROPERTIES
+"IMPORTED_LOCATION" "${binary_dir}/googlemock/libgmock_main.a"
+"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
+)
+set(LIBGMOCK_LIBRARIES libgmock libgmock_main)
+set(LIBGMOCK_INCLUDE_DIR "${source_dir}/googlemock/include")
+set(LIBGTEST_INCLUDE_DIR "${source_dir}/googletest/include")
+endif()

- target_link_libraries(fizz_test_support
- PUBLIC
- fizz
- )
-
- # export fizz headers and targets for unit tests utils
- # since other projects such as mvfst and proxygen use them
- install(
- TARGETS fizz_test_support
- EXPORT fizz-exports
- ARCHIVE DESTINATION ${FIZZ_TEST_INSTALL_PREFIX}/lib
- LIBRARY DESTINATION ${FIZZ_TEST_INSTALL_PREFIX}/lib
- )
-
- foreach(dir ${FIZZ_TEST_HEADER_DIRS})
- get_filename_component(PARENT_DIR "/${dir}" DIRECTORY)
- install(
- DIRECTORY ${dir}
- DESTINATION "${FIZZ_TEST_INSTALL_PREFIX}/include/fizz${PARENT_DIR}"
- FILES_MATCHING PATTERN "*.h"
- )
- endforeach()
+add_library(fizz_test_support
+crypto/aead/test/TestUtil.cpp
+crypto/test/TestUtil.cpp
+${FIZZ_TEST_HEADERS})
+
+target_link_libraries(fizz_test_support
+PUBLIC
+fizz
+)
+
+# export fizz headers and targets for unit tests utils
+# since other projects such as mvfst and proxygen use them
+install(
+TARGETS fizz_test_support
+EXPORT fizz-exports
+ARCHIVE DESTINATION ${FIZZ_TEST_INSTALL_PREFIX}/lib
+LIBRARY DESTINATION ${FIZZ_TEST_INSTALL_PREFIX}/lib
+)
+
+foreach(dir ${FIZZ_TEST_HEADER_DIRS})
+get_filename_component(PARENT_DIR "/${dir}" DIRECTORY)
+install(
+DIRECTORY ${dir}
+DESTINATION "${FIZZ_TEST_INSTALL_PREFIX}/include/fizz${PARENT_DIR}"
+FILES_MATCHING PATTERN "*.h"
+)
+endforeach()
+
+if(BUILD_TESTS)
+ enable_testing()

macro(add_gtest test_source test_name)
add_executable(${test_name} ${test_source} test/CMakeTestMain.cpp)
@@ -440,7 +441,7 @@ if(BUILD_TESTS)
add_gtest(test/HandshakeTest.cpp HandshakeTest)
endif()

-option(BUILD_EXAMPLES "BUILD_EXAMPLES" ON)
+option(BUILD_EXAMPLES "BUILD_EXAMPLES" OFF)

if(BUILD_EXAMPLES)
add_executable(BogoShim test/BogoShim.cpp)
diff --git a/fizz/cmake/CheckAtomic.cmake b/fizz/cmake/CheckAtomic.cmake
index b0cadee..2abee5a 100644
--- a/fizz/cmake/CheckAtomic.cmake
+++ b/fizz/cmake/CheckAtomic.cmake
@@ -39,55 +39,109 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
# SOFTWARE.

-include(CheckCXXSourceCompiles)
+# atomic builtins are required for threading support.
+
+INCLUDE(CheckCXXSourceCompiles)
+INCLUDE(CheckLibraryExists)

# Sometimes linking against libatomic is required for atomic ops, if
# the platform doesn't support lock-free atomics.

function(check_working_cxx_atomics varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
- get_directory_property(compile_options COMPILE_OPTIONS)
- set(CMAKE_REQUIRED_FLAGS ${compile_options})
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
CHECK_CXX_SOURCE_COMPILES("
#include <atomic>
+std::atomic<int> x;
int main() {
- struct Test { int val; };
- std::atomic<Test> s;
- s.is_lock_free();
-}" ${varname})
+ return x;
+}
+" ${varname})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
endfunction(check_working_cxx_atomics)

+function(check_working_cxx_atomics64 varname)
+ set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
+ CHECK_CXX_SOURCE_COMPILES("
+#include <atomic>
+#include <cstdint>
+std::atomic<uint64_t> x (0);
+int main() {
+ uint64_t i = x.load(std::memory_order_relaxed);
+ return 0;
+}
+" ${varname})
+ set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
+endfunction(check_working_cxx_atomics64)

-if(NOT DEFINED PROXYGEN_COMPILER_IS_GCC_COMPATIBLE)
- if(CMAKE_COMPILER_IS_GNUCXX)
- set(PROXYGEN_COMPILER_IS_GCC_COMPATIBLE ON)
- elseif(MSVC)
- set(PROXYGEN_COMPILER_IS_GCC_COMPATIBLE OFF)
- elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
- set(PROXYGEN_COMPILER_IS_GCC_COMPATIBLE ON)
- elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")
- set(PROXYGEN_COMPILER_IS_GCC_COMPATIBLE ON)
- endif()
-endif()

# This isn't necessary on MSVC, so avoid command-line switch annoyance
# by only running on GCC-like hosts.
-if(PROXYGEN_COMPILER_IS_GCC_COMPATIBLE)
+if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
# First check if atomics work without the library.
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it.
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
- check_library_exists(atomic __atomic_is_lock_free "" HAVE_LIBATOMIC)
- if(HAVE_LIBATOMIC)
+ check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
+ if( HAVE_LIBATOMIC )
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
- message(FATAL_ERROR "Host compiler must support std::atomic!")
+ message(FATAL_ERROR "Host compiler must support std::atomic!")
endif()
- list(APPEND CMAKE_CXX_STANDARD_LIBRARIES -latomic)
else()
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
endif()
endif()
endif()
+
+# Check for 64 bit atomic operations.
+if(MSVC)
+ set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
+else()
+ check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+endif()
+
+# If not, check if the library exists, and atomics work with it.
+if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+ check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
+ if(HAVE_CXX_LIBATOMICS64)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
+ check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
+ if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
+ message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
+ endif()
+ else()
+ message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
+ endif()
+endif()
+
+## TODO: This define is only used for the legacy atomic operations in
+## llvm's Atomic.h, which should be replaced. Other code simply
+## assumes C++11 <atomic> works.
+CHECK_CXX_SOURCE_COMPILES("
+#ifdef _MSC_VER
+#include <windows.h>
+#endif
+int main() {
+#ifdef _MSC_VER
+ volatile LONG val = 1;
+ MemoryBarrier();
+ InterlockedCompareExchange(&val, 0, 1);
+ InterlockedIncrement(&val);
+ InterlockedDecrement(&val);
+#else
+ volatile unsigned long val = 1;
+ __sync_synchronize();
+ __sync_val_compare_and_swap(&val, 1, 0);
+ __sync_add_and_fetch(&val, 1);
+ __sync_sub_and_fetch(&val, 1);
+#endif
+ return 0;
+ }
+" LLVM_HAS_ATOMICS)
+
+if( NOT LLVM_HAS_ATOMICS )
+ message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
+endif()
49 changes: 49 additions & 0 deletions projects/proxygen/folly_patch.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
diff --git a/CMake/FollyCompilerUnix.cmake b/CMake/FollyCompilerUnix.cmake
index 9c76fdc6..186f3f30 100644
--- a/CMake/FollyCompilerUnix.cmake
+++ b/CMake/FollyCompilerUnix.cmake
@@ -19,7 +19,7 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_COMMON}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_COMMON} -O3")

# Note that CMAKE_REQUIRED_FLAGS must be a string, not a list
-set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=${CXX_STD}")
+#set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=${CXX_STD}")
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
function(apply_folly_compile_options_to_target THETARGET)
target_compile_definitions(${THETARGET}
diff --git a/CMake/folly-deps.cmake b/CMake/folly-deps.cmake
index 0fb8a90a..9c4599b2 100644
--- a/CMake/folly-deps.cmake
+++ b/CMake/folly-deps.cmake
@@ -117,7 +117,7 @@ CHECK_INCLUDE_FILE_CXX(elf.h FOLLY_HAVE_ELF_H)
find_library(UNWIND_LIBRARIES NAMES unwind)
if (UNWIND_LIBRARIES)
list(APPEND FOLLY_LINK_LIBRARIES ${UNWIND_LIBRARIES})
- list(APPEND CMAKE_REQUIRED_LIBRARIES ${UNWIND_LIBRARIES})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${UNWIND_LIBRARIES} ${LIBLZMA_LIBRARIES})
endif()
check_function_exists(backtrace FOLLY_HAVE_BACKTRACE)
if (FOLLY_HAVE_ELF_H AND FOLLY_HAVE_BACKTRACE AND LIBDWARF_FOUND)
@@ -155,6 +155,7 @@ if(NOT FOLLY_CPP_ATOMIC_BUILTIN)
endif()
endif()

+
option(
FOLLY_LIBRARY_SANITIZE_ADDRESS
"Build folly with Address Sanitizer enabled."
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d785431..38228903 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,10 @@ if(POLICY CMP0075)
cmake_policy(SET CMP0075 NEW)
endif()

+if(POLICY CMP0067)
+ cmake_policy(SET CMP0067 NEW)
+endif()
+
# includes
set(CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/CMake"
Loading

0 comments on commit 6ee029d

Please sign in to comment.