Fix compilation error with WITH_COMPILER_ASAN=ON on macOS

This change solves the following linker error:

  ld: warning: __eh_frame section too large (max 16MB) to encode dwarf unwind offsets in compact unwind table

Proposed solution is to disable unwind table when building Blender with
address sanitizer enabled.

It is stated in the comment in the code, but to make it explicit there
could some side-effects of code which relies on frame walking:

- backtrace()
- __attribute__((__cleanup__(f)))
- __builtin_return_address(n), for n > 0
- pthread_cleanup_push when it is implemented using
  __attribute__((__cleanup__(f)))

From the local tests it seems that backtrace() provides the same
output as prior to this change (but with classic linker used, as prior
to this change it is not possible to link Blender).

The rest of the possibly functionality is not used by Blender, but
it is a bit hard to tell if it is used by any of the dependent
libraries. However, if the libraries are compiled dynamically, there
will be no affect on them with this change.

I am unable to run the full test suit as some of the tests are
failing prior to this change with classic linker. Overall it seems
to be no unwanted side effects on Blender development.

Note that the change only affects debug builds with ASAN enabled,
so it is a low risk of causing some real problem so might as well
just give it a whirl and see if some unpredicted issue arises.

Pull Request: https://projects.blender.org/blender/blender/pulls/116745
This commit is contained in:
Sergey Sharybin 2024-01-03 16:39:05 +01:00 committed by Sergey Sharybin
parent f63accd3b6
commit f0d6346c9a
1 changed files with 19 additions and 0 deletions

View File

@ -1302,6 +1302,25 @@ if(NOT CMAKE_BUILD_TYPE MATCHES "Release")
string(REPLACE " " ";" _list_COMPILER_ASAN_CFLAGS ${COMPILER_ASAN_CFLAGS})
set(_is_CONFIG_DEBUG "$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>")
add_compile_options("$<${_is_CONFIG_DEBUG}:${_list_COMPILER_ASAN_CFLAGS}>")
# Skip generation of the unwind tables, as they might require a lot of space when sanitizers
# are enabled and not fit into the .eh_frame section. Disabling the unwind tables might have
# side effects on code which does frame walking, such as
# - backtrace()
# - __attribute__((__cleanup__(f)))
# - __builtin_return_address(n), for n > 0
# - pthread_cleanup_push when it is implemented using __attribute__((__cleanup__(f)))
# It should not have affect on debugging, since it uses -g flag which generates debugging
# tables in the .debug_frame section.
# At the time of adding these flags calling backtrace() from C code on Apple M2 did not
# affect on the printed backtrace, and exception handling was correct as well.
#
# Related discussion:
# https://stackoverflow.com/questions/26300819/why-gcc-compiled-c-program-needs-eh-frame-section
add_compile_options("$<${_is_CONFIG_DEBUG}:-fno-unwind-tables>")
add_compile_options("$<${_is_CONFIG_DEBUG}:-fno-asynchronous-unwind-tables>")
add_compile_options("$<${_is_CONFIG_DEBUG}:-fno-omit-frame-pointer>")
add_link_options("$<${_is_CONFIG_DEBUG}:-fno-omit-frame-pointer;-fsanitize=address>")
unset(_list_COMPILER_ASAN_CFLAGS)
unset(_is_CONFIG_DEBUG)