| Index: base/debug/crash_logging.cc
|
| diff --git a/base/debug/crash_logging.cc b/base/debug/crash_logging.cc
|
| index 604c28620ec1cb9a7e783d6bc42b44ddb9051720..b21eae5e3cb8706b08230d4cf88c70222e5887af 100644
|
| --- a/base/debug/crash_logging.cc
|
| +++ b/base/debug/crash_logging.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "base/debug/crash_logging.h"
|
|
|
| +#include <cmath>
|
| #include <map>
|
|
|
| #include "base/debug/stack_trace.h"
|
| @@ -17,16 +18,30 @@ namespace debug {
|
|
|
| namespace {
|
|
|
| +// Global map of crash key names to registration entries.
|
| typedef std::map<base::StringPiece, CrashKey> CrashKeyMap;
|
| CrashKeyMap* g_crash_keys_ = NULL;
|
|
|
| +// The maximum length of a single chunk.
|
| size_t g_chunk_max_length_ = 0;
|
|
|
| +// String used to format chunked key names.
|
| const char kChunkFormatString[] = "%s-%" PRIuS;
|
|
|
| +// The functions that are called to actually set the key-value pairs in the
|
| +// crash reportng system.
|
| SetCrashKeyValueFuncT g_set_key_func_ = NULL;
|
| ClearCrashKeyValueFuncT g_clear_key_func_ = NULL;
|
|
|
| +// For a given |length|, computes the number of chunks a value of that size
|
| +// will occupy.
|
| +size_t NumChunksForLength(size_t length) {
|
| + return std::ceil(length / static_cast<float>(g_chunk_max_length_));
|
| +}
|
| +
|
| +// The longest max_length allowed by the system.
|
| +const size_t kLargestValueAllowed = 1024;
|
| +
|
| } // namespace
|
|
|
| void SetCrashKeyValue(const base::StringPiece& key,
|
| @@ -41,7 +56,7 @@ void SetCrashKeyValue(const base::StringPiece& key,
|
| // << "(key = " << key << ")";
|
|
|
| // Handle the un-chunked case.
|
| - if (!crash_key || crash_key->num_chunks == 1) {
|
| + if (!crash_key || crash_key->max_length <= g_chunk_max_length_) {
|
| g_set_key_func_(key, value);
|
| return;
|
| }
|
| @@ -49,7 +64,9 @@ void SetCrashKeyValue(const base::StringPiece& key,
|
| // Unset the unused chunks.
|
| std::vector<std::string> chunks =
|
| ChunkCrashKeyValue(*crash_key, value, g_chunk_max_length_);
|
| - for (size_t i = chunks.size(); i < crash_key->num_chunks; ++i) {
|
| + for (size_t i = chunks.size();
|
| + i < NumChunksForLength(crash_key->max_length);
|
| + ++i) {
|
| g_clear_key_func_(base::StringPrintf(kChunkFormatString, key.data(), i+1));
|
| }
|
|
|
| @@ -67,12 +84,12 @@ void ClearCrashKey(const base::StringPiece& key) {
|
| const CrashKey* crash_key = LookupCrashKey(key);
|
|
|
| // Handle the un-chunked case.
|
| - if (!crash_key || crash_key->num_chunks == 1) {
|
| + if (!crash_key || crash_key->max_length <= g_chunk_max_length_) {
|
| g_clear_key_func_(key);
|
| return;
|
| }
|
|
|
| - for (size_t i = 0; i < crash_key->num_chunks; ++i) {
|
| + for (size_t i = 0; i < NumChunksForLength(crash_key->max_length); ++i) {
|
| g_clear_key_func_(base::StringPrintf(kChunkFormatString, key.data(), i+1));
|
| }
|
| }
|
| @@ -136,7 +153,8 @@ size_t InitCrashKeys(const CrashKey* const keys, size_t count,
|
| size_t total_keys = 0;
|
| for (size_t i = 0; i < count; ++i) {
|
| g_crash_keys_->insert(std::make_pair(keys[i].key_name, keys[i]));
|
| - total_keys += keys[i].num_chunks;
|
| + total_keys += NumChunksForLength(keys[i].max_length);
|
| + DCHECK_LT(keys[i].max_length, kLargestValueAllowed);
|
| }
|
| DCHECK_EQ(count, g_crash_keys_->size())
|
| << "Duplicate crash keys were registered";
|
| @@ -161,11 +179,9 @@ void SetCrashKeyReportingFunctions(
|
| std::vector<std::string> ChunkCrashKeyValue(const CrashKey& crash_key,
|
| const base::StringPiece& value,
|
| size_t chunk_max_length) {
|
| - std::string value_string = value.as_string();
|
| + std::string value_string = value.substr(0, crash_key.max_length).as_string();
|
| std::vector<std::string> chunks;
|
| - for (size_t i = 0, offset = 0;
|
| - i < crash_key.num_chunks && offset < value_string.length();
|
| - ++i) {
|
| + for (size_t offset = 0; offset < value_string.length(); ) {
|
| std::string chunk = value_string.substr(offset, chunk_max_length);
|
| chunks.push_back(chunk);
|
| offset += chunk.length();
|
|
|