Commit f12be75c authored by Robert Sesek's avatar Robert Sesek Committed by Commit Bot

Add a utility to format a base::debug::StackTrace for CrashKeyString.

Bug: 598854
Change-Id: Ie92935f4919e57cae338c33750458c0509a93627
Reviewed-on: https://chromium-review.googlesource.com/782040
Commit-Queue: Robert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#518381}
parent cd4a636f
......@@ -15,6 +15,7 @@ group("common") {
static_library("crash_key") {
sources = [
"crash_key.cc",
"crash_key.h",
]
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/crash/core/common/crash_key.h"
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"
namespace crash_reporter {
namespace internal {
std::string FormatStackTrace(const base::debug::StackTrace& trace,
size_t max_length) {
size_t count = 0;
const void* const* addresses = trace.Addresses(&count);
std::string value;
for (size_t i = 0; i < count; ++i) {
std::string address = base::StringPrintf(
"0x%" PRIx64, reinterpret_cast<uint64_t>(addresses[i]));
if (value.size() + address.size() > max_length)
break;
value += address + " ";
}
if (value.back() == ' ') {
value.resize(value.size() - 1);
}
return value;
}
} // namespace internal
} // namespace crash_reporter
......@@ -7,6 +7,9 @@
#include <stdint.h>
#include <string>
#include "base/debug/stack_trace.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"
......@@ -171,6 +174,25 @@ class ScopedCrashKeyString {
DISALLOW_COPY_AND_ASSIGN(ScopedCrashKeyString);
};
namespace internal {
// Formats a stack trace into a string whose length will not exceed
// |max_length|. This function ensures no addresses are truncated when
// being formatted.
std::string FormatStackTrace(const base::debug::StackTrace& trace,
size_t max_length);
} // namespace internal
// Formats a base::debug::StackTrace as a string of space-separated hexadecimal
// numbers and stores it in a CrashKeyString.
// TODO(rsesek): When all clients use Crashpad, traces should become a first-
// class Annotation type rather than being forced through string conversion.
template <uint32_t Size>
void SetCrashKeyStringToStackTrace(CrashKeyString<Size>* key,
const base::debug::StackTrace& trace) {
std::string trace_string = internal::FormatStackTrace(trace, Size);
key->Set(trace_string);
}
// Initializes the crash key subsystem if it is required.
void InitializeCrashKeys();
......
......@@ -4,6 +4,8 @@
#include "components/crash/core/common/crash_key.h"
#include "base/debug/stack_trace.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace crash_reporter {
......@@ -27,5 +29,54 @@ TEST_F(CrashKeyStringTest, ScopedCrashKeyString) {
EXPECT_FALSE(key.is_set());
}
TEST_F(CrashKeyStringTest, FormatStackTrace) {
const uintptr_t addresses[] = {
0x0badbeef, 0x77778888, 0xabc, 0x000ddeeff, 0x12345678,
};
base::debug::StackTrace trace(reinterpret_cast<const void* const*>(addresses),
arraysize(addresses));
std::string too_small = internal::FormatStackTrace(trace, 3);
EXPECT_EQ(0u, too_small.size());
std::string one_value = internal::FormatStackTrace(trace, 16);
EXPECT_EQ("0xbadbeef", one_value);
std::string three_values = internal::FormatStackTrace(trace, 30);
EXPECT_EQ("0xbadbeef 0x77778888 0xabc", three_values);
std::string all_values = internal::FormatStackTrace(trace, 128);
EXPECT_EQ("0xbadbeef 0x77778888 0xabc 0xddeeff 0x12345678", all_values);
}
#if defined(ARCH_CPU_64_BITS)
TEST_F(CrashKeyStringTest, FormatStackTrace64) {
const uintptr_t addresses[] = {
0xbaaaabaaaaba, 0x1000000000000000,
};
base::debug::StackTrace trace(reinterpret_cast<const void* const*>(addresses),
arraysize(addresses));
std::string too_small = internal::FormatStackTrace(trace, 8);
EXPECT_EQ(0u, too_small.size());
std::string one_value = internal::FormatStackTrace(trace, 20);
EXPECT_EQ("0xbaaaabaaaaba", one_value);
std::string all_values = internal::FormatStackTrace(trace, 35);
EXPECT_EQ("0xbaaaabaaaaba 0x1000000000000000", all_values);
}
#endif
TEST_F(CrashKeyStringTest, SetStackTrace) {
static CrashKeyString<1024> key("test-trace");
EXPECT_FALSE(key.is_set());
SetCrashKeyStringToStackTrace(&key, base::debug::StackTrace());
EXPECT_TRUE(key.is_set());
}
} // namespace
} // namespace crash_reporter
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