Commit 78109661 authored by Taiju Tsuiki's avatar Taiju Tsuiki Committed by Fumitoshi Ukai

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
  https://chromium.googlesource.com/chromium/src/+/3dae0a2d7da309159a301e40a592692ec8431a38

  Fix -INT_MIN integer overflow in itoa_r().
  https://chromium.googlesource.com/chromium/src/+/ac4d28e9cb934e01ff16a9e67a5f387caa82719f

  Add print_unsymbolized_stack_traces gn arg.
  https://chromium.googlesource.com/chromium/src/+/6a2726776f59cdcf0090f584a15db4a1ab8c40d7

  Switch to standard integer types in base/.
  https://chromium.googlesource.com/chromium/src/+/9b6f42934e5a1e65ebfc668d91a28a6e2678a14c

* Add a build option to print unsymbolized traces

This PRINT_UNSYMBOLIZED_STACK_TRACES option to cmake, and
--enable-unsymbolized-traces option to autoconf.
parent de82428e
...@@ -21,6 +21,8 @@ option (WITH_GFLAGS "Use gflags" ON) ...@@ -21,6 +21,8 @@ option (WITH_GFLAGS "Use gflags" ON)
option (WITH_THREADS "Enable multithreading support" ON) option (WITH_THREADS "Enable multithreading support" ON)
option (WITH_TLS "Enable Thread Local Storage (TLS) support" ON) option (WITH_TLS "Enable Thread Local Storage (TLS) support" ON)
option (BUILD_SHARED_LIBS "Build shared libraries" OFF) 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) list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
......
...@@ -207,6 +207,15 @@ AC_PC_FROM_UCONTEXT(AC_MSG_WARN(Could not find the PC. Will not output failed a ...@@ -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_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 # These are what's needed by logging.h.in and raw_logging.h.in
AC_SUBST(ac_google_start_namespace) AC_SUBST(ac_google_start_namespace)
AC_SUBST(ac_google_end_namespace) AC_SUBST(ac_google_end_namespace)
......
...@@ -167,6 +167,9 @@ ...@@ -167,6 +167,9 @@
/* How to access the PC from a struct ucontext */ /* How to access the PC from a struct ucontext */
#cmakedefine PC_FROM_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 /* Define to necessary symbol if this constant uses a non-standard name on
your system. */ your system. */
#cmakedefine PTHREAD_CREATE_JOINABLE #cmakedefine PTHREAD_CREATE_JOINABLE
......
...@@ -154,6 +154,9 @@ ...@@ -154,6 +154,9 @@
/* How to access the PC from a struct ucontext */ /* How to access the PC from a struct ucontext */
#undef PC_FROM_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 /* Define to necessary symbol if this constant uses a non-standard name on
your system. */ your system. */
#undef PTHREAD_CREATE_JOINABLE #undef PTHREAD_CREATE_JOINABLE
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#include <string.h> #include <string.h>
#include <algorithm>
#include <limits> #include <limits>
#include "symbolize.h" #include "symbolize.h"
...@@ -292,13 +293,12 @@ FindSymbol(uint64_t pc, const int fd, char *out, int out_size, ...@@ -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. // Read at most NUM_SYMBOLS symbols at once to save read() calls.
ElfW(Sym) buf[NUM_SYMBOLS]; ElfW(Sym) buf[NUM_SYMBOLS];
const ssize_t len = ReadFromOffset(fd, &buf, sizeof(buf), offset); int num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i);
if (len == -1) { const ssize_t len =
return false; ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset);
}
SAFE_ASSERT(len % sizeof(buf[0]) == 0); SAFE_ASSERT(len % sizeof(buf[0]) == 0);
const ssize_t num_symbols_in_buf = len / sizeof(buf[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) { for (int 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;
...@@ -684,7 +684,8 @@ static char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) ...@@ -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). // Handle negative numbers (only for base 10).
if (i < 0 && 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. // Make sure we can write the '-' character.
if (++n > sz) { if (++n > sz) {
...@@ -780,8 +781,13 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, ...@@ -780,8 +781,13 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
out_size - 1); out_size - 1);
} }
#if defined(PRINT_UNSYMBOLIZED_STACK_TRACES)
{
FileDescriptor wrapped_object_fd(object_fd);
#else
// Check whether a file name was returned. // Check whether a file name was returned.
if (object_fd < 0) { if (object_fd < 0) {
#endif
if (out[1]) { if (out[1]) {
// The object file containing PC was determined successfully however the // The object file containing PC was determined successfully however the
// object file was not opened successfully. This is still considered // object file was not opened successfully. This is still considered
...@@ -805,7 +811,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, ...@@ -805,7 +811,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
// Run the call back if it's installed. // Run the call back if it's installed.
// Note: relocation (and much of the rest of this code) will be // Note: relocation (and much of the rest of this code) will be
// wrong for prelinked shared libraries and PIE executables. // 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(), int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(),
pc, out, out_size, pc, out, out_size,
relocation); relocation);
......
...@@ -116,8 +116,11 @@ _START_GOOGLE_NAMESPACE_ ...@@ -116,8 +116,11 @@ _START_GOOGLE_NAMESPACE_
// counter "pc". The callback function should write output to "out" // counter "pc". The callback function should write output to "out"
// and return the size of the output written. On error, the callback // and return the size of the output written. On error, the callback
// function should return -1. // function should return -1.
typedef int (*SymbolizeCallback)(int fd, void *pc, char *out, size_t out_size, typedef int (*SymbolizeCallback)(int fd,
uint64 relocation); void* pc,
char* out,
size_t out_size,
uint64_t relocation);
void InstallSymbolizeCallback(SymbolizeCallback callback); void InstallSymbolizeCallback(SymbolizeCallback callback);
// Installs a callback function, which will be called instead of // Installs a callback function, which will be called instead of
...@@ -130,10 +133,10 @@ void InstallSymbolizeCallback(SymbolizeCallback callback); ...@@ -130,10 +133,10 @@ void InstallSymbolizeCallback(SymbolizeCallback callback);
// file is opened successfully, returns the file descriptor. Otherwise, // file is opened successfully, returns the file descriptor. Otherwise,
// returns -1. |out_file_name_size| is the size of the file name buffer // returns -1. |out_file_name_size| is the size of the file name buffer
// (including the null-terminator). // (including the null-terminator).
typedef int (*SymbolizeOpenObjectFileCallback)(uint64 pc, typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc,
uint64 &start_address, uint64_t& start_address,
uint64 &base_address, uint64_t& base_address,
char *out_file_name, char* out_file_name,
int out_file_name_size); int out_file_name_size);
void InstallSymbolizeOpenObjectFileCallback( void InstallSymbolizeOpenObjectFileCallback(
SymbolizeOpenObjectFileCallback callback); SymbolizeOpenObjectFileCallback callback);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment