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

Unified Diff: chrome/app/mash/mash_crash_keys.cc

Issue 2718123003: mash: Store chrome --mash crash key metadata in shared memory
Patch Set: rebase Created 3 years, 10 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: chrome/app/mash/mash_crash_keys.cc
diff --git a/chrome/app/mash/mash_crash_keys.cc b/chrome/app/mash/mash_crash_keys.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f611b5623009785b9d8dba32870a9a99e50e33c3
--- /dev/null
+++ b/chrome/app/mash/mash_crash_keys.cc
@@ -0,0 +1,123 @@
+// 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 "chrome/app/mash/mash_crash_keys.h"
+
+#include <fcntl.h> // For O_ constants.
+#include <stdlib.h>
+#include <sys/mman.h> // For shm_mem().
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include "base/debug/crash_logging.h"
+#include "base/logging.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.h"
+#include "breakpad/src/common/simple_string_dictionary.h"
+#include "components/crash/core/common/crash_keys.h"
+
+using google_breakpad::SimpleStringDictionary;
+
+namespace mash_crash_keys {
+namespace {
+
+// The size of the shared memory buffer for crash keys.
+const size_t kSharedMemorySize = sizeof(SimpleStringDictionary);
+
+// The shared memory name, including a trailing pid. The name is shared with
+// crash_reporter, see src/platform2/crash-reporter/user_collector.cc.
+const char kSharedMemoryNameFormat[] = "/chrome_crash_keys_%d";
+
+// File descriptor for the shared memory buffer containing the crash key
+// dictionary.
+int g_shared_memory_fd = -1;
+
+SimpleStringDictionary* g_crash_key_dictionary = nullptr;
+
+void SetCrashKey(const base::StringPiece& key, const base::StringPiece& value) {
+ g_crash_key_dictionary->SetKeyValue(key.data(), value.data());
hashimoto 2017/03/02 07:42:22 base/strings/string_piece.h says StrinbPiece::data
+}
+
+void ClearCrashKey(const base::StringPiece& key) {
+ g_crash_key_dictionary->RemoveKey(key.data());
hashimoto 2017/03/02 07:42:22 ditto.
+}
+
+void CreateSharedMemoryDictionary() {
+ CHECK(!g_crash_key_dictionary);
+
+ // Create a shared memory buffer with a well-known name. Chrome unlinks
+ // the shared memory buffer below for normal exit. The OS crash_reporter
+ // unlinks the buffer for crashes.
+ const std::string shared_memory_name =
+ base::StringPrintf(kSharedMemoryNameFormat, getpid());
+ const int oflag = O_CREAT | O_RDWR;
vapier 2017/03/11 06:14:59 i don't think this exec's, so should use O_CLOEXEC
+ // Make user-only read-write (not group or world). crash_reporter runs as root
+ // and can read the buffer regardless.
+ const mode_t mode = S_IRUSR | S_IWUSR;
vapier 2017/03/11 06:14:59 S_xxx constants aren't readable. just use an octa
+ g_shared_memory_fd = shm_open(shared_memory_name.c_str(), oflag, mode);
hashimoto 2017/03/02 07:42:22 Can't we just use utilities in base/memory/shared_
+ PCHECK(g_shared_memory_fd != -1);
+
+ // Set the size of the buffer. The bytes are automatically initialized to 0.
+ int result = ftruncate(g_shared_memory_fd, kSharedMemorySize);
hashimoto 2017/03/02 07:42:22 Please use HANDLE_EINTR. ftruncate may return EINT
+ PCHECK(result != -1);
+
+ // Map the buffer as read-write memory.
+ void* buffer = mmap(nullptr, kSharedMemorySize, PROT_READ | PROT_WRITE,
+ MAP_SHARED, g_shared_memory_fd, 0 /* offset */);
+ PCHECK(buffer != MAP_FAILED);
+
+ // Memory filled with 0 is a valid empty SimpleStringDictionary.
hashimoto 2017/03/02 07:42:22 Please use placement new, so that you don't have t
+ g_crash_key_dictionary = reinterpret_cast<SimpleStringDictionary*>(buffer);
+ DCHECK_EQ(0u, g_crash_key_dictionary->GetCount());
+}
+
+void RegisterCrashKeys() {
hashimoto 2017/03/02 07:42:22 If you want to allow processes which cannot depend
+ // Register keys used by non-browser processes launched by the service manager
+ // (e.g. the GPU service). See chrome/common/crash_keys.cc.
+ std::vector<base::debug::CrashKey> keys = {
+ {"url-chunk", crash_keys::kLargeSize},
hashimoto 2017/03/02 07:42:22 Please use the constants defined in the appropriat
+ {"total-discardable-memory-allocated", crash_keys::kSmallSize},
+ {"discardable-memory-free", crash_keys::kSmallSize},
+ };
+ crash_keys::GetCrashKeysForCommandLineSwitches(&keys);
+ base::debug::InitCrashKeys(&keys.at(0), keys.size(),
+ crash_keys::kChunkMaxLength);
+}
+
+} // namespace
+
+void Initialize() {
+ CHECK(!g_crash_key_dictionary);
+ CreateSharedMemoryDictionary();
+ RegisterCrashKeys();
+ base::debug::SetCrashKeyReportingFunctions(&SetCrashKey, &ClearCrashKey);
+}
+
+void Shutdown() {
+ CHECK(g_crash_key_dictionary);
+ int result = munmap(g_crash_key_dictionary, kSharedMemorySize);
+ PCHECK(result != -1);
+ g_crash_key_dictionary = nullptr;
+
+ result = close(g_shared_memory_fd);
+ PCHECK(result != -1);
+ g_shared_memory_fd = -1;
+
+ const std::string shared_memory_name =
+ base::StringPrintf(kSharedMemoryNameFormat, getpid());
+ result = shm_unlink(shared_memory_name.c_str());
+ PCHECK(result != -1);
+}
+
+int GetSharedMemoryFdForTesting() {
+ return g_shared_memory_fd;
+}
+
+size_t GetCrashKeyCountForTesting() {
+ return g_crash_key_dictionary->GetCount();
+}
+
+} // namespace mash_crash_keys

Powered by Google App Engine
This is Rietveld 408576698