Top Level Namespace
Defined Under Namespace
Modules: Contrast, ContrastThread, DummyMod, ERBPropagator, ForcePrepend, Funchook Classes: Class, Delegator, Hash, Module, Object, String, Thread
Constant Summary collapse
- FUNCHOOK_DIR_NAME =
'funchook'
- FUNCHOOK_DIR =
File.(File.join(File.dirname(File.(__FILE__)), '..', FUNCHOOK_DIR_NAME))
- COMMANDS =
['./autogen.sh', './configure', 'make clean', 'make'].freeze
- SOURCE_PATHS =
[ File.join('include', 'funchook.h'), File.join('src', 'libfunchook.dylib'), File.join('src', 'libfunchook.so') ].freeze
- TARGET_PATHS =
([ File.(File.join(File.(__dir__), '..', 'shared_libraries')), File.(__dir__) ] + bundler_install_target_paths).freeze
- SYMS =
Create explicit symbol list, that will be set as promise to be loaded dynamic on run time.
%w[ _assess _policy _assess_policy _assess_propagator _core_assess _contrast_patcher _contrast_check_prepended _contrast_check_and_register_instance_patch _contrast_register_singleton_prepend_patch _contrast_register_patch _contrast_register_singleton_patch _inst_methods_enter_cntr_scope _inst_methods_enter_method_scope _inst_methods_exit_cntr_scope _inst_methods_exit_method_scope _inst_methods_in_cntr_scope _rb_sym_method _rb_sym_hash_tracked _rb_sym_skip_assess_analysis _rb_sym_skip_contrast_analysis _patch_via_funchook ].freeze
- STANDARD_FLAGS =
The mkmf.rb file uses all passed flags from Ruby configuration (RbConfig::CONFIG) on Ruby build time. Problem with Clang and GCC is that it do not keep up with c89 and finds error on including <ryby.h> as not allowing inline variables.
Ruby inlining is a C99 feature that is allowed to be used, because the Ruby configure script can work around the absence of the inline feature with a simple #define:
ifndef __cplusplus define inline endif
There is difference between using c89 and gnu89, as the latter is extended version of the 1989 standard allowing features like // comments for example. This makes the use of the gnu not favorable since it will skip some checks and would make wholes in the c89 standard support.
We can directly append the CFLAGS we need with ENV variable used to create the makefile. MAKEFILE_CONFIG is extension of the RbConfig::CONFIG used to build the Ruby itself. So if we try to run c89 on clang it will brake because of detecting errors from external library used - Ruby itself build with different standard as it seems. This means the Ruby must be compiled beforehand with the compiler forced to C89.
This makes the C dialect of choice to be gnu89 with strict pedantic warnings reported as errors, and making the compiler configurable by flags:
'-std=gnu89'
- CLANG =
'clang'
- WARNING_FLAGS =
Adding -pedantic could raise <ruby.h> warnings, and we are not in control of that code. e.g. error: ‘_Bool’ is a C99 extension [-Werror,-Wc99-extensions] ; empty macros and etc.
-Wno-int-conversion => Passing VALUEs as function args but required as unsigned long parameters. -Werror => report all warnings as errors -Wshorten-64-to-32 => is recognized by clang but not in gcc.
Use alternative if viable. [Wno-narrowing]
-Wno-maybe-uninitialized is used by clang but not gcc
Note: Clang supports old style function definition e.g. void func () {} but the gcc is not. make sure to add parameters type => void func (void) {}. All Changes must be tested against both clang and gcc.
%w[ -Wno-language-extension-token -Wno-incompatible-function-pointer-types -Wno-declaration-after-statement -Wno-variadic-macros -Wno-int-conversion -Wno-incompatible-pointer-types -Wno-narrowing ].freeze
- GCC_FLAGS =
Flags that are only recognized by gcc:
%w[-Wno-maybe-uninitialized].freeze
Instance Method Summary collapse
-
#darwin? ⇒ Boolean
rubocop:disable Security/Object/Freeze.
-
#enable_env_cc ⇒ Object
use C compiler if set.
-
#ext_path ⇒ Object
__dir__ is relative to the file you’re reading.
-
#extend_cflags ⇒ Object
Extend $CFLAGS passed directly to compiler in ruby mkmf.
-
#mac_symbol_resolve ⇒ Object
Since we cannot link directly the bundles created after the extensions being build, we can pass flags to the linker to resolve symbols not being found during compilation, since they are going to be available on load time.
-
#make! ⇒ Object
Generate Makefile.
Instance Method Details
#darwin? ⇒ Boolean
rubocop:disable Security/Object/Freeze
82 83 84 |
# File 'ext/extconf_common.rb', line 82 def darwin? RbConfig::CONFIG['target_os'].include?('darwin') end |
#enable_env_cc ⇒ Object
use C compiler if set.
106 107 108 |
# File 'ext/extconf_common.rb', line 106 def enable_env_cc RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC'] end |
#ext_path ⇒ Object
__dir__ is relative to the file you’re reading. this file you’re reading is presently within $APP_ROOT/ext/.
161 162 163 |
# File 'ext/extconf_common.rb', line 161 def ext_path __dir__ end |
#extend_cflags ⇒ Object
Extend $CFLAGS passed directly to compiler in ruby mkmf
Extended flags are mainly tested with clang and gcc. Experience with other compilers may vary. To that end if something brakes on client side we must have a mechanism to go back to previous non strict gnu89 standard and be able to maintain the build. We can disable newly added changes with this setting CONTRAST_USE_C89=false.
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'ext/extconf_common.rb', line 92 def extend_cflags return if ENV['CONTRAST__USE_GNU89'] == 'false' $CFLAGS += " #{ [STANDARD_FLAGS, WARNING_FLAGS].flatten.join(' ') }" # Extend with GCC specific flags: unless RbConfig::MAKEFILE_CONFIG['CC'].downcase.include?(CLANG) || RbConfig::MAKEFILE_CONFIG['CPP'].downcase.include?(CLANG) || RbConfig::CONFIG['CC'].downcase.include?(CLANG) $CFLAGS += " #{ GCC_FLAGS.flatten.join(' ') }" end end |
#mac_symbol_resolve ⇒ Object
Since we cannot link directly the bundles created after the extensions being build, we can pass flags to the linker to resolve symbols not being found during compilation, since they are going to be available on load time. Ruby first is loaded then the extensions. MacOS introduced new fixups with Xcode 14. This causes the issue of symbols not being linked during compilation for the Agent, and other ruby related issues with objective C objects being used, bigdecimal being different and so on.
Ruby itself is build on MacOS with ‘–enabled-shared’ flag, also Ruby interpreters compiled under Xcode14 no longer specify by default in DLDFLAGS this flag:
'-undefined dynamic_lookup'
( As of Xcode14.3 behavior of dynamic_lookup is reverted back.)
This simply is telling the linker that any unknown symbols will be resolved dynamic on extension load. However with the new fixup chain introduced an warning may be produced: ld: warning: -undefined dynamic_lookup may not work with chained fixups. The fixups are responsible for the dynamic linking of the dylibs.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'ext/extconf_common.rb', line 127 def mac_symbol_resolve # If this is braking the build, it can be disabled. return if ENV['CONTRAST__NO_MAC_LD_FIX'] == 'true' return unless darwin? # Disabled as of the unknown changes to newly ruby interpreter builds: # RbConfig::CONFIG['EXTDLDFLAGS'] = "-bundle_loader #{ RbConfig::CONFIG['EXTDLDFLAGS'] }" # Avoid using this, as not desirable: # # Adding -no_fixup_chains will brake older compilers but will work on newer. # This flag solves the problem but on the long run might not be the solution needed, now not being default, # any new feature changes on Mac or Ruby side might brake things again. # Use this only if explicitly set as ENV var,as a backup on client's end. # # $LDFLAGS << " " << flag append_ldflags('-Wl,-no_fixup_chains -undefined dynamic_lookup') if ENV['CONTRAST__MAC_LD_USE_ALT'] == 'true' # Another alternative is to use -Wl,-U with explicit listed depending symbols. # Append the symfile: SYMS.each { |sym| $DLDFLAGS << " -Wl,-U,#{ sym }" } unless ENV['CONTRAST__MAC_LD_USE_ALT'] == 'true' end |
#make! ⇒ Object
Generate Makefile.
151 152 153 |
# File 'ext/extconf_common.rb', line 151 def make! create_makefile("#{ $TO_MAKE }/#{ $TO_MAKE }") end |