From: Maxim Ostapenko Date: Tue, 12 Jul 2016 07:26:08 +0000 (+0300) Subject: Make lsan-force-options and lsan-build-env more usable. Factor out common X-Git-Tag: accepted/tizen/3.0/base/20161028.102939~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=28a0437c8669094addc3c23a9005f241ec75a8fa;p=platform%2Fupstream%2Flinaro-gcc.git Make lsan-force-options and lsan-build-env more usable. Factor out common code from {A, UB}San to sanitizer_common code. Add -fno-omit-frame-pointer -U_FORTIFY_SOURCE to lsan-force-options because LSan heavily relies on frame pointers. Disable LSan in QEMU builds through LSAN_OPTIONS file. Refactor Tizen specific patches in ASan and UBSan. Change-Id: I95f59243352e75d6cd0eae22e7aaa02ab0e96cfc Signed-off-by: Maxim Ostapenko --- diff --git a/libsanitizer/asan/asan_flags.cc b/libsanitizer/asan/asan_flags.cc index db257c4..4f87cd2 100644 --- a/libsanitizer/asan/asan_flags.cc +++ b/libsanitizer/asan/asan_flags.cc @@ -105,21 +105,11 @@ void InitializeFlags() { ubsan_parser.ParseString(ubsan_default_options); #endif - // Read from command line. - const char *options = GetEnv("ASAN_OPTIONS"); - // If environment variable ASAN_OPTIONS is not set use predefined file to - // init options. - bool getFlagsFromFile = options == 0; - char *asanFlags = 0; - uptr len = GetPageSizeCached(); - uptr read_len = 0; - if (getFlagsFromFile) { - ReadFileToBuffer("/ASAN_OPTIONS", &asanFlags, &len, &read_len, - GetPageSizeCached()); - options = asanFlags; - } - + int mmaped = 0; + const char *options = + GetRuntimeOptions("ASAN_OPTIONS", "/ASAN_OPTIONS", &mmaped); asan_parser.ParseString(options); + #if CAN_SANITIZE_LEAKS lsan_parser.ParseString(GetEnv("LSAN_OPTIONS")); #endif @@ -179,9 +169,8 @@ void InitializeFlags() { f->quarantine_size_mb = kDefaultQuarantineSizeMb; } - if (getFlagsFromFile) - UnmapOrDie(asanFlags, len); - + if (mmaped) + UnmapOrDie((void *)options, GetPageSizeCached()); } } // namespace __asan diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cc index 7f51016..d4dfc1d 100644 --- a/libsanitizer/asan/asan_rtl.cc +++ b/libsanitizer/asan/asan_rtl.cc @@ -400,25 +400,11 @@ static void PrintAddressSpaceLayout() { kHighShadowBeg > kMidMemEnd); } -extern "C" -int mount(const char *source, const char *target, const char *filesystemtype, - unsigned long mountflags, const void *data); - static void MaybeDisableUlimit() { if (!AddressSpaceIsUnlimited()) SetAddressSpaceUnlimited(); } -bool MaybeMountProcFS() { - if (FileExists("/proc/self/maps")) return true; - - if(0 != mount("proc", "/proc", "proc", 0, 0)) { - Report("Failed to mount /proc, Asan is likely to fail\n"); - return false; - } - return true; -} - static void AsanInitInternal() { if (LIKELY(asan_inited)) return; MaybeMountProcFS(); diff --git a/libsanitizer/lsan/lsan.cc b/libsanitizer/lsan/lsan.cc index c39d8cf..1c0df71 100644 --- a/libsanitizer/lsan/lsan.cc +++ b/libsanitizer/lsan/lsan.cc @@ -15,6 +15,7 @@ #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_flag_parser.h" #include "sanitizer_common/sanitizer_stacktrace.h" +#include "sanitizer_common/sanitizer_libc.h" #include "lsan_allocator.h" #include "lsan_common.h" #include "lsan_thread.h" @@ -53,13 +54,20 @@ static void InitializeFlags() { RegisterLsanFlags(&parser, f); RegisterCommonFlags(&parser); - parser.ParseString(GetEnv("LSAN_OPTIONS")); + int mmaped = 0; + const char *options = + GetRuntimeOptions("LSAN_OPTIONS", "/LSAN_OPTIONS", &mmaped); + parser.ParseString(options); SetVerbosity(common_flags()->verbosity); if (Verbosity()) ReportUnrecognizedFlags(); if (common_flags()->help) parser.PrintFlagDescriptions(); + __sanitizer_set_report_path(common_flags()->log_path); + + if (mmaped) + UnmapOrDie((void *)options, GetPageSizeCached()); } extern "C" void __lsan_init() { diff --git a/libsanitizer/sanitizer_common/sanitizer_common.cc b/libsanitizer/sanitizer_common/sanitizer_common.cc index d4ecf25..7c7a6c8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.cc +++ b/libsanitizer/sanitizer_common/sanitizer_common.cc @@ -460,6 +460,24 @@ void PrintCmdline() { Printf("\n\n"); } +const char *GetRuntimeOptions(const char *env_option, const char *filename, + int *mmaped) { + // Read from command line. + const char *options = GetEnv(env_option); + // If environment variable {A, L, UB}SAN_OPTIONS is not set use predefined + // file to init options. + bool getFlagsFromFile = options == 0; + char *flags = 0; + uptr len = GetPageSizeCached(); + uptr read_len = 0; + if (getFlagsFromFile) { + ReadFileToBuffer(filename, &flags, &len, &read_len, GetPageSizeCached()); + *mmaped = 1; + options = flags; + } + return options; +} + } // namespace __sanitizer using namespace __sanitizer; // NOLINT diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h index 1550154..0ac1cd1 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.h +++ b/libsanitizer/sanitizer_common/sanitizer_common.h @@ -712,6 +712,9 @@ struct SignalContext { void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp); +const char *GetRuntimeOptions(const char *env_option, const char *filename, + int *mmaped); + } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.cc b/libsanitizer/sanitizer_common/sanitizer_libc.cc index 05fdca6..d3d9cfe 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libc.cc +++ b/libsanitizer/sanitizer_common/sanitizer_libc.cc @@ -258,4 +258,15 @@ bool mem_is_zero(const char *beg, uptr size) { return all == 0; } +bool MaybeMountProcFS() { + if (FileExists("/proc/self/maps")) + return true; + + if (0 != mount("proc", "/proc", "proc", 0, 0)) { + Report("Failed to mount /proc, %s is likely to fail\n", SanitizerToolName); + return false; + } + return true; +} + } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.h b/libsanitizer/sanitizer_common/sanitizer_libc.h index 1b3f8ed..f9f5820 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libc.h +++ b/libsanitizer/sanitizer_common/sanitizer_libc.h @@ -76,6 +76,12 @@ uptr internal_sched_yield(); // Error handling bool internal_iserror(uptr retval, int *rverrno = nullptr); +extern "C" int mount(const char *source, const char *target, + const char *filesystemtype, unsigned long mountflags, + const void *data); + +bool MaybeMountProcFS(); + } // namespace __sanitizer #endif // SANITIZER_LIBC_H diff --git a/libsanitizer/ubsan/ubsan_flags.cc b/libsanitizer/ubsan/ubsan_flags.cc index f3496d3..d94da279 100644 --- a/libsanitizer/ubsan/ubsan_flags.cc +++ b/libsanitizer/ubsan/ubsan_flags.cc @@ -56,20 +56,13 @@ void InitializeFlags() { // Override from user-specified string. parser.ParseString(MaybeCallUbsanDefaultOptions()); - // Read from command line. - const char *options = GetEnv("UBSAN_OPTIONS"); - char *ubsanFlags = 0; - uptr len = GetPageSizeCached(); - uptr read_len = 0; - bool getFlagsFromFile = ubsanFlags == 0; - // Override from predefined file if exists. - if (getFlagsFromFile) { - ReadFileToBuffer("/UBSAN_OPTIONS", &ubsanFlags, &len, &read_len, - GetPageSizeCached()); - options = ubsanFlags; - } + int mmaped = 0; + const char *options = + GetRuntimeOptions("UBSAN_OPTIONS", "/UBSAN_OPTIONS", &mmaped); parser.ParseString(options); - UnmapOrDie(ubsanFlags, len); + + if (mmaped) + UnmapOrDie((void *)options, GetPageSizeCached()); SetVerbosity(common_flags()->verbosity); if (Verbosity()) ReportUnrecognizedFlags(); diff --git a/packaging/LSAN_OPTIONS b/packaging/LSAN_OPTIONS new file mode 100644 index 0000000..cc480ba --- /dev/null +++ b/packaging/LSAN_OPTIONS @@ -0,0 +1 @@ +detect_leaks=0 diff --git a/packaging/gcc-aarch64.spec b/packaging/gcc-aarch64.spec index a8f6a08..d2b206c 100644 --- a/packaging/gcc-aarch64.spec +++ b/packaging/gcc-aarch64.spec @@ -87,7 +87,8 @@ Source15: gcc-force-options Source16: gcc-unforce-options Source17: ASAN_OPTIONS Source18: asan_symbolize.py -Source19: gcc.manifest +Source19: LSAN_OPTIONS +Source20: gcc.manifest Group: Development/Building Summary: The GNU C Compiler and Support Files License: GPL-3.0+ @@ -651,13 +652,14 @@ Scripts for LSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-4.9.2/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=leak +/usr/bin/gcc-force-options -fsanitize=leak -fno-omit-frame-pointer -U_FORTIFY_SOURCE %preun -n lsan-force-options # Restore read-only mode chmod a-w /usr/bin [ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-4.9.2/obj/gcc/ /usr/bin/gcc-unforce-options +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ %package -n asan-build-env Summary: Asan build environment @@ -689,7 +691,7 @@ Lsan build environment %post -n lsan-build-env # Add /usr/lib64/liblsan.so to /etc/ld.so.preload [ -f /etc/ld.so.preload ] && mv -v /etc/ld.so.preload /etc/ld.so.preload.orig -echo "%{libdir}/liblsan.so" > /etc/ld.so.preload +echo "liblsan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig @@ -738,7 +740,7 @@ plugins build. %prep %setup -q -n gcc-%{version} -cp %{SOURCE19} . +cp %{SOURCE20} . tar xf %{SOURCE10} ln -sf gmp-6.0.0 gmp @@ -908,6 +910,11 @@ chmod a+x %{buildroot}%{_prefix}/bin/asan_symbolize.py cp %{SOURCE17} %{buildroot} chmod 644 %{buildroot}/ASAN_OPTIONS + +%ifarch %lsan_arch +cp %{SOURCE19} %{buildroot} +chmod 644 %{buildroot}/LSAN_OPTIONS +%endif } %files @@ -1157,6 +1164,7 @@ chmod 644 %{buildroot}/ASAN_OPTIONS %ifarch %lsan_arch %files -n lsan-build-env %defattr(-,root,root,-) +/LSAN_OPTIONS %endif %files -n sanitizer-devel diff --git a/packaging/gcc-armv7l.spec b/packaging/gcc-armv7l.spec index 016c272..3822649 100644 --- a/packaging/gcc-armv7l.spec +++ b/packaging/gcc-armv7l.spec @@ -87,7 +87,8 @@ Source15: gcc-force-options Source16: gcc-unforce-options Source17: ASAN_OPTIONS Source18: asan_symbolize.py -Source19: gcc.manifest +Source19: LSAN_OPTIONS +Source20: gcc.manifest Group: Development/Building Summary: The GNU C Compiler and Support Files License: GPL-3.0+ @@ -651,13 +652,14 @@ Scripts for LSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-4.9.2/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=leak +/usr/bin/gcc-force-options -fsanitize=leak -fno-omit-frame-pointer -U_FORTIFY_SOURCE %preun -n lsan-force-options # Restore read-only mode chmod a-w /usr/bin [ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-4.9.2/obj/gcc/ /usr/bin/gcc-unforce-options +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ %package -n asan-build-env Summary: Asan build environment @@ -689,7 +691,7 @@ Lsan build environment %post -n lsan-build-env # Add /usr/lib64/liblsan.so to /etc/ld.so.preload [ -f /etc/ld.so.preload ] && mv -v /etc/ld.so.preload /etc/ld.so.preload.orig -echo "%{libdir}/liblsan.so" > /etc/ld.so.preload +echo "liblsan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig @@ -738,7 +740,7 @@ plugins build. %prep %setup -q -n gcc-%{version} -cp %{SOURCE19} . +cp %{SOURCE20} . tar xf %{SOURCE10} ln -sf gmp-6.0.0 gmp @@ -908,6 +910,11 @@ chmod a+x %{buildroot}%{_prefix}/bin/asan_symbolize.py cp %{SOURCE17} %{buildroot} chmod 644 %{buildroot}/ASAN_OPTIONS + +%ifarch %lsan_arch +cp %{SOURCE19} %{buildroot} +chmod 644 %{buildroot}/LSAN_OPTIONS +%endif } %files @@ -1157,6 +1164,7 @@ chmod 644 %{buildroot}/ASAN_OPTIONS %ifarch %lsan_arch %files -n lsan-build-env %defattr(-,root,root,-) +/LSAN_OPTIONS %endif %files -n sanitizer-devel diff --git a/packaging/linaro-gcc.spec b/packaging/linaro-gcc.spec index 6a74463..5675485 100644 --- a/packaging/linaro-gcc.spec +++ b/packaging/linaro-gcc.spec @@ -84,7 +84,8 @@ Source15: gcc-force-options Source16: gcc-unforce-options Source17: ASAN_OPTIONS Source18: asan_symbolize.py -Source19: gcc.manifest +Source19: LSAN_OPTIONS +Source20: gcc.manifest Group: Development/Building Summary: The GNU C Compiler and Support Files License: GPL-3.0+ @@ -648,13 +649,14 @@ Scripts for LSan instrumentation # Change mode to allow all users to run gcc-force/unforce-options chmod a+w /usr/bin [ -d /emul/ ] && chmod a+w /emul/usr/bin/ && chmod a+w /emul/home/abuild/rpmbuild/BUILD/gcc-4.9.2/obj/gcc/ -/usr/bin/gcc-force-options -fsanitize=leak +/usr/bin/gcc-force-options -fsanitize=leak -fno-omit-frame-pointer -U_FORTIFY_SOURCE %preun -n lsan-force-options # Restore read-only mode chmod a-w /usr/bin [ -d /emul/ ] && chmod a-w /emul/usr/bin/ && chmod a-w /emul/home/abuild/rpmbuild/BUILD/gcc-4.9.2/obj/gcc/ /usr/bin/gcc-unforce-options +[ -d /emul/ ] && chmod a-w /emul/usr/bin/ %package -n asan-build-env Summary: Asan build environment @@ -686,7 +688,7 @@ Lsan build environment %post -n lsan-build-env # Add /usr/lib64/liblsan.so to /etc/ld.so.preload [ -f /etc/ld.so.preload ] && mv -v /etc/ld.so.preload /etc/ld.so.preload.orig -echo "%{libdir}/liblsan.so" > /etc/ld.so.preload +echo "liblsan.so" > /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && cat /etc/ld.so.preload.orig >> /etc/ld.so.preload [ -f /etc/ld.so.preload.orig ] && rm -f /etc/ld.so.preload.orig @@ -735,7 +737,7 @@ plugins build. %prep %setup -q -n gcc-%{version} -cp %{SOURCE19} . +cp %{SOURCE20} . tar xf %{SOURCE10} ln -sf gmp-6.0.0 gmp @@ -905,6 +907,11 @@ chmod a+x %{buildroot}%{_prefix}/bin/asan_symbolize.py cp %{SOURCE17} %{buildroot} chmod 644 %{buildroot}/ASAN_OPTIONS + +%ifarch %lsan_arch +cp %{SOURCE19} %{buildroot} +chmod 644 %{buildroot}/LSAN_OPTIONS +%endif } %files @@ -1154,6 +1161,7 @@ chmod 644 %{buildroot}/ASAN_OPTIONS %ifarch %lsan_arch %files -n lsan-build-env %defattr(-,root,root,-) +/LSAN_OPTIONS %endif %files -n sanitizer-devel