Upstream Chromium local changes to symbolize.cc (#391)

* Upstream Chromium local changes to symbolize.cc

Chromium has its own fork of symbolize.cc and symbolize.h, and it has
several not-yet-upstreamed changes, that are not specific to Chromium.

This patch upstreams such a changes.

  Fixed google::FindSymbol reading past end of a section
  3dae0a2d7d

  Fix -INT_MIN integer overflow in itoa_r().
  ac4d28e9cb

  Add print_unsymbolized_stack_traces gn arg.
  6a2726776f

  Switch to standard integer types in base/.
  9b6f42934e

* Add a build option to print unsymbolized traces

This PRINT_UNSYMBOLIZED_STACK_TRACES option to cmake, and
--enable-unsymbolized-traces option to autoconf.
This commit is contained in:
Taiju Tsuiki 2018-11-21 11:14:38 +09:00 committed by Fumitoshi Ukai
parent de82428e52
commit 781096619d
6 changed files with 39 additions and 13 deletions

View File

@ -21,6 +21,8 @@ option (WITH_GFLAGS "Use gflags" ON)
option (WITH_THREADS "Enable multithreading support" ON)
option (WITH_TLS "Enable Thread Local Storage (TLS) support" ON)
option (BUILD_SHARED_LIBS "Build shared libraries" OFF)
option (PRINT_UNSYMBOLIZED_STACK_TRACES
"Print raw pc values on symbolization failure" OFF)
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

View File

@ -207,6 +207,15 @@ AC_PC_FROM_UCONTEXT(AC_MSG_WARN(Could not find the PC. Will not output failed a
AC_DEFINE_UNQUOTED(TEST_SRC_DIR, "$srcdir", [location of source code])
AC_ARG_ENABLE(unsymbolized-traces,
AS_HELP_STRING([--enable-unsymbolized-traces],
[Print raw pc values when symbolization is failed.]),
enable_unsymbolized_traces=yes)
if test x"$enable_unsymbolized_traces" = x"yes"; then
AC_DEFINE(PRINT_UNSYMBOLIZED_STACK_TRACES, 1,
[define if we should print raw pc values on symbolization failure.])
fi
# These are what's needed by logging.h.in and raw_logging.h.in
AC_SUBST(ac_google_start_namespace)
AC_SUBST(ac_google_end_namespace)

View File

@ -167,6 +167,9 @@
/* How to access the PC from a struct ucontext */
#cmakedefine PC_FROM_UCONTEXT
/* define if we should print raw pc values on symbolization failure. */
#cmakedefine PRINT_UNSYMBOLIZED_STACK_TRACES
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#cmakedefine PTHREAD_CREATE_JOINABLE

View File

@ -154,6 +154,9 @@
/* How to access the PC from a struct ucontext */
#undef PC_FROM_UCONTEXT
/* define if we should print raw pc values on symbolization failure. */
#undef PRINT_UNSYMBOLIZED_STACK_TRACES
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE

View File

@ -58,6 +58,7 @@
#include <string.h>
#include <algorithm>
#include <limits>
#include "symbolize.h"
@ -292,13 +293,12 @@ FindSymbol(uint64_t pc, const int fd, char *out, int out_size,
// Read at most NUM_SYMBOLS symbols at once to save read() calls.
ElfW(Sym) buf[NUM_SYMBOLS];
const ssize_t len = ReadFromOffset(fd, &buf, sizeof(buf), offset);
if (len == -1) {
return false;
}
int num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i);
const ssize_t len =
ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset);
SAFE_ASSERT(len % sizeof(buf[0]) == 0);
const ssize_t num_symbols_in_buf = len / sizeof(buf[0]);
SAFE_ASSERT(num_symbols_in_buf <= sizeof(buf)/sizeof(buf[0]));
SAFE_ASSERT(num_symbols_in_buf <= num_symbols_to_read);
for (int j = 0; j < num_symbols_in_buf; ++j) {
const ElfW(Sym)& symbol = buf[j];
uint64_t start_address = symbol.st_value;
@ -684,7 +684,8 @@ static char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding)
// Handle negative numbers (only for base 10).
if (i < 0 && base == 10) {
j = -i;
// This does "j = -i" while avoiding integer overflow.
j = static_cast<uintptr_t>(-(i + 1)) + 1;
// Make sure we can write the '-' character.
if (++n > sz) {
@ -780,8 +781,13 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
out_size - 1);
}
#if defined(PRINT_UNSYMBOLIZED_STACK_TRACES)
{
FileDescriptor wrapped_object_fd(object_fd);
#else
// Check whether a file name was returned.
if (object_fd < 0) {
#endif
if (out[1]) {
// The object file containing PC was determined successfully however the
// object file was not opened successfully. This is still considered
@ -805,7 +811,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
// Run the call back if it's installed.
// Note: relocation (and much of the rest of this code) will be
// wrong for prelinked shared libraries and PIE executables.
uint64 relocation = (elf_type == ET_DYN) ? start_address : 0;
uint64_t relocation = (elf_type == ET_DYN) ? start_address : 0;
int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(),
pc, out, out_size,
relocation);

View File

@ -116,8 +116,11 @@ _START_GOOGLE_NAMESPACE_
// counter "pc". The callback function should write output to "out"
// and return the size of the output written. On error, the callback
// function should return -1.
typedef int (*SymbolizeCallback)(int fd, void *pc, char *out, size_t out_size,
uint64 relocation);
typedef int (*SymbolizeCallback)(int fd,
void* pc,
char* out,
size_t out_size,
uint64_t relocation);
void InstallSymbolizeCallback(SymbolizeCallback callback);
// Installs a callback function, which will be called instead of
@ -130,10 +133,10 @@ void InstallSymbolizeCallback(SymbolizeCallback callback);
// file is opened successfully, returns the file descriptor. Otherwise,
// returns -1. |out_file_name_size| is the size of the file name buffer
// (including the null-terminator).
typedef int (*SymbolizeOpenObjectFileCallback)(uint64 pc,
uint64 &start_address,
uint64 &base_address,
char *out_file_name,
typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc,
uint64_t& start_address,
uint64_t& base_address,
char* out_file_name,
int out_file_name_size);
void InstallSymbolizeOpenObjectFileCallback(
SymbolizeOpenObjectFileCallback callback);