Message ID | 20140530134933.GZ10386@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
Thanks Jakub! Looks like there is not rush with another merge now. --kcc On Fri, May 30, 2014 at 5:49 PM, Jakub Jelinek <jakub@redhat.com> wrote: > On Fri, May 30, 2014 at 08:09:22AM -0500, Peter Bergner wrote: >> On Thu, 2014-05-29 at 14:07 -0500, Peter Bergner wrote: >> > On Wed, 2014-05-28 at 09:36 +0200, Thomas Schwinge wrote: >> > > This is being discussed in the thread at >> > > <http://gcc.gnu.org/ml/gcc-patches/2014-05/msg02031.html>. Until that >> > > has been resolved, I do agree to check in the following patch (and have >> > > successfully tested it, but cannot formally approve it for commit; thus >> > > copying the libsanitizer maintainers): >> > >> > The re-enablement patch was submitted to the llvm mailing list here: >> > >> > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140526/219249.html >> > >> > Once that is committed and merged into gcc, we can re-enable building >> > libsanitizer for powerpc*-linux. >> >> Ok, it was committed upstream as revision 209879. Kostya, can we get >> this merged into gcc trunk and powerpc*-linux re-enabled again? Thanks. > > I've cherry-picked the two upstream commits and after testing on > x86_64-linux/i686-linux committed to trunk. > > 2014-05-30 Jakub Jelinek <jakub@redhat.com> > > * sanitizer_common/sanitizer_stacktrace.cc: Cherry pick upstream > r209879. > * sanitizer_common/sanitizer_common.h: Likewise. > * asan/asan_mapping.h: Likewise. > * asan/asan_linux.cc: Likewise. > * tsan/tsan_mman.cc: Cherry pick upstream r209744. > * sanitizer_common/sanitizer_allocator.h: Likewise. > > --- libsanitizer/sanitizer_common/sanitizer_stacktrace.cc (revision 209878) > +++ libsanitizer/sanitizer_common/sanitizer_stacktrace.cc (revision 209879) > @@ -18,11 +18,13 @@ > namespace __sanitizer { > > uptr StackTrace::GetPreviousInstructionPc(uptr pc) { > -#ifdef __arm__ > +#if defined(__arm__) > // Cancel Thumb bit. > pc = pc & (~1); > -#endif > -#if defined(__sparc__) > +#elif defined(__powerpc__) || defined(__powerpc64__) > + // PCs are always 4 byte aligned. > + return pc - 4; > +#elif defined(__sparc__) > return pc - 8; > #else > return pc - 1; > --- libsanitizer/sanitizer_common/sanitizer_common.h (revision 209878) > +++ libsanitizer/sanitizer_common/sanitizer_common.h (revision 209879) > @@ -28,7 +28,11 @@ struct StackTrace; > const uptr kWordSize = SANITIZER_WORDSIZE / 8; > const uptr kWordSizeInBits = 8 * kWordSize; > > -const uptr kCacheLineSize = 64; > +#if defined(__powerpc__) || defined(__powerpc64__) > + const uptr kCacheLineSize = 128; > +#else > + const uptr kCacheLineSize = 64; > +#endif > > const uptr kMaxPathLength = 512; > > --- libsanitizer/asan/asan_mapping.h (revision 209878) > +++ libsanitizer/asan/asan_mapping.h (revision 209879) > @@ -87,6 +87,7 @@ static const u64 kDefaultShadowOffset64 > static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. > static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; > static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000; > +static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; > static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000 > static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000 > > @@ -109,6 +110,8 @@ static const u64 kFreeBSD_ShadowOffset64 > # else > # if defined(__aarch64__) > # define SHADOW_OFFSET kAArch64_ShadowOffset64 > +# elif defined(__powerpc64__) > +# define SHADOW_OFFSET kPPC64_ShadowOffset64 > # elif SANITIZER_FREEBSD > # define SHADOW_OFFSET kFreeBSD_ShadowOffset64 > # elif SANITIZER_MAC > --- libsanitizer/asan/asan_linux.cc (revision 209878) > +++ libsanitizer/asan/asan_linux.cc (revision 209879) > @@ -188,6 +188,13 @@ void GetPcSpBp(void *context, uptr *pc, > *bp = ucontext->uc_mcontext.gregs[REG_EBP]; > *sp = ucontext->uc_mcontext.gregs[REG_ESP]; > # endif > +#elif defined(__powerpc__) || defined(__powerpc64__) > + ucontext_t *ucontext = (ucontext_t*)context; > + *pc = ucontext->uc_mcontext.regs->nip; > + *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; > + // The powerpc{,64}-linux ABIs do not specify r31 as the frame > + // pointer, but GCC always uses r31 when we need a frame pointer. > + *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; > #elif defined(__sparc__) > ucontext_t *ucontext = (ucontext_t*)context; > uptr *stk_ptr; > --- libsanitizer/tsan/tsan_mman.cc (revision 209743) > +++ libsanitizer/tsan/tsan_mman.cc (revision 209744) > @@ -217,19 +217,15 @@ using namespace __tsan; > > extern "C" { > uptr __tsan_get_current_allocated_bytes() { > - u64 stats[AllocatorStatCount]; > + uptr stats[AllocatorStatCount]; > allocator()->GetStats(stats); > - u64 m = stats[AllocatorStatMalloced]; > - u64 f = stats[AllocatorStatFreed]; > - return m >= f ? m - f : 1; > + return stats[AllocatorStatAllocated]; > } > > uptr __tsan_get_heap_size() { > - u64 stats[AllocatorStatCount]; > + uptr stats[AllocatorStatCount]; > allocator()->GetStats(stats); > - u64 m = stats[AllocatorStatMmapped]; > - u64 f = stats[AllocatorStatUnmapped]; > - return m >= f ? m - f : 1; > + return stats[AllocatorStatMapped]; > } > > uptr __tsan_get_free_bytes() { > --- libsanitizer/sanitizer_common/sanitizer_allocator.h (revision 209743) > +++ libsanitizer/sanitizer_common/sanitizer_allocator.h (revision 209744) > @@ -198,14 +198,12 @@ template<class SizeClassAllocator> struc > > // Memory allocator statistics > enum AllocatorStat { > - AllocatorStatMalloced, > - AllocatorStatFreed, > - AllocatorStatMmapped, > - AllocatorStatUnmapped, > + AllocatorStatAllocated, > + AllocatorStatMapped, > AllocatorStatCount > }; > > -typedef u64 AllocatorStatCounters[AllocatorStatCount]; > +typedef uptr AllocatorStatCounters[AllocatorStatCount]; > > // Per-thread stats, live in per-thread cache. > class AllocatorStats { > @@ -214,16 +212,21 @@ class AllocatorStats { > internal_memset(this, 0, sizeof(*this)); > } > > - void Add(AllocatorStat i, u64 v) { > + void Add(AllocatorStat i, uptr v) { > v += atomic_load(&stats_[i], memory_order_relaxed); > atomic_store(&stats_[i], v, memory_order_relaxed); > } > > - void Set(AllocatorStat i, u64 v) { > + void Sub(AllocatorStat i, uptr v) { > + v = atomic_load(&stats_[i], memory_order_relaxed) - v; > atomic_store(&stats_[i], v, memory_order_relaxed); > } > > - u64 Get(AllocatorStat i) const { > + void Set(AllocatorStat i, uptr v) { > + atomic_store(&stats_[i], v, memory_order_relaxed); > + } > + > + uptr Get(AllocatorStat i) const { > return atomic_load(&stats_[i], memory_order_relaxed); > } > > @@ -231,7 +234,7 @@ class AllocatorStats { > friend class AllocatorGlobalStats; > AllocatorStats *next_; > AllocatorStats *prev_; > - atomic_uint64_t stats_[AllocatorStatCount]; > + atomic_uintptr_t stats_[AllocatorStatCount]; > }; > > // Global stats, used for aggregation and querying. > @@ -260,7 +263,7 @@ class AllocatorGlobalStats : public Allo > } > > void Get(AllocatorStatCounters s) const { > - internal_memset(s, 0, AllocatorStatCount * sizeof(u64)); > + internal_memset(s, 0, AllocatorStatCount * sizeof(uptr)); > SpinMutexLock l(&mu_); > const AllocatorStats *stats = this; > for (;;) { > @@ -270,6 +273,9 @@ class AllocatorGlobalStats : public Allo > if (stats == this) > break; > } > + // All stats must be positive. > + for (int i = 0; i < AllocatorStatCount; i++) > + s[i] = ((sptr)s[i]) > 0 ? s[i] : 1; > } > > private: > @@ -522,7 +528,7 @@ class SizeClassAllocator64 { > map_size += kUserMapSize; > CHECK_GE(region->mapped_user + map_size, end_idx); > MapWithCallback(region_beg + region->mapped_user, map_size); > - stat->Add(AllocatorStatMmapped, map_size); > + stat->Add(AllocatorStatMapped, map_size); > region->mapped_user += map_size; > } > uptr total_count = (region->mapped_user - beg_idx - size) > @@ -841,7 +847,7 @@ class SizeClassAllocator32 { > uptr res = reinterpret_cast<uptr>(MmapAlignedOrDie(kRegionSize, kRegionSize, > "SizeClassAllocator32")); > MapUnmapCallback().OnMap(res, kRegionSize); > - stat->Add(AllocatorStatMmapped, kRegionSize); > + stat->Add(AllocatorStatMapped, kRegionSize); > CHECK_EQ(0U, (res & (kRegionSize - 1))); > possible_regions.set(ComputeRegionId(res), static_cast<u8>(class_id)); > return res; > @@ -907,7 +913,7 @@ struct SizeClassAllocatorLocalCache { > void *Allocate(SizeClassAllocator *allocator, uptr class_id) { > CHECK_NE(class_id, 0UL); > CHECK_LT(class_id, kNumClasses); > - stats_.Add(AllocatorStatMalloced, SizeClassMap::Size(class_id)); > + stats_.Add(AllocatorStatAllocated, SizeClassMap::Size(class_id)); > PerClass *c = &per_class_[class_id]; > if (UNLIKELY(c->count == 0)) > Refill(allocator, class_id); > @@ -922,7 +928,7 @@ struct SizeClassAllocatorLocalCache { > // If the first allocator call on a new thread is a deallocation, then > // max_count will be zero, leading to check failure. > InitCache(); > - stats_.Add(AllocatorStatFreed, SizeClassMap::Size(class_id)); > + stats_.Sub(AllocatorStatAllocated, SizeClassMap::Size(class_id)); > PerClass *c = &per_class_[class_id]; > CHECK_NE(c->max_count, 0UL); > if (UNLIKELY(c->count == c->max_count)) > @@ -1033,8 +1039,8 @@ class LargeMmapAllocator { > stats.currently_allocated += map_size; > stats.max_allocated = Max(stats.max_allocated, stats.currently_allocated); > stats.by_size_log[size_log]++; > - stat->Add(AllocatorStatMalloced, map_size); > - stat->Add(AllocatorStatMmapped, map_size); > + stat->Add(AllocatorStatAllocated, map_size); > + stat->Add(AllocatorStatMapped, map_size); > } > return reinterpret_cast<void*>(res); > } > @@ -1052,8 +1058,8 @@ class LargeMmapAllocator { > chunks_sorted_ = false; > stats.n_frees++; > stats.currently_allocated -= h->map_size; > - stat->Add(AllocatorStatFreed, h->map_size); > - stat->Add(AllocatorStatUnmapped, h->map_size); > + stat->Sub(AllocatorStatAllocated, h->map_size); > + stat->Sub(AllocatorStatMapped, h->map_size); > } > MapUnmapCallback().OnUnmap(h->map_beg, h->map_size); > UnmapOrDie(reinterpret_cast<void*>(h->map_beg), h->map_size); > > > Jakub
On Fri, 2014-05-30 at 15:49 +0200, Jakub Jelinek wrote: > On Fri, May 30, 2014 at 08:09:22AM -0500, Peter Bergner wrote: > > On Thu, 2014-05-29 at 14:07 -0500, Peter Bergner wrote: > > > On Wed, 2014-05-28 at 09:36 +0200, Thomas Schwinge wrote: > > > > This is being discussed in the thread at > > > > <http://gcc.gnu.org/ml/gcc-patches/2014-05/msg02031.html>. Until that > > > > has been resolved, I do agree to check in the following patch (and have > > > > successfully tested it, but cannot formally approve it for commit; thus > > > > copying the libsanitizer maintainers): > > > > > > The re-enablement patch was submitted to the llvm mailing list here: > > > > > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140526/219249.html > > > > > > Once that is committed and merged into gcc, we can re-enable building > > > libsanitizer for powerpc*-linux. > > > > Ok, it was committed upstream as revision 209879. Kostya, can we get > > this merged into gcc trunk and powerpc*-linux re-enabled again? Thanks. > > I've cherry-picked the two upstream commits and after testing on > x86_64-linux/i686-linux committed to trunk. Great, thanks! I bootstrapped and ran the asan testsuite. I'm now seeing lots of FAILs due to: ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD. ...which Paolo mentioned in the other thread that he is hitting this too. There was some discussion on what to do, but has there been a decision on how to fix this yet? Or is it fixed upstream and we just need to merge that fix too? Peter
On Sat, May 31, 2014 at 11:53 PM, Peter Bergner <bergner@vnet.ibm.com> wrote: > On Fri, 2014-05-30 at 15:49 +0200, Jakub Jelinek wrote: >> On Fri, May 30, 2014 at 08:09:22AM -0500, Peter Bergner wrote: >> > On Thu, 2014-05-29 at 14:07 -0500, Peter Bergner wrote: >> > > On Wed, 2014-05-28 at 09:36 +0200, Thomas Schwinge wrote: >> > > > This is being discussed in the thread at >> > > > <http://gcc.gnu.org/ml/gcc-patches/2014-05/msg02031.html>. Until that >> > > > has been resolved, I do agree to check in the following patch (and have >> > > > successfully tested it, but cannot formally approve it for commit; thus >> > > > copying the libsanitizer maintainers): >> > > >> > > The re-enablement patch was submitted to the llvm mailing list here: >> > > >> > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140526/219249.html >> > > >> > > Once that is committed and merged into gcc, we can re-enable building >> > > libsanitizer for powerpc*-linux. >> > >> > Ok, it was committed upstream as revision 209879. Kostya, can we get >> > this merged into gcc trunk and powerpc*-linux re-enabled again? Thanks. >> >> I've cherry-picked the two upstream commits and after testing on >> x86_64-linux/i686-linux committed to trunk. > > Great, thanks! I bootstrapped and ran the asan testsuite. I'm now seeing > lots of FAILs due to: > > ASan runtime does not come first in initial library list; you should either > link runtime to your application or manually preload it with LD_PRELOAD. > > ...which Paolo mentioned in the other thread that he is hitting this too. > There was some discussion on what to do, but has there been a decision on > how to fix this yet? Or is it fixed upstream and we just need to merge > that fix too? Yuri needs to send the patch to llvm-commits. > > Peter > >
>> There was some discussion on what to do, but has there been a decision on >> how to fix this yet? Or is it fixed upstream and we just need to merge >> that fix too? > Yuri needs to send the patch to llvm-commits. I think I already did that: D3911 -Y
Committed as r210012, please don't forget to add llvm-commits to CC next time (I did not see the message) Thanks! On Mon, Jun 2, 2014 at 9:57 AM, Yury Gribov <y.gribov@samsung.com> wrote: >>> There was some discussion on what to do, but has there been a decision on >>> how to fix this yet? Or is it fixed upstream and we just need to merge >>> that fix too? >> >> Yuri needs to send the patch to llvm-commits. > > > I think I already did that: D3911 > > -Y
On Mon, 2014-06-02 at 14:48 +0400, Konstantin Serebryany wrote: > Committed as r210012, please don't forget to add llvm-commits to CC > next time (I did not see the message) > Thanks! I took that patch and applied it to the gcc sources, but I still see the error on ppc: [bergner@makalu-lp1 asan]$ /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/xgcc -B/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/ /home/bergner/gcc/gcc-fsf-mainline-asan/gcc/testsuite/c-c++-common/asan/asan-interface-1.c -B/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/ -B/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/ -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs -fsanitize=address -g -I/home/bergner/gcc/gcc-fsf-mainline-asan/gcc/testsuite/../../libsanitizer/include -fno-diagnostics-show-caret -fdiagnostics-color=never -O0 -lm -m32 -o ./asan-interface-1.exe [bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ./asan-interface-1.exe ==36082==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD. [bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe linux-vdso32.so.1 => (0x00100000) libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000) libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000) libc.so.6 => /lib/power8/libc.so.6 (0x0f740000) /lib/ld.so.1 (0x206b0000) libpthread.so.0 => /lib/power8/libpthread.so.0 (0x0f6f0000) libdl.so.2 => /lib/libdl.so.2 (0x0f6b0000) libstdc++.so.6 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libstdc++-v3/src/.libs/libstdc++.so.6 (0x0f520000) libgcc_s.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32/libgcc_s.so.1 (0x0f4c0000) If I explicitly add a -lasan before the -lm on the compile, then everything works fine. Is this a test case error for not linking -lasan before -lm or ??? Peter
> I took that patch and applied it to the gcc sources, > but I still see the error on ppc: >... > [bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe > linux-vdso32.so.1 => (0x00100000) > libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000) > libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000) Now check indeed seems to be useful: libasan should be the first library in the list when -fsanitize=address flag is present. Are compiler specs for Power somehow special? -Y
On Tue, Jun 03, 2014 at 10:19:48AM +0400, Yury Gribov wrote: > >I took that patch and applied it to the gcc sources, > >but I still see the error on ppc: > >... > >[bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe > > linux-vdso32.so.1 => (0x00100000) > > libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000) > > libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000) > > Now check indeed seems to be useful: libasan should be the first > library in the list when -fsanitize=address flag is present. Are > compiler specs for Power somehow special? -fsanitize=address should insert -lasan quite early on the linker command line, please try to cut'n'paste the command line from testsuite/g++/g++.log and add -v to see what is passed to the linker. Perhaps the linker reorders the libraries? Or do you have LD_PRELOAD? Jakub
On Tue, 2014-06-03 at 08:41 +0200, Jakub Jelinek wrote: > On Tue, Jun 03, 2014 at 10:19:48AM +0400, Yury Gribov wrote: > > >I took that patch and applied it to the gcc sources, > > >but I still see the error on ppc: > > >... > > >[bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe > > > linux-vdso32.so.1 => (0x00100000) > > > libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000) > > > libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000) > > > > Now check indeed seems to be useful: libasan should be the first > > library in the list when -fsanitize=address flag is present. Are > > compiler specs for Power somehow special? > > -fsanitize=address should insert -lasan quite early on the linker command > line, please try to cut'n'paste the command line from testsuite/g++/g++.log > and add -v to see what is passed to the linker. > Perhaps the linker reorders the libraries? > Or do you have LD_PRELOAD? No LD_PRELOAD. It adds -lasan "early", but after the libraries and object files that are explicitly added to the linker command. Since -lm is explicitly added to the linker command, the implicitly added -lasan comes after. The -v command is below. Peter /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/collect2 -plugin /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/liblto_plugin.so -plugin-opt=/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/lto-wrapper -plugin-opt=-fresolution=/tmp/cckyoSrJ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -V -m elf32ppclinux -dynamic-linker /lib/ld.so.1 -o ./asan-interface-1.exe /lib/../lib/crt1.o /lib/../lib/crti.o /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32/crtbegin.o -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32 -L/lib/../lib -L/usr/lib/../lib -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer -L/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan /tmp/ccUTAlke.o -lm -lasan -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32/crtend.o /lib/../lib/crtn.o
> It adds -lasan "early", but after the libraries and > object files that are explicitly added to the linker command. > Since -lm is explicitly added to the linker command, the implicitly > added -lasan comes after. The -v command is below. Hm, -lasan manages to override user-specified -lm on gcc trunk for x64: $ /tmp/gcc-bootstrap-and-regtest/build-orig/gcc/xgcc -B/tmp/gcc-bootstrap-and-regtest/build-orig/gcc/ /home/ygribov/src/gcc-master/gcc/testsuite/c-c++-common/asan/asan-interface-1.c -B/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/ -B/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan/ -L/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan/.libs -fsanitize=address -g -I/home/ygribov/src/gcc-master/gcc/testsuite/../../libsanitizer/include -fno-diagnostics-show-caret -fdiagnostics-color=never -O0 -lm -o ./asan-interface-1.exe -v ... /tmp/gcc-bootstrap-and-regtest/build-orig/gcc/collect2 -plugin /tmp/gcc-bootstrap-and-regtest/build-orig/gcc/liblto_plugin.so -plugin-opt=/tmp/gcc-bootstrap-and-regtest/build-orig/gcc/lto-wrapper -plugin-opt=-fresolution=/tmp/ccZD4gPg.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o ./asan-interface-1.exe /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /tmp/gcc-bootstrap-and-regtest/build-orig/gcc/crtbegin.o -L/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan/.libs -L/tmp/gcc-bootstrap-and-regtest/build-orig/gcc -L/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer -L/tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu /tmp/gcc-bootstrap-and-regtest/build-orig/x86_64-unknown-linux-gnu/./libsanitizer/asan/libasan_preinit.o -lasan /tmp/ccgt1Kd9.o -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /tmp/gcc-bootstrap-and-regtest/build-orig/gcc/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o -Y
On Tue, Jun 03, 2014 at 08:06:41AM -0500, Peter Bergner wrote: > On Tue, 2014-06-03 at 08:41 +0200, Jakub Jelinek wrote: > > On Tue, Jun 03, 2014 at 10:19:48AM +0400, Yury Gribov wrote: > > > >I took that patch and applied it to the gcc sources, > > > >but I still see the error on ppc: > > > >... > > > >[bergner@makalu-lp1 asan]$ LD_LIBRARY_PATH=:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs::/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/gcc/32:/home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs: ldd ./asan-interface-1.exe > > > > linux-vdso32.so.1 => (0x00100000) > > > > libm.so.6 => /lib/power8/libm.so.6 (0x0ff00000) > > > > libasan.so.1 => /home/bergner/gcc/build/gcc-fsf-mainline-asan-debug-3/powerpc64-linux/32/libsanitizer/asan/.libs/libasan.so.1 (0x0f930000) > > > > > > Now check indeed seems to be useful: libasan should be the first > > > library in the list when -fsanitize=address flag is present. Are > > > compiler specs for Power somehow special? > > > > -fsanitize=address should insert -lasan quite early on the linker command > > line, please try to cut'n'paste the command line from testsuite/g++/g++.log > > and add -v to see what is passed to the linker. > > Perhaps the linker reorders the libraries? > > Or do you have LD_PRELOAD? > > No LD_PRELOAD. It adds -lasan "early", but after the libraries and > object files that are explicitly added to the linker command. > Since -lm is explicitly added to the linker command, the implicitly > added -lasan comes after. The -v command is below. Ah, that is a powerpc*-linux* bug. All other linux targets include config/gnu-user.h header, perhaps early and override it, but rs6000* seems to be the only? exception that does not. So, either you need to include that header and perhaps tweak afterwards, or duplicate the asan/tsan related stuff in there and make sure to keep it up to date. Jakub
On Tue, 2014-06-03 at 15:21 +0200, Jakub Jelinek wrote: > On Tue, Jun 03, 2014 at 08:06:41AM -0500, Peter Bergner wrote: > > No LD_PRELOAD. It adds -lasan "early", but after the libraries and > > object files that are explicitly added to the linker command. > > Since -lm is explicitly added to the linker command, the implicitly > > added -lasan comes after. The -v command is below. > > Ah, that is a powerpc*-linux* bug. All other linux targets include > config/gnu-user.h header, perhaps early and override it, but rs6000* > seems to be the only? exception that does not. > > So, either you need to include that header and perhaps tweak afterwards, > or duplicate the asan/tsan related stuff in there and make sure to keep it > up to date. I'll try adding the include. Thanks for pointing that out! Peter
--- libsanitizer/sanitizer_common/sanitizer_stacktrace.cc (revision 209878) +++ libsanitizer/sanitizer_common/sanitizer_stacktrace.cc (revision 209879) @@ -18,11 +18,13 @@ namespace __sanitizer { uptr StackTrace::GetPreviousInstructionPc(uptr pc) { -#ifdef __arm__ +#if defined(__arm__) // Cancel Thumb bit. pc = pc & (~1); -#endif -#if defined(__sparc__) +#elif defined(__powerpc__) || defined(__powerpc64__) + // PCs are always 4 byte aligned. + return pc - 4; +#elif defined(__sparc__) return pc - 8; #else return pc - 1; --- libsanitizer/sanitizer_common/sanitizer_common.h (revision 209878) +++ libsanitizer/sanitizer_common/sanitizer_common.h (revision 209879) @@ -28,7 +28,11 @@ struct StackTrace; const uptr kWordSize = SANITIZER_WORDSIZE / 8; const uptr kWordSizeInBits = 8 * kWordSize; -const uptr kCacheLineSize = 64; +#if defined(__powerpc__) || defined(__powerpc64__) + const uptr kCacheLineSize = 128; +#else + const uptr kCacheLineSize = 64; +#endif const uptr kMaxPathLength = 512; --- libsanitizer/asan/asan_mapping.h (revision 209878) +++ libsanitizer/asan/asan_mapping.h (revision 209879) @@ -87,6 +87,7 @@ static const u64 kDefaultShadowOffset64 static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000; +static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000 static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000 @@ -109,6 +110,8 @@ static const u64 kFreeBSD_ShadowOffset64 # else # if defined(__aarch64__) # define SHADOW_OFFSET kAArch64_ShadowOffset64 +# elif defined(__powerpc64__) +# define SHADOW_OFFSET kPPC64_ShadowOffset64 # elif SANITIZER_FREEBSD # define SHADOW_OFFSET kFreeBSD_ShadowOffset64 # elif SANITIZER_MAC --- libsanitizer/asan/asan_linux.cc (revision 209878) +++ libsanitizer/asan/asan_linux.cc (revision 209879) @@ -188,6 +188,13 @@ void GetPcSpBp(void *context, uptr *pc, *bp = ucontext->uc_mcontext.gregs[REG_EBP]; *sp = ucontext->uc_mcontext.gregs[REG_ESP]; # endif +#elif defined(__powerpc__) || defined(__powerpc64__) + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.regs->nip; + *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; + // The powerpc{,64}-linux ABIs do not specify r31 as the frame + // pointer, but GCC always uses r31 when we need a frame pointer. + *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; #elif defined(__sparc__) ucontext_t *ucontext = (ucontext_t*)context; uptr *stk_ptr; --- libsanitizer/tsan/tsan_mman.cc (revision 209743) +++ libsanitizer/tsan/tsan_mman.cc (revision 209744) @@ -217,19 +217,15 @@ using namespace __tsan; extern "C" { uptr __tsan_get_current_allocated_bytes() { - u64 stats[AllocatorStatCount]; + uptr stats[AllocatorStatCount]; allocator()->GetStats(stats); - u64 m = stats[AllocatorStatMalloced]; - u64 f = stats[AllocatorStatFreed]; - return m >= f ? m - f : 1; + return stats[AllocatorStatAllocated]; } uptr __tsan_get_heap_size() { - u64 stats[AllocatorStatCount]; + uptr stats[AllocatorStatCount]; allocator()->GetStats(stats); - u64 m = stats[AllocatorStatMmapped]; - u64 f = stats[AllocatorStatUnmapped]; - return m >= f ? m - f : 1; + return stats[AllocatorStatMapped]; } uptr __tsan_get_free_bytes() { --- libsanitizer/sanitizer_common/sanitizer_allocator.h (revision 209743) +++ libsanitizer/sanitizer_common/sanitizer_allocator.h (revision 209744) @@ -198,14 +198,12 @@ template<class SizeClassAllocator> struc // Memory allocator statistics enum AllocatorStat { - AllocatorStatMalloced, - AllocatorStatFreed, - AllocatorStatMmapped, - AllocatorStatUnmapped, + AllocatorStatAllocated, + AllocatorStatMapped, AllocatorStatCount }; -typedef u64 AllocatorStatCounters[AllocatorStatCount]; +typedef uptr AllocatorStatCounters[AllocatorStatCount]; // Per-thread stats, live in per-thread cache. class AllocatorStats { @@ -214,16 +212,21 @@ class AllocatorStats { internal_memset(this, 0, sizeof(*this)); } - void Add(AllocatorStat i, u64 v) { + void Add(AllocatorStat i, uptr v) { v += atomic_load(&stats_[i], memory_order_relaxed); atomic_store(&stats_[i], v, memory_order_relaxed); } - void Set(AllocatorStat i, u64 v) { + void Sub(AllocatorStat i, uptr v) { + v = atomic_load(&stats_[i], memory_order_relaxed) - v; atomic_store(&stats_[i], v, memory_order_relaxed); } - u64 Get(AllocatorStat i) const { + void Set(AllocatorStat i, uptr v) { + atomic_store(&stats_[i], v, memory_order_relaxed); + } + + uptr Get(AllocatorStat i) const { return atomic_load(&stats_[i], memory_order_relaxed); } @@ -231,7 +234,7 @@ class AllocatorStats { friend class AllocatorGlobalStats; AllocatorStats *next_; AllocatorStats *prev_; - atomic_uint64_t stats_[AllocatorStatCount]; + atomic_uintptr_t stats_[AllocatorStatCount]; }; // Global stats, used for aggregation and querying. @@ -260,7 +263,7 @@ class AllocatorGlobalStats : public Allo } void Get(AllocatorStatCounters s) const { - internal_memset(s, 0, AllocatorStatCount * sizeof(u64)); + internal_memset(s, 0, AllocatorStatCount * sizeof(uptr)); SpinMutexLock l(&mu_); const AllocatorStats *stats = this; for (;;) { @@ -270,6 +273,9 @@ class AllocatorGlobalStats : public Allo if (stats == this) break; } + // All stats must be positive. + for (int i = 0; i < AllocatorStatCount; i++) + s[i] = ((sptr)s[i]) > 0 ? s[i] : 1; } private: @@ -522,7 +528,7 @@ class SizeClassAllocator64 { map_size += kUserMapSize; CHECK_GE(region->mapped_user + map_size, end_idx); MapWithCallback(region_beg + region->mapped_user, map_size); - stat->Add(AllocatorStatMmapped, map_size); + stat->Add(AllocatorStatMapped, map_size); region->mapped_user += map_size; } uptr total_count = (region->mapped_user - beg_idx - size) @@ -841,7 +847,7 @@ class SizeClassAllocator32 { uptr res = reinterpret_cast<uptr>(MmapAlignedOrDie(kRegionSize, kRegionSize, "SizeClassAllocator32")); MapUnmapCallback().OnMap(res, kRegionSize); - stat->Add(AllocatorStatMmapped, kRegionSize); + stat->Add(AllocatorStatMapped, kRegionSize); CHECK_EQ(0U, (res & (kRegionSize - 1))); possible_regions.set(ComputeRegionId(res), static_cast<u8>(class_id)); return res; @@ -907,7 +913,7 @@ struct SizeClassAllocatorLocalCache { void *Allocate(SizeClassAllocator *allocator, uptr class_id) { CHECK_NE(class_id, 0UL); CHECK_LT(class_id, kNumClasses); - stats_.Add(AllocatorStatMalloced, SizeClassMap::Size(class_id)); + stats_.Add(AllocatorStatAllocated, SizeClassMap::Size(class_id)); PerClass *c = &per_class_[class_id]; if (UNLIKELY(c->count == 0)) Refill(allocator, class_id); @@ -922,7 +928,7 @@ struct SizeClassAllocatorLocalCache { // If the first allocator call on a new thread is a deallocation, then // max_count will be zero, leading to check failure. InitCache(); - stats_.Add(AllocatorStatFreed, SizeClassMap::Size(class_id)); + stats_.Sub(AllocatorStatAllocated, SizeClassMap::Size(class_id)); PerClass *c = &per_class_[class_id]; CHECK_NE(c->max_count, 0UL); if (UNLIKELY(c->count == c->max_count)) @@ -1033,8 +1039,8 @@ class LargeMmapAllocator { stats.currently_allocated += map_size; stats.max_allocated = Max(stats.max_allocated, stats.currently_allocated); stats.by_size_log[size_log]++; - stat->Add(AllocatorStatMalloced, map_size); - stat->Add(AllocatorStatMmapped, map_size); + stat->Add(AllocatorStatAllocated, map_size); + stat->Add(AllocatorStatMapped, map_size); } return reinterpret_cast<void*>(res); } @@ -1052,8 +1058,8 @@ class LargeMmapAllocator { chunks_sorted_ = false; stats.n_frees++; stats.currently_allocated -= h->map_size; - stat->Add(AllocatorStatFreed, h->map_size); - stat->Add(AllocatorStatUnmapped, h->map_size); + stat->Sub(AllocatorStatAllocated, h->map_size); + stat->Sub(AllocatorStatMapped, h->map_size); } MapUnmapCallback().OnUnmap(h->map_beg, h->map_size); UnmapOrDie(reinterpret_cast<void*>(h->map_beg), h->map_size);