fix(symbolize): cleanup (#1048)

This commit is contained in:
Sergiu Deitsch 2024-01-08 01:40:29 +01:00 committed by GitHub
parent 734ab3463f
commit aaefca72b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 37 deletions

View File

@ -57,54 +57,53 @@
#if defined(HAVE_SYMBOLIZE) #if defined(HAVE_SYMBOLIZE)
# include <algorithm> # include <algorithm>
# include <cstdlib>
# include <cstring> # include <cstring>
# include <limits> # include <limits>
# include "demangle.h" # include "demangle.h"
# include "symbolize.h" # include "symbolize.h"
namespace google {
// We don't use assert() since it's not guaranteed to be // We don't use assert() since it's not guaranteed to be
// async-signal-safe. Instead we define a minimal assertion // async-signal-safe. Instead we define a minimal assertion
// macro. So far, we don't need pretty printing for __FILE__, etc. // macro. So far, we don't need pretty printing for __FILE__, etc.
# define GLOG_SAFE_ASSERT(expr) ((expr) ? 0 : (std::abort(), 0))
// A wrapper for abort() to make it callable in ? :. namespace google {
static int AssertFail() {
abort();
return 0; // Should not reach.
}
# define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail()) namespace {
static SymbolizeCallback g_symbolize_callback = nullptr; SymbolizeCallback g_symbolize_callback = nullptr;
void InstallSymbolizeCallback(SymbolizeCallback callback) { SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback = nullptr;
g_symbolize_callback = callback;
}
static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback =
nullptr;
void InstallSymbolizeOpenObjectFileCallback(
SymbolizeOpenObjectFileCallback callback) {
g_symbolize_open_object_file_callback = callback;
}
// This function wraps the Demangle function to provide an interface // This function wraps the Demangle function to provide an interface
// where the input symbol is demangled in-place. // where the input symbol is demangled in-place.
// To keep stack consumption low, we would like this function to not // To keep stack consumption low, we would like this function to not
// get inlined. // get inlined.
static ATTRIBUTE_NOINLINE void DemangleInplace(char* out, size_t out_size) { ATTRIBUTE_NOINLINE
void DemangleInplace(char* out, size_t out_size) {
char demangled[256]; // Big enough for sane demangled symbols. char demangled[256]; // Big enough for sane demangled symbols.
if (Demangle(out, demangled, sizeof(demangled))) { if (Demangle(out, demangled, sizeof(demangled))) {
// Demangling succeeded. Copy to out if the space allows. // Demangling succeeded. Copy to out if the space allows.
size_t len = strlen(demangled); size_t len = strlen(demangled);
if (len + 1 <= out_size) { // +1 for '\0'. if (len + 1 <= out_size) { // +1 for '\0'.
SAFE_ASSERT(len < sizeof(demangled)); GLOG_SAFE_ASSERT(len < sizeof(demangled));
memmove(out, demangled, len + 1); memmove(out, demangled, len + 1);
} }
} }
} }
} // namespace
void InstallSymbolizeCallback(SymbolizeCallback callback) {
g_symbolize_callback = callback;
}
void InstallSymbolizeOpenObjectFileCallback(
SymbolizeOpenObjectFileCallback callback) {
g_symbolize_open_object_file_callback = callback;
}
} // namespace google } // namespace google
# if defined(__ELF__) # if defined(__ELF__)
@ -134,19 +133,23 @@ static ATTRIBUTE_NOINLINE void DemangleInplace(char* out, size_t out_size) {
# include "glog/raw_logging.h" # include "glog/raw_logging.h"
# include "symbolize.h" # include "symbolize.h"
namespace google {
namespace {
// Re-runs run until it doesn't cause EINTR. // Re-runs run until it doesn't cause EINTR.
// Similar to the TEMP_FAILURE_RETRY macro from GNU C. // Similar to the TEMP_FAILURE_RETRY macro from GNU C.
template <class Functor> template <class Functor>
auto FailureRetry(Functor run, int error = EINTR) noexcept(noexcept(run())) { auto FailureRetry(Functor run, int error = EINTR) noexcept(noexcept(run())) {
decltype(run()) result; decltype(run()) result;
do { while ((result = run()) == -1 && errno == error) {
} while ((result = run()) == -1 && errno == error); }
return result; return result;
} }
namespace google { } // namespace
// Read up to "count" bytes from "offset" in the file pointed by file // Read up to "count" bytes from "offset" in the file pointed by file
// descriptor "fd" into the buffer starting at "buf" while handling short reads // descriptor "fd" into the buffer starting at "buf" while handling short reads
@ -154,9 +157,9 @@ namespace google {
// -1. // -1.
static ssize_t ReadFromOffset(const int fd, void* buf, const size_t count, static ssize_t ReadFromOffset(const int fd, void* buf, const size_t count,
const size_t offset) { const size_t offset) {
SAFE_ASSERT(fd >= 0); GLOG_SAFE_ASSERT(fd >= 0);
SAFE_ASSERT(count <= GLOG_SAFE_ASSERT(count <=
static_cast<size_t>(std::numeric_limits<ssize_t>::max())); static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
char* buf0 = reinterpret_cast<char*>(buf); char* buf0 = reinterpret_cast<char*>(buf);
size_t num_bytes = 0; size_t num_bytes = 0;
while (num_bytes < count) { while (num_bytes < count) {
@ -172,7 +175,7 @@ static ssize_t ReadFromOffset(const int fd, void* buf, const size_t count,
} }
num_bytes += static_cast<size_t>(len); num_bytes += static_cast<size_t>(len);
} }
SAFE_ASSERT(num_bytes <= count); GLOG_SAFE_ASSERT(num_bytes <= count);
return static_cast<ssize_t>(num_bytes); return static_cast<ssize_t>(num_bytes);
} }
@ -219,9 +222,9 @@ static ATTRIBUTE_NOINLINE bool GetSectionHeaderByType(const int fd,
if (len == -1) { if (len == -1) {
return false; return false;
} }
SAFE_ASSERT(static_cast<size_t>(len) % sizeof(buf[0]) == 0); GLOG_SAFE_ASSERT(static_cast<size_t>(len) % sizeof(buf[0]) == 0);
const size_t num_headers_in_buf = static_cast<size_t>(len) / sizeof(buf[0]); const size_t num_headers_in_buf = static_cast<size_t>(len) / sizeof(buf[0]);
SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0])); GLOG_SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0]));
for (size_t j = 0; j < num_headers_in_buf; ++j) { for (size_t j = 0; j < num_headers_in_buf; ++j) {
if (buf[j].sh_type == type) { if (buf[j].sh_type == type) {
*out = buf[j]; *out = buf[j];
@ -315,9 +318,9 @@ static ATTRIBUTE_NOINLINE bool FindSymbol(uint64_t pc, const int fd, char* out,
size_t num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i); size_t num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i);
const ssize_t len = const ssize_t len =
ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset); ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset);
SAFE_ASSERT(static_cast<size_t>(len) % sizeof(buf[0]) == 0); GLOG_SAFE_ASSERT(static_cast<size_t>(len) % sizeof(buf[0]) == 0);
const size_t num_symbols_in_buf = static_cast<size_t>(len) / sizeof(buf[0]); const size_t num_symbols_in_buf = static_cast<size_t>(len) / sizeof(buf[0]);
SAFE_ASSERT(num_symbols_in_buf <= num_symbols_to_read); GLOG_SAFE_ASSERT(num_symbols_in_buf <= num_symbols_to_read);
for (unsigned j = 0; j < num_symbols_in_buf; ++j) { for (unsigned j = 0; j < num_symbols_in_buf; ++j) {
const ElfW(Sym)& symbol = buf[j]; const ElfW(Sym)& symbol = buf[j];
uint64_t start_address = symbol.st_value; uint64_t start_address = symbol.st_value;
@ -416,8 +419,8 @@ class LineReader {
eod_ = buf_ + num_bytes; eod_ = buf_ + num_bytes;
bol_ = buf_; bol_ = buf_;
} else { } else {
bol_ = eol_ + 1; // Advance to the next line in the buffer. bol_ = eol_ + 1; // Advance to the next line in the buffer.
SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_". GLOG_SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_".
if (!HasCompleteLine()) { if (!HasCompleteLine()) {
const auto incomplete_line_length = static_cast<size_t>(eod_ - bol_); const auto incomplete_line_length = static_cast<size_t>(eod_ - bol_);
// Move the trailing incomplete line to the beginning. // Move the trailing incomplete line to the beginning.
@ -492,7 +495,7 @@ static char* GetHex(const char* start, const char* end, uint64_t* hex) {
break; break;
} }
} }
SAFE_ASSERT(p <= end); GLOG_SAFE_ASSERT(p <= end);
return const_cast<char*>(p); return const_cast<char*>(p);
} }
@ -715,7 +718,7 @@ static char* itoa_r(uintptr_t i, char* buf, size_t sz, unsigned base,
// buffer size |dest_size| and guarantees that |dest| is null-terminated. // buffer size |dest_size| and guarantees that |dest| is null-terminated.
static void SafeAppendString(const char* source, char* dest, size_t dest_size) { static void SafeAppendString(const char* source, char* dest, size_t dest_size) {
size_t dest_string_length = strlen(dest); size_t dest_string_length = strlen(dest);
SAFE_ASSERT(dest_string_length < dest_size); GLOG_SAFE_ASSERT(dest_string_length < dest_size);
dest += dest_string_length; dest += dest_string_length;
dest_size -= dest_string_length; dest_size -= dest_string_length;
strncpy(dest, source, dest_size); strncpy(dest, source, dest_size);

View File

@ -1,4 +1,4 @@
// Copyright (c) 2006, Google Inc. // Copyright (c) 2024, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -132,6 +132,7 @@ void InstallSymbolizeCallback(SymbolizeCallback callback);
// (including the null-terminator). // (including the null-terminator).
using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t&, uint64_t&, using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t&, uint64_t&,
char*, size_t); char*, size_t);
GLOG_EXPORT
void InstallSymbolizeOpenObjectFileCallback( void InstallSymbolizeOpenObjectFileCallback(
SymbolizeOpenObjectFileCallback callback); SymbolizeOpenObjectFileCallback callback);