Conversation
|
PR with tests: ClickHouse/ClickHouse#17965 |
|
What's the purpose of this patch? |
|
libunwind should not use malloc to be signal safe. It can use pre-allocated global buffer, but thread synchronization is required. |
src/DwarfParser.hpp
Outdated
|
|
||
| static bool atomic_compare_exchange_weak_wrapper(void * _Atomic & ptr, void *& expected, void * desired) | ||
| { | ||
| #ifdef __GNUC__ |
There was a problem hiding this comment.
clang++ defines GNUC:
$ clang++ -E -dM -xc++ - <<< '' | grep GNUC
#define __GNUC_GNU_INLINE__ 1
#define __GNUC_MINOR__ 2
#define __GNUC_PATCHLEVEL__ 1
#define __GNUC__ 4
|
|
||
| private: | ||
| static constexpr size_t entrySize = sizeof(FreeListEntry); | ||
| static constexpr size_t buffer_size = LIBUNWIND_MAX_STACK_SIZE * entrySize; |
There was a problem hiding this comment.
Theoretically it can fail on concurrent unwinding of very long stacks from multiple threads.
But it's Ok.
There was a problem hiding this comment.
Is it? 1024 / 32 (our usual stack size limit) = 128 threads getting stack trace simultaneously, and if we're over that, we abort. Combine that with query profiler running on a large server, and it doesn't look good.
In general, the previous code had hard guarantee that the abort() doesn't happen if the program is correct, but this one doesn't. So it will happen.
There was a problem hiding this comment.
I have added mmap for buffer and changed total limit to 1024 * 1024 frames
There was a problem hiding this comment.
Let's make it complete -- either we shoud mmap enough memory so that the allocation never fails (may be inconvenient to push the server settings here?), or we can add another mmap in case there was not enough memory. If we use the latter option, we should set the initial size low enough, so that this logic is tested. Maybe we can lower the initial size in debug even more.
In case we add second mmap, aborting on its errors looks bad -- i.e. we're out of mappings, several queries fail and start to unwind stack, and then mmap for stack also fails, and we abort. Maybe we can return empty stacks in this case?
There was a problem hiding this comment.
Or a third option, simlified -- allocate a static buffer once (maybe slightly larger than 1024 entries), but don't abort if we're out of memory, just truncate the stack. We might see some truncated stacks in profiler from time to time, but this is probably not very important.
Nice, I guessed almost correctly. Let's put this into comments. |
No description provided.