Index: components/crash/core/common/crash_keys.cc |
diff --git a/components/crash/core/common/crash_keys.cc b/components/crash/core/common/crash_keys.cc |
index c0afc6a14bde0ef66ddd94777434472fa6ebdd56..5d0be35ea55114e257041fb67635e55abbd2661c 100644 |
--- a/components/crash/core/common/crash_keys.cc |
+++ b/components/crash/core/common/crash_keys.cc |
@@ -4,11 +4,16 @@ |
#include "components/crash/core/common/crash_keys.h" |
+#include "base/bind.h" |
+#include "base/callback.h" |
+#include "base/command_line.h" |
#include "base/debug/crash_logging.h" |
#include "base/format_macros.h" |
+#include "base/logging.h" |
#include "base/strings/string_piece.h" |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
+#include "base/strings/utf_string_conversions.h" |
namespace crash_keys { |
@@ -25,6 +30,9 @@ const char kChannel[] = "channel"; |
const char kNumVariations[] = "num-experiments"; |
const char kVariations[] = "variations"; |
+const char kSwitch[] = "switch-%" PRIuS; |
+const char kNumSwitches[] = "num-switches"; |
+ |
const char kBug464926CrashKey[] = "bug-464926-info"; |
#if defined(OS_MACOSX) |
@@ -92,4 +100,74 @@ void SetVariationsList(const std::vector<std::string>& variations) { |
base::debug::SetCrashKeyValue(kVariations, variations_string); |
} |
+void GetCrashKeysForCommandLineSwitches( |
+ std::vector<base::debug::CrashKey>* keys) { |
+ DCHECK(keys); |
+ base::debug::CrashKey crash_key = { kNumSwitches, kSmallSize }; |
+ keys->push_back(crash_key); |
+ |
+ // The fixed_keys names are string constants. Use static storage for |
+ // formatted key names as well, since they will persist for the duration of |
+ // the program. |
+ static char formatted_keys[kSwitchesMaxCount][sizeof(kSwitch) + 1] = {{ 0 }}; |
grt (UTC plus 2)
2015/11/27 18:51:21
oh my. this is an accident waiting to happen. size
Joe Mason
2015/11/27 21:16:47
Done.
|
+ const size_t formatted_key_len = sizeof(formatted_keys[0]); |
+ for (size_t i = 0; i < kSwitchesMaxCount; ++i) { |
+ // Name the keys using 1-based indexing. |
+ int n = base::snprintf(formatted_keys[i], formatted_key_len, kSwitch, |
+ i + 1); |
+ DCHECK_GT(n, 0); |
+ base::debug::CrashKey crash_key = { formatted_keys[i], kSmallSize }; |
+ keys->push_back(crash_key); |
+ } |
+} |
+ |
+namespace { |
+ |
+bool PassThroughFilter(const std::string &) { |
+ // By default do not reject any switches. |
+ return false; |
+} |
+ |
+} // namespace |
+ |
+void SetSwitchesFromCommandLine(const base::CommandLine& command_line) { |
+ SetSwitchesFromCommandLine(command_line, base::Bind(&PassThroughFilter)); |
+} |
+ |
+void SetSwitchesFromCommandLine(const base::CommandLine& command_line, |
+ const base::Callback<bool(const std::string &)>& skip_filter) { |
+ const base::CommandLine::StringVector& argv = command_line.argv(); |
+ |
+ // Set the number of switches in case size > kNumSwitches. |
+ base::debug::SetCrashKeyValue(kNumSwitches, |
+ base::StringPrintf("%" PRIuS, argv.size() - 1)); |
+ |
+ size_t key_i = 1; // Key names are 1-indexed. |
+ |
+ // Go through the argv, skipping the exec path. |
+ for (size_t i = 1; i < argv.size(); ++i) { |
+#if defined(OS_WIN) |
+ std::string switch_str = base::WideToUTF8(argv[i]); |
+#else |
+ std::string switch_str = argv[i]; |
+#endif |
+ |
+ // Skip uninteresting switches. |
+ if (skip_filter.Run(switch_str)) |
+ continue; |
+ |
+ // Stop if there are too many switches. |
+ if (i > crash_keys::kSwitchesMaxCount) |
grt (UTC plus 2)
2015/11/27 18:51:21
i -> key_i
Joe Mason
2015/11/27 21:16:47
Good catch! Fixed.
|
+ break; |
+ |
+ std::string key = base::StringPrintf(kSwitch, key_i++); |
+ base::debug::SetCrashKeyValue(key, switch_str); |
+ } |
+ |
+ // Clear any remaining switches. |
+ for (; key_i <= kSwitchesMaxCount; ++key_i) { |
grt (UTC plus 2)
2015/11/27 18:51:21
nit: omit braces. :-)
Joe Mason
2015/11/27 21:16:47
Done.
|
+ base::debug::ClearCrashKey(base::StringPrintf(kSwitch, key_i)); |
+ } |
+} |
+ |
} // namespace crash_keys |