Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmake/utils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ function(make_third_party_configuration PIC_ENABLED PROJECT_GENERIC_NAME PROJECT
set(${OUT_LIB_SPECIFIER} ${NO_PIC_LIBRARY_SPECIFIER} PARENT_SCOPE)
endif()

set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -fno-omit-frame-pointer")

if(COMPILE_RUNTIME_LIGHT)
set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} ${RUNTIME_LIGHT_VISIBILITY}")
endif()
Expand Down
17 changes: 13 additions & 4 deletions common/fast-backtrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <execinfo.h>

#include "common/sanitizer.h"
Expand Down Expand Up @@ -43,9 +44,13 @@ int fast_backtrace(void** buffer, int size) {
}

int fast_backtrace_by_bp(void* bp, void* stack_end_, void** buffer, int size) {
stack_frame* current_bp = static_cast<stack_frame*>(bp);
if (stack_end_ == nullptr) {
return 0;
}
const auto last_frame_addr = reinterpret_cast<std::uintptr_t>(stack_end_) - sizeof(stack_frame);
auto* current_bp = static_cast<stack_frame*>(bp);
int i = 0;
while (i < size && reinterpret_cast<char*>(current_bp) <= stack_end_ && !(reinterpret_cast<long>(current_bp) & (sizeof(long) - 1))) {
while (i < size && reinterpret_cast<std::uintptr_t>(current_bp) <= last_frame_addr && !(reinterpret_cast<long>(current_bp) & (sizeof(long) - 1))) {
void* ip = current_bp->ip;
buffer[i++] = ip;
stack_frame* p = current_bp->bp;
Expand All @@ -67,9 +72,13 @@ int fast_backtrace_without_recursions(void** buffer, int size) noexcept {
}

int fast_backtrace_without_recursions_by_bp(void* bp, void* stack_end_, void** buffer, int size) noexcept {
stack_frame* current_bp = static_cast<stack_frame*>(bp);
if (stack_end_ == nullptr) {
return 0;
}
const auto last_frame_addr = reinterpret_cast<std::uintptr_t>(stack_end_) - sizeof(stack_frame);
auto* current_bp = static_cast<stack_frame*>(bp);
int i = 0;
while (i < size && reinterpret_cast<char*>(current_bp) <= stack_end_ && !(reinterpret_cast<long>(current_bp) & (sizeof(long) - 1))) {
while (i < size && reinterpret_cast<std::uintptr_t>(current_bp) <= last_frame_addr && !(reinterpret_cast<long>(current_bp) & (sizeof(long) - 1))) {
buffer[i++] = current_bp->ip;
for (int possible_recursion_len = 1; i >= 2 * possible_recursion_len; ++possible_recursion_len) {
if (std::equal(buffer + i - possible_recursion_len, buffer + i, buffer + i - possible_recursion_len * 2)) {
Expand Down
13 changes: 12 additions & 1 deletion runtime-light/stdlib/diagnostics/backtrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Distributed under the GPL v3 License, see LICENSE.notice.txt

#include <cstddef>
#include <cstdint>
#include <iterator>
#include <span>

Expand All @@ -14,14 +15,24 @@

namespace {

bool is_aligned(const void* ptr, std::size_t alignment) noexcept {
return (reinterpret_cast<std::uintptr_t>(ptr) & (alignment - 1)) == 0;
}

size_t sync_frames(std::span<void*> addresses, kphp::coro::stack_frame* start_frame, kphp::coro::stack_frame* stop_frame) noexcept {
kphp::log::assertion(start_frame != nullptr && stop_frame != nullptr);

auto address{addresses.begin()};
for (auto* current_stack_frame{start_frame}; current_stack_frame != stop_frame && address != addresses.end();
for (auto* current_stack_frame{start_frame};
address != addresses.end() && reinterpret_cast<std::uintptr_t>(current_stack_frame) < reinterpret_cast<std::uintptr_t>(stop_frame) &&
is_aligned(current_stack_frame, alignof(void*));
current_stack_frame = current_stack_frame->caller_stack_frame) {
*address = current_stack_frame->return_address;
address = std::next(address);
auto* next{current_stack_frame->caller_stack_frame};
if (reinterpret_cast<std::uintptr_t>(next) <= reinterpret_cast<std::uintptr_t>(current_stack_frame)) {
break;
}
}
return std::distance(addresses.begin(), address);
}
Expand Down
Loading