Commit Graph

838 Commits

Author SHA1 Message Date
Aliaksey Kandratsenka
42dde1b883 heap-checker_unittest: run thread-unsafe libc calls less unsafely
Comment there says race is fine, bit it isn't. Crashes under
musl. Lets not crash.
2023-07-22 00:08:38 -04:00
Aliaksey Kandratsenka
8be84e4a5c drop old mmap hooks and introduce internal & simpler mmap_hook.h
Previous implementation wasn't entirely safe w.r.t. 32-bit off_t
systems. Specifically around mmap replacement hook. Also, API was a
lot more general and broad than we actually need.

Sadly, old mmap hooks API was shipped with our public headers. But
thankfully it appears to be unused externally (checked via github
search). So we keep this old API and ABI for the sake of formal API
and ABI compatibility. But this old API is now empty and always
fails (some OS/hardware combinations didn't have functional
implementations of those hooks anyways).

New API is 64-bit clean and only provides us with what we need. Namely
being able to react to virtual address space mapping changes for
logging, heap profiling and heap leak checker. I.e. no pre hooks or
mmap-replacement hooks. We also explicitly not ship this API
externally to give us freedom to change it.

New code is also hopefully tidier and slightly more portable. At least
there are fewer arch-specific ifdef-s.

Another somewhat notable change is, since mmap hook isn't needed in
"minimal" configuration, we now don't override system's
mmap/munmap/etc functions in this configuration. No big deal, but it
reduces risk of damage if we somehow mess those up. I.e. musl's mmap
does few things that our mmap replacement doesn't, such as very fancy
vm_lock thingy. Which doesn't look critical, but is good thing for us
not to interfere with when not necessary.

Fixes issue #1406 and issue #1407. Lets also mention issue #1010 which
is somewhat relevant.
2023-07-21 16:13:19 -04:00
Aliaksey Kandratsenka
6b691cc019 drop patching virtual alloc fns on windows
It wasn't implemented exactly right and, most importantly, there is
nothing on windows that uses those (now dead) mmap hooks.
2023-07-21 14:32:48 -04:00
Aliaksey Kandratsenka
fecaf37ae4 drop DevMemSysAllocator
It was never useful for anything.
2023-07-21 14:32:37 -04:00
Aliaksey Kandratsenka
e53ec241b6 unbreak __sbrk detection on cmake 2023-07-21 14:32:37 -04:00
Aliaksey Kandratsenka
d4f3362035 add missing .gitignore for safe_strerror_test.exe 2023-07-21 14:32:37 -04:00
Aliaksey Kandratsenka
e0f4c0e6fb manually inline MapObjectToSpan into ReleaseToSpans
It was originally separated into own function due to some (now
obsolete) compiler optimization bug. We stopped worked around that bug
few commits ago. But as github user plopresti rightfully pointed
out (much, much thanks!), we lost `static' on that function. But since
it is trivial function and used exactly once, it is best to simply
inline it's 2 lines of code back instead of returning static.

Previous commit was: 68b442714a
2023-07-17 15:56:19 -04:00
Aliaksey Kandratsenka
46d3315ad7 amputate maybe_threads
This facility allowed us to build tcmalloc without linking in actual
-lpthread. Via weak symbols we checked at runtime if pthread functions
are available and if not, special single-threaded stubs were used
instead. Not always brining in pthread dependency helped performance
of some programs or libraries which depended at runtime on whether
threads are linked or not. Most notable of those are libstdc++ which
uses non-atomic refcounting on single threaded programs.

But such optional dependency on pthreads caused complications for
nearly no benefit. One trouble was reported in github issue #1110.

This days glibc/libstdc++ combo actually depends on
sys/single_threaded.h facility. So bringing pthread at runtime is
fine. Also modern glibc ships pthread symbols inside libc anyways and
libpthread is empty. I also found that for whatever reason on BSDs and
osx we already pulled in proper pthreads too.

So we loose nothing and we get issue #1110 fixed. And we simplify
everything.
2023-07-14 03:07:16 -04:00
Aliaksey Kandratsenka
3cd265b05a replace pthread_once usages with simple spinlock-backed flag
Our perftools_pthread_once implementation has some ifdefs and what
not. I.e. some OSes have complications around early usage and windows
is windows. But in fact we can implement trivial spinlock-supported
implementation and depend on nothing.

Update issue #1110
2023-07-14 03:07:16 -04:00
Aliaksey Kandratsenka
215b2d939a drop disabled windows-specific spinlock code 2023-07-14 02:31:17 -04:00
Aliaksey Kandratsenka
37fd4adab4 use regular off_t on 64-bit linuxes
off64_t is legacy of the past.

Update github issue #1407
2023-07-13 22:06:12 -04:00
Gabriel Marin
4a923a6b36 tcmalloc: enable large object pointer offset check
Original CL: https://chromiumcodereview.appspot.com/10391178

  1. Enable large object pointer offset check in release build.
  Following code will now cause a check error:
  char* p = reinterpret_cast<char*>(malloc(kMaxSize + 1));
  free(p + 1);

  2. Remove a duplicated error reporting function "DieFromBadFreePointer",
  can use "InvalidGetAllocatedSize".

Reviewed-on: https://chromium-review.googlesource.com/1184335
[alkondratenko@gmail.com] removed some unrelated formatting changes
Signed-off-by: Aliaksey Kandratsenka <alkondratenko@gmail.com>
2023-07-13 19:41:21 -04:00
Aliaksey Kandratsenka
4b3fc02082 fix clang barking at debugallocator's magic2_ field
It barks because we access the field in a special way through address
computation (see magic2_addr), so it is indeed not accessed
directly. To emphasize that it comes directly after size2_ we simply
converted size2 and magic2_ into explicit array size_and_magic2_.
2023-07-13 19:21:38 -04:00
Aliaksey Kandratsenka
c29e3059dd mark CheckCachedSizeClass as used
It is only used from inside ASSERT and clang doesn't like it being
declared but unused when NDEBUG is set.
2023-07-13 19:21:30 -04:00
Aliaksey Kandratsenka
f7c6835fac drop unused linuxthreads.cc:local_itoa function 2023-07-13 18:58:55 -04:00
Aliaksey Kandratsenka
5a3a324459 try to avoid certain warnings in tests
Our tests do explicitly trigger certain "bad" cases. And compilers are
getting increasingly smarter, so they start giving us warnings. People
dislike warnings, so lets try to disable them specifically for unit
tests.

Refers to issue #1401
2023-07-13 18:58:42 -04:00
Aliaksey Kandratsenka
e63d2f855d avoid semi-bogus use-after-free warning
In heap checker we actually use test_str address after deletion, to
verify at runtime that heap checker is indeed tracking deletions. But
gcc barks. So lets hide allocation from it by calling
tc_newarray/tc_deletearray.

Refers to #1401
2023-07-13 18:17:39 -04:00
Aliaksey Kandratsenka
9d46f1e890 exercise ASSERTs as part of pagemap_unittest
This fixes couple gcc warnings (array bounds) when accessing page map
radix tree.

Refers to #1401
2023-07-13 18:11:35 -04:00
Aliaksey Kandratsenka
d2bacb8e36 help compiler see that CHECK_CONDITION failures are fatal
Some compiler warnings are caused by this lack of information to
compiler.

Refers to #1401
2023-07-13 18:11:35 -04:00
Aliaksey Kandratsenka
2ffa4e0841 unbreak static initialization of initial malloc hooks
g++ 13 somehow considers reinterpret_cast<uintptr_t>(InitialNewHook)
as non-constexpr. It then generates runtime constructor for malloc
hooks, which run too late. That broke heap checker and heap profiler.

We fix by making array of hooks inside malloc to have proper function
pointer type, which lets us avoid reinterpret_cast which makes
construction compile-time again.
2023-07-13 16:07:51 -04:00
Aliaksey Kandratsenka
55d559f7c9 fix flakiness of profile-handler_unittest
When checking if timer is enabled, we should look at
it_interval.
2023-07-13 16:04:14 -04:00
Aliaksey Kandratsenka
5ba98e397c when CHECK_OP fails print filename and line number 2023-07-13 16:03:43 -04:00
Aliaksey Kandratsenka
9d781627bb avoid calling memory allocator under profile handler signal_lock_
If we don't avoid there is possibility of deadlock. Like this:

*) thread A runs malloc and happens to have some lock(s) there. It
gets profiling signal.

*) thread B runs ProfileHandler::UnregisterCallback or similar and has
both control_lock_ and signal_lock_.

*) thread B calls memory allocator (it used to delete token under
lock) and hits the malloc lock, so waits

*) thread A that has malloc lock wants to get signal_lock_ and waits
too.

Correct behavior is since we grab signal_lock_ from pretty much
anywhere as part of signal handler, it then implies transitively that
anything that grabs that lock cannot call into anything that grabs any
other lock (e.g. including malloc). I.e. signal_lock_ "nests" under
every other lock in the program.

So we refector the code some. When removing callbacks we simply copy
entire list with right token removed. Then grab signal_lock_ and only
swap copy with old callback list. Then signal_lock_ lock is released
and all the memory freeing operations are performed.

When adding callback we utilize splice to also avoid anything "heavy"
under signal_lock_.

And as part of that change we're now able to have UpdateTimer method
only needing control_lock_ instead of signal_lock_.

We add somewhat elaborate unit test that was able to catch the issue
without fix and now works fine.

Closes github issue #412
2023-07-10 02:29:28 -04:00
Aliaksey Kandratsenka
c44e44cecb prevent potential corruption of errno in thread lister
See
https://github.com/gperftools/gperftools/issues/500#issuecomment-133814659
for explanations. We of course evolved quite a bit since that comment,
but general issue still applies.
2023-07-10 00:22:12 -04:00
Aliaksey Kandratsenka
2b5743ffa6 amputate tcmalloc unittest trylock counting
We had this logic to ensure that TesterThread succeeds at least 50% of
times grabbing passed objects lock, apparently to ensure that multiple
threads actually participate. But this check occasionally flakes. It
is totally possible that lock owner gets preempted while holding lock
and other threads accumulate gazillion of failed trylocks. So while it
is nice to test this somehow, flakes are bad enough, so we drop this
test.
2023-07-09 18:05:01 -04:00
Chris Cambly
2d70ea9ad2 initial batch of changes to enable AIX in 32-bit and 64-bit
- Some small automake changes. Add libc++ for AIX instead of libstdc++
- Add the interface changes for AIX:User-defined malloc replacement
- Add code to avoid use of pthreads library prior to its initialization
- Some small changes to the unittest case
- Update INSTALL for AIX

[alkondratenko@gmail.com]: lower-case/de-trailing-dot for commit subject line
[alkondratenko@gmail.com]: rebase
[alkondratenko@gmail.com]: amputate unused AM_CONDITIONAL for AIX
[alkondratenko@gmail.com]: explicitly mention libc_override_aix.h in Makefile.am
2023-07-09 16:52:20 -04:00
Aliaksey Kandratsenka
26927d1333 clean up unused link dependencies for malloc_extension_c_test
We used to explicitly link to libstdc++, libm and even libpthread, but
this should be handled by libtool since those are dependencies of
libtcmalloc_minimal. What also helps is we now build everything with
C++ compiler, not C. So libstdc++ or (libc++) dependency doesn't need
to be added at all, even if libtool for some reason fails to handle
it.
2023-07-09 16:11:51 -04:00
zhangyiru
ea47513a8f avoid memleak exceed int range when using heap-checker
[alkondratenko@gmail.com] format size_t with %zu
Signed-off-by: Aliaksey Kandratsenka <alkondratenko@gmail.com>
2023-07-06 11:53:23 -04:00
tigeran
4ac4d88a99 Remove unused using declaration
std::sort in `heap-profiler.cc` is not in use, so remove it.
2023-07-06 11:41:24 -04:00
Aliaksey Kandratsenka
4e24f4adaa fix overflow in c-f-l populate when span address is close to top
This fixes github issue #1323.

When populating span with linked list of objects ptr + size <= limit
condition could overflow before comparing to limit. So fixed code
carefully tests limit. We also produce version with
__builtin_add_overflow since this is semi-hot loop and we want it to
be fast.
2023-07-04 01:45:33 -04:00
Aliaksey Kandratsenka
f15425dc99 implement SafeStrError and use it inside strerror
This fixes issue #1371

From time to time things file inside tcmalloc guts where calling to
malloc is not safe. Regular strerror does locale bits, so will
occasionally open files/malloc/etc. We avoid this by using our own
"safe" variant that hardcodes names of all POSIX errno constants.
2023-07-03 18:14:05 -04:00
Aliaksey Kandratsenka
88d0fd5a3b remove dead remains of arm_instruction_set_select header 2023-07-03 17:29:13 -04:00
Aliaksey Kandratsenka
d9cecd6e42 print errno whenever dumping heap profile fails for some reason
Refers to issue #1116
2023-07-03 16:45:00 -04:00
Aliaksey Kandratsenka
fe5ba4b524 use sys/ptrace.h instead of linux/ptrace.h
As was pointed out at
https://github.com/gperftools/gperftools/pull/1329 there is no need
for us to depend on linux-headers thingy. Libc headers should be
enough.
2023-07-03 16:20:26 -04:00
Aliaksey Kandratsenka
55e798623f unbreak compilation with --disable-cpu-profiler 2023-07-03 15:31:21 -04:00
Aliaksey Kandratsenka
dd89dc7d01 install compat headers and .pc files only with matching libs
Thix closes issue #1356
2023-07-03 15:29:56 -04:00
Ali Saidi
a63ea13b20 Add an arm64 implementation for SpinlockPause()
This patch adds an arm64 implementation of the SpinlockPause() function
allowing the core to adaptively spin to acquire the lock and improving
performance in multi-threaded environments where the locks can be contended.

From experience with other projects, we've found a single isb is the closest
corollary to the rep; nop timing or x86.

Overall, across thirty runs, the binary_trees_shared benchmark improves 6% in
average, median, and P90 runtime with this change.
2023-07-03 14:05:13 -04:00
Sergey Fedorov
3c0738ac1c libc_override_osx.h: a small fix for ppc 2023-07-03 13:38:35 -04:00
Aliaksey Kandratsenka
cc4e289a83 drop weakening from cmake build
Weakening is optional and in github issue #1392 we apparently tried to
weaken on windows and failed. So lets not even try.
2023-07-03 13:02:59 -04:00
Aliaksey Kandratsenka
44eb0ee83c bump heap profiler stats fields to 64 bit
People actually seen overflows there. Fixes github issue #1303
2023-07-03 12:47:35 -04:00
Aliaksey Kandratsenka
972c12f77d refactor stacktrace.cc and drop x86 backtracer
We had plenty of old and mostly no more correct i386 cruft. Now that
generic_fp backtracer covers i386 just fine, we can drop explicit x86
backtracer.

With that we refactored and simplified stacktrace.cc mostly around
picking default implementation, but also adding few more minor
cleanups.
2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
d9b178695f support more OSes in generic-fp
We're still x86+arm+riscv only, but netbsd and freebsd work too. OSX
as well.
2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
4b78ffd03c try building with -fno-omit-frame-pointer -momit-leaf-frame-pointer
The idea is -momit-leaf-frame-pointer gives us performance pretty much
same as fully omitting frame pointers. And having frame pointers
elsewhere allows us to support cases when user's code is built with
frame pointers. We also pass all tests with
TCMALLOC_STACKTRACE_METHOD=generic_fp (not just libunwind or libgcc).
2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
e5ac219780 restore unwind-bench
We previously deleted it, since it wasn't portable enough. But
unportable bits are now ifdef-ed out, so we can return it.
2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
cf046c8421 extend generic frame pointer backtracer to support x86-32 (aka x32) 2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
f56c27910a extend generic frame pointer backtracer to support i386 2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
58d6842576 more coverage for stacktrace_unittest 2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
25698cd1b8 improve diagnostics for stacktrace_unittest 2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
a25e7fa8b0 cleanup cmake's config.h stuff
Some header defines were not cmakedefine01.
2023-07-02 22:30:00 -04:00
Aliaksey Kandratsenka
88d7e65cc2 drop unused libtool target in our Makefile.am
Not sure what it was for, but it is not useful today.
2023-07-02 22:30:00 -04:00