Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3021)

Unified Diff: base/debug/crash_logging.cc

Issue 11761030: Create the crash key registration system and register some Mac-specific keys. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/debug/crash_logging.cc
diff --git a/base/debug/crash_logging.cc b/base/debug/crash_logging.cc
index 1e20677ec4a32f94408811f773e17f75eaf018ce..0817e5983564e31c38c8eb58ee0d13ecd54874ce 100644
--- a/base/debug/crash_logging.cc
+++ b/base/debug/crash_logging.cc
@@ -4,6 +4,8 @@
#include "base/debug/crash_logging.h"
+#include <map>
+
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "base/string_util.h"
@@ -12,18 +14,62 @@
namespace base {
namespace debug {
-static SetCrashKeyValueFuncT g_set_key_func_ = NULL;
-static ClearCrashKeyValueFuncT g_clear_key_func_ = NULL;
+namespace {
+
+std::map<std::string, CrashKey>* g_crash_keys_;
Scott Hess - ex-Googler 2013/01/04 18:59:39 Would prefer =NULL, if it's the default, the compi
Robert Sesek 2013/01/04 19:25:38 Done.
+
+const char kChunkFormatString[] = "%s-%zu";
+
+SetCrashKeyValueFuncT g_set_key_func_ = NULL;
+ClearCrashKeyValueFuncT g_clear_key_func_ = NULL;
+
+} // namespace
Scott Hess - ex-Googler 2013/01/04 18:59:39 This should be outside the base::debug::, I think?
Robert Sesek 2013/01/04 19:25:38 I don't think it matters.
void SetCrashKeyValue(const base::StringPiece& key,
const base::StringPiece& value) {
- if (g_set_key_func_)
+ if (!g_set_key_func_)
+ return;
+
+ const CrashKey* crash_key = LookupCrashKey(key);
+
+ // TODO(rsesek): Do this:
+ //DCHECK(crash_key) << "All crash keys must be registered before use "
+ // << "(key = " << key << ")";
+
+ // Handle the un-chunked case.
+ if (!crash_key || crash_key->num_chunks == 1) {
g_set_key_func_(key, value);
+ return;
+ }
+
+ // Unset the unused chunks.
+ std::vector<std::string> chunks = ChunkCrashKeyValue(*crash_key, value);
+ for (size_t i = chunks.size(); i < crash_key->num_chunks; ++i) {
+ g_clear_key_func_(base::StringPrintf(kChunkFormatString, key.data(), i+1));
+ }
+
+ // Set the chunked keys.
+ for (size_t i = 0; i < chunks.size(); ++i) {
+ g_set_key_func_(base::StringPrintf(kChunkFormatString, key.data(), i+1),
+ chunks[i]);
+ }
}
void ClearCrashKey(const base::StringPiece& key) {
- if (g_clear_key_func_)
+ if (!g_clear_key_func_)
+ return;
+
+ const CrashKey* crash_key = LookupCrashKey(key);
+
+ // Handle the un-checked case.
+ if (!crash_key || crash_key->num_chunks == 1) {
g_clear_key_func_(key);
+ return;
+ }
+
+ for (size_t i = 1; i <= crash_key->num_chunks; ++i) {
+ g_clear_key_func_(base::StringPrintf(kChunkFormatString, key.data(), i));
+ }
}
void SetCrashKeyToStackTrace(const base::StringPiece& key,
@@ -70,6 +116,42 @@ ScopedCrashKey::~ScopedCrashKey() {
ClearCrashKey(key_);
}
+void InitCrashKeys(const CrashKey* const keys, size_t count,
+ InitCrashKeysCallbackFuncT completion_callback) {
+ if (!keys) {
+ delete g_crash_keys_;
+ g_crash_keys_ = NULL;
+ return;
+ }
+
+ g_crash_keys_ = new std::map<std::string, CrashKey>;
Scott Hess - ex-Googler 2013/01/04 18:59:39 This won't work great for modules which want to ma
Robert Sesek 2013/01/04 19:25:38 Because Windows enforces the requirement of a fixe
+
+ std::vector<std::string> all_keys;
+ all_keys.reserve(count);
+ for (size_t i = 0; i < count; ++i) {
+ g_crash_keys_->insert(std::make_pair(keys[i].key_name, keys[i]));
+ if (keys[i].num_chunks == 1) {
+ all_keys.push_back(keys[i].key_name);
+ } else {
+ for (size_t j = 1; j <= keys[i].num_chunks; ++j) {
+ all_keys.push_back(
+ base::StringPrintf(kChunkFormatString, keys[i].key_name, j));
+ }
+ }
+ }
+
+ if (completion_callback)
+ completion_callback(all_keys);
+}
+
+const CrashKey* LookupCrashKey(const base::StringPiece& key) {
+ std::map<std::string, CrashKey>::const_iterator it =
+ g_crash_keys_->find(key.as_string());
Scott Hess - ex-Googler 2013/01/04 18:59:39 Once we're calling as_string(), StringPiece isn't
Robert Sesek 2013/01/04 19:25:38 If we do it by const char* though, won't using the
Scott Hess - ex-Googler 2013/01/05 00:22:05 That's actually what I meant - kKeyName would be t
+ if (it == g_crash_keys_->end())
+ return NULL;
+ return &(it->second);
+}
+
void SetCrashKeyReportingFunctions(
SetCrashKeyValueFuncT set_key_func,
ClearCrashKeyValueFuncT clear_key_func) {
@@ -77,5 +159,27 @@ void SetCrashKeyReportingFunctions(
g_clear_key_func_ = clear_key_func;
}
+std::vector<std::string> ChunkCrashKeyValue(const CrashKey& crash_key,
+ const base::StringPiece& value) {
+ std::string value_string = value.as_string();
+ std::vector<std::string> chunks;
+ size_t offset = 0;
+ for (size_t i = 0;
+ i < crash_key.num_chunks && offset < value_string.length();
+ ++i) {
+ std::string chunk = value_string.substr(offset, crash_key.max_length);
+ chunks.push_back(chunk);
+ offset += chunk.length();
+ }
+ return chunks;
+}
+
+void ResetCrashLoggingForTesting() {
+ delete g_crash_keys_;
+ g_crash_keys_ = NULL;
+ g_set_key_func_ = NULL;
+ g_clear_key_func_ = NULL;
+}
+
} // namespace debug
} // namespace base

Powered by Google App Engine
This is Rietveld 408576698