diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 21:05:12 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 21:05:12 +0000 |
commit | 4f052883e187b34d47d6ffad7a9227517a02bd3c (patch) | |
tree | fe96c167a80e64df9cf7c51573156a29129b3267 | |
parent | 58b06ebe718ee0ac09a74e8c544b1cd65b3690e0 (diff) | |
download | chromium_src-4f052883e187b34d47d6ffad7a9227517a02bd3c.zip chromium_src-4f052883e187b34d47d6ffad7a9227517a02bd3c.tar.gz chromium_src-4f052883e187b34d47d6ffad7a9227517a02bd3c.tar.bz2 |
Set the active URL using the crash key system instead of platform-specific mechanisims.
This is a sort of canary to ensure that crash reports still contain the URL
on all platforms. If this is successful, then the rest of child_process_logging
can be replaced with this mechanism!
BUG=77656
TEST=Tomorrow's canary's crash reports still contain the active URL.
Review URL: https://chromiumcodereview.appspot.com/22819007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@218085 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/breakpad_linux.cc | 74 | ||||
-rw-r--r-- | chrome/app/breakpad_linux_impl.h | 7 | ||||
-rw-r--r-- | chrome/app/breakpad_win.cc | 42 | ||||
-rw-r--r-- | chrome/app/breakpad_win.h | 3 | ||||
-rw-r--r-- | chrome/browser/crash_handler_host_linux.cc | 38 | ||||
-rw-r--r-- | chrome/chrome_tests_unit.gypi | 1 | ||||
-rw-r--r-- | chrome/common/child_process_logging.h | 40 | ||||
-rw-r--r-- | chrome/common/child_process_logging_mac.mm | 43 | ||||
-rw-r--r-- | chrome/common/child_process_logging_mac_unittest.mm | 144 | ||||
-rw-r--r-- | chrome/common/child_process_logging_posix.cc | 7 | ||||
-rw-r--r-- | chrome/common/child_process_logging_win.cc | 20 | ||||
-rw-r--r-- | chrome/common/chrome_content_client.cc | 5 | ||||
-rw-r--r-- | chrome/common/crash_keys.cc | 6 | ||||
-rw-r--r-- | chrome/common/crash_keys.h | 3 |
14 files changed, 51 insertions, 382 deletions
diff --git a/chrome/app/breakpad_linux.cc b/chrome/app/breakpad_linux.cc index cf9d0c7..60e4fda 100644 --- a/chrome/app/breakpad_linux.cc +++ b/chrome/app/breakpad_linux.cc @@ -192,26 +192,19 @@ size_t LengthWithoutTrailingSpaces(const char* str, size_t len) { return len; } -// Populates the passed in allocated strings and their sizes with the GUID, -// crash url and distro of the crashing process. -// The passed strings are expected to be at least kGuidSize, kMaxActiveURLSize +// Populates the passed in allocated strings and their sizes with the GUID +// and distro of the crashing process. +// The passed strings are expected to be at least kGuidSize // and kDistroSize bytes long respectively. -void PopulateGUIDAndURLAndDistro(char* guid, size_t* guid_len_param, - char* crash_url, size_t* crash_url_len_param, - char* distro, size_t* distro_len_param) { +void PopulateGUIDAndDistro(char* guid, size_t* guid_len_param, + char* distro, size_t* distro_len_param) { size_t guid_len = std::min(my_strlen(child_process_logging::g_client_id), kGuidSize); - size_t crash_url_len = - std::min(my_strlen(child_process_logging::g_active_url), - kMaxActiveURLSize); size_t distro_len = std::min(my_strlen(base::g_linux_distro), kDistroSize); memcpy(guid, child_process_logging::g_client_id, guid_len); - memcpy(crash_url, child_process_logging::g_active_url, crash_url_len); memcpy(distro, base::g_linux_distro, distro_len); if (guid_len_param) *guid_len_param = guid_len; - if (crash_url_len_param) - *crash_url_len_param = crash_url_len; if (distro_len_param) *distro_len_param = distro_len; } @@ -594,8 +587,6 @@ bool CrashDone(const MinidumpDescriptor& minidump, #endif info.process_type = "browser"; info.process_type_length = 7; - info.crash_url = NULL; - info.crash_url_length = 0; info.guid = child_process_logging::g_client_id; info.guid_length = my_strlen(child_process_logging::g_client_id); info.distro = base::g_linux_distro; @@ -700,26 +691,22 @@ bool CrashDoneInProcessNoUpload( // Start constructing the message to send to the browser. char guid[kGuidSize + 1] = {0}; - char crash_url[kMaxActiveURLSize + 1] = {0}; char distro[kDistroSize + 1] = {0}; size_t guid_length = 0; - size_t crash_url_length = 0; size_t distro_length = 0; - PopulateGUIDAndURLAndDistro(guid, &guid_length, crash_url, &crash_url_length, - distro, &distro_length); + PopulateGUIDAndDistro(guid, &guid_length, distro, &distro_length); BreakpadInfo info = {0}; info.filename = NULL; info.fd = descriptor.fd(); info.process_type = g_process_type; info.process_type_length = my_strlen(g_process_type); - info.crash_url = crash_url; - info.crash_url_length = crash_url_length; info.guid = guid; info.guid_length = guid_length; info.distro = distro; info.distro_length = distro_length; info.upload = false; info.process_start_time = g_process_start_time; + info.crash_keys = g_crash_keys; HandleCrashDump(info); return FinalizeCrashDoneAndroid(); } @@ -771,9 +758,8 @@ bool NonBrowserCrashHandler(const void* crash_context, // Start constructing the message to send to the browser. char guid[kGuidSize + 1] = {0}; - char crash_url[kMaxActiveURLSize + 1] = {0}; char distro[kDistroSize + 1] = {0}; - PopulateGUIDAndURLAndDistro(guid, NULL, crash_url, NULL, distro, NULL); + PopulateGUIDAndDistro(guid, NULL, distro, NULL); char b; // Dummy variable for sys_read below. const char* b_addr = &b; // Get the address of |b| so we can create the @@ -792,26 +778,24 @@ bool NonBrowserCrashHandler(const void* crash_context, iov[0].iov_len = crash_context_size; iov[1].iov_base = guid; iov[1].iov_len = kGuidSize + 1; - iov[2].iov_base = crash_url; - iov[2].iov_len = kMaxActiveURLSize + 1; - iov[3].iov_base = distro; - iov[3].iov_len = kDistroSize + 1; - iov[4].iov_base = &b_addr; - iov[4].iov_len = sizeof(b_addr); - iov[5].iov_base = &fds[0]; - iov[5].iov_len = sizeof(fds[0]); - iov[6].iov_base = &g_process_start_time; - iov[6].iov_len = sizeof(g_process_start_time); - iov[7].iov_base = &base::g_oom_size; - iov[7].iov_len = sizeof(base::g_oom_size); + iov[2].iov_base = distro; + iov[2].iov_len = kDistroSize + 1; + iov[3].iov_base = &b_addr; + iov[3].iov_len = sizeof(b_addr); + iov[4].iov_base = &fds[0]; + iov[4].iov_len = sizeof(fds[0]); + iov[5].iov_base = &g_process_start_time; + iov[5].iov_len = sizeof(g_process_start_time); + iov[6].iov_base = &base::g_oom_size; + iov[6].iov_len = sizeof(base::g_oom_size); google_breakpad::SerializedNonAllocatingMap* serialized_map; - iov[8].iov_len = g_crash_keys->Serialize( + iov[7].iov_len = g_crash_keys->Serialize( const_cast<const google_breakpad::SerializedNonAllocatingMap**>( &serialized_map)); - iov[8].iov_base = serialized_map; + iov[7].iov_base = serialized_map; #if defined(ADDRESS_SANITIZER) - iov[9].iov_base = const_cast<char*>(g_asan_report_str); - iov[9].iov_len = kMaxAsanReportSize + 1; + iov[8].iov_base = const_cast<char*>(g_asan_report_str); + iov[8].iov_len = kMaxAsanReportSize + 1; #endif msg.msg_iov = iov; @@ -1178,11 +1162,6 @@ void HandleCrashDump(const BreakpadInfo& info) { // abcdef \r\n // BOUNDARY \r\n // - // zero or more: - // Content-Disposition: form-data; name="url-chunk-1" \r\n \r\n - // abcdef \r\n - // BOUNDARY \r\n - // // zero or one: // Content-Disposition: form-data; name="channel" \r\n \r\n // beta \r\n @@ -1357,15 +1336,6 @@ void HandleCrashDump(const BreakpadInfo& info) { writer.Flush(); } - // For renderers and plugins. - if (info.crash_url_length) { - static const char url_chunk_msg[] = "url-chunk-"; - static const unsigned kMaxUrlLength = 8 * MimeWriter::kMaxCrashChunkSize; - writer.AddPairDataInChunks(url_chunk_msg, sizeof(url_chunk_msg) - 1, - info.crash_url, std::min(info.crash_url_length, kMaxUrlLength), - MimeWriter::kMaxCrashChunkSize, false /* Don't strip whitespaces. */); - } - if (*child_process_logging::g_channel) { writer.AddPairString("channel", child_process_logging::g_channel); writer.AddBoundary(); diff --git a/chrome/app/breakpad_linux_impl.h b/chrome/app/breakpad_linux_impl.h index f9c9d92..f82f81d 100644 --- a/chrome/app/breakpad_linux_impl.h +++ b/chrome/app/breakpad_linux_impl.h @@ -17,7 +17,6 @@ typedef google_breakpad::NonAllocatingMap<256, 256, 64> CrashKeyStorage; -static const size_t kMaxActiveURLSize = 1024; static const size_t kGuidSize = 32; // 128 bits = 32 chars in hex. static const size_t kDistroSize = 128; #if defined(ADDRESS_SANITIZER) @@ -31,10 +30,10 @@ static const off_t kMaxMinidumpFileSize = 1258291; // The size of the iovec used to transfer crash data from a child back to the // browser. #if !defined(ADDRESS_SANITIZER) -const size_t kCrashIovSize = 9; +const size_t kCrashIovSize = 8; #else // Additional field to pass the AddressSanitizer log to the crash handler. -const size_t kCrashIovSize = 10; +const size_t kCrashIovSize = 9; #endif // BreakpadInfo describes a crash report. @@ -50,8 +49,6 @@ struct BreakpadInfo { #endif const char* process_type; // Process type, e.g. "renderer". unsigned process_type_length; // Length of |process_type|. - const char* crash_url; // Active URL in the crashing process. - unsigned crash_url_length; // Length of |crash_url|. const char* guid; // Client ID. unsigned guid_length; // Length of |guid|. const char* distro; // Linux distro string. diff --git a/chrome/app/breakpad_win.cc b/chrome/app/breakpad_win.cc index 0cb2813..d16f7ce 100644 --- a/chrome/app/breakpad_win.cc +++ b/chrome/app/breakpad_win.cc @@ -100,7 +100,6 @@ typedef NTSTATUS (WINAPI* NtTerminateProcessPtr)(HANDLE ProcessHandle, NTSTATUS ExitStatus); char* g_real_terminate_process_stub = NULL; -static size_t g_url_chunks_offset = 0; static size_t g_num_of_extensions_offset = 0; static size_t g_extension_ids_offset = 0; static size_t g_client_id_offset = 0; @@ -461,15 +460,6 @@ google_breakpad::CustomClientInfo* GetCustomInfo(const std::wstring& exe_path, g_num_of_views_offset = g_custom_entries->size(); g_custom_entries->push_back( google_breakpad::CustomInfoEntry(L"num-views", L"")); - // Create entries for the URL. Currently we only allow each chunk to be 64 - // characters, which isn't enough for a URL. As a hack we create 8 entries - // and split the URL across the g_custom_entries. - g_url_chunks_offset = g_custom_entries->size(); - // one-based index for the name suffix. - for (int i = 1; i <= kMaxUrlChunks; ++i) { - g_custom_entries->push_back(google_breakpad::CustomInfoEntry( - base::StringPrintf(L"url-chunk-%i", i).c_str(), L"")); - } if (type == L"plugin" || type == L"ppapi") { std::wstring plugin_path = @@ -615,38 +605,6 @@ long WINAPI ServiceExceptionFilter(EXCEPTION_POINTERS* info) { return EXCEPTION_EXECUTE_HANDLER; } -extern "C" void __declspec(dllexport) __cdecl SetActiveURL( - const wchar_t* url_cstring) { - DCHECK(url_cstring); - - if (!g_custom_entries) - return; - - std::wstring url(url_cstring); - size_t chunk_index = 0; - size_t url_size = url.size(); - - // Split the url across all the chunks. - for (size_t url_offset = 0; - chunk_index < kMaxUrlChunks && url_offset < url_size; ++chunk_index) { - size_t current_chunk_size = std::min(url_size - url_offset, - static_cast<size_t>( - google_breakpad::CustomInfoEntry::kValueMaxLength - 1)); - - wchar_t* entry_value = - (*g_custom_entries)[g_url_chunks_offset + chunk_index].value; - url._Copy_s(entry_value, - google_breakpad::CustomInfoEntry::kValueMaxLength, - current_chunk_size, url_offset); - entry_value[current_chunk_size] = L'\0'; - url_offset += current_chunk_size; - } - - // And null terminate any unneeded chunks. - for (; chunk_index < kMaxUrlChunks; ++chunk_index) - (*g_custom_entries)[g_url_chunks_offset + chunk_index].value[0] = L'\0'; -} - extern "C" void __declspec(dllexport) __cdecl SetClientId( const wchar_t* client_id) { if (client_id == NULL) diff --git a/chrome/app/breakpad_win.h b/chrome/app/breakpad_win.h index 96e0ef3..0514d4e 100644 --- a/chrome/app/breakpad_win.h +++ b/chrome/app/breakpad_win.h @@ -28,9 +28,6 @@ extern size_t g_experiment_chunks_offset; } // namespace breakpad_win -// The maximum number of 64-char URL chunks we will report. -static const int kMaxUrlChunks = 8; - void InitCrashReporter(); // Intercepts a crash but does not process it, just ask if we want to restart diff --git a/chrome/browser/crash_handler_host_linux.cc b/chrome/browser/crash_handler_host_linux.cc index 27ad89b..4fce401 100644 --- a/chrome/browser/crash_handler_host_linux.cc +++ b/chrome/browser/crash_handler_host_linux.cc @@ -57,7 +57,6 @@ void CrashDumpTask(CrashHandlerHostLinux* handler, BreakpadInfo* info) { HandleCrashDump(*info); delete[] info->filename; delete[] info->process_type; - delete[] info->crash_url; delete[] info->guid; delete[] info->distro; delete info->crash_keys; @@ -136,7 +135,6 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { char* crash_context = new char[kCrashContextSize]; // Freed in CrashDumpTask(); char* guid = new char[kGuidSize + 1]; - char* crash_url = new char[kMaxActiveURLSize + 1]; char* distro = new char[kDistroSize + 1]; #if defined(ADDRESS_SANITIZER) asan_report_str_ = new char[kMaxAsanReportSize + 1]; @@ -157,7 +155,6 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { const ssize_t expected_msg_size = kCrashContextSize + kGuidSize + 1 + - kMaxActiveURLSize + 1 + kDistroSize + 1 + sizeof(tid_buf_addr) + sizeof(tid_fd) + sizeof(uptime) + @@ -170,23 +167,21 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { iov[0].iov_len = kCrashContextSize; iov[1].iov_base = guid; iov[1].iov_len = kGuidSize + 1; - iov[2].iov_base = crash_url; - iov[2].iov_len = kMaxActiveURLSize + 1; - iov[3].iov_base = distro; - iov[3].iov_len = kDistroSize + 1; - iov[4].iov_base = &tid_buf_addr; - iov[4].iov_len = sizeof(tid_buf_addr); - iov[5].iov_base = &tid_fd; - iov[5].iov_len = sizeof(tid_fd); - iov[6].iov_base = &uptime; - iov[6].iov_len = sizeof(uptime); - iov[7].iov_base = &oom_size; - iov[7].iov_len = sizeof(oom_size); - iov[8].iov_base = serialized_crash_keys; - iov[8].iov_len = crash_keys_size; + iov[2].iov_base = distro; + iov[2].iov_len = kDistroSize + 1; + iov[3].iov_base = &tid_buf_addr; + iov[3].iov_len = sizeof(tid_buf_addr); + iov[4].iov_base = &tid_fd; + iov[4].iov_len = sizeof(tid_fd); + iov[5].iov_base = &uptime; + iov[5].iov_len = sizeof(uptime); + iov[6].iov_base = &oom_size; + iov[6].iov_len = sizeof(oom_size); + iov[7].iov_base = serialized_crash_keys; + iov[7].iov_len = crash_keys_size; #if defined(ADDRESS_SANITIZER) - iov[9].iov_base = asan_report_str_; - iov[9].iov_len = kMaxAsanReportSize + 1; + iov[8].iov_base = asan_report_str_; + iov[8].iov_len = kMaxAsanReportSize + 1; #endif msg.msg_iov = iov; msg.msg_iovlen = kCrashIovSize; @@ -324,7 +319,7 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { bad_context->tid = crashing_tid; // Sanitize the string data a bit more - guid[kGuidSize] = crash_url[kMaxActiveURLSize] = distro[kDistroSize] = 0; + guid[kGuidSize] = distro[kDistroSize] = 0; // Freed in CrashDumpTask(); BreakpadInfo* info = new BreakpadInfo; @@ -336,9 +331,6 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) { process_type_str[info->process_type_length] = '\0'; info->process_type = process_type_str; - info->crash_url_length = strlen(crash_url); - info->crash_url = crash_url; - info->guid_length = strlen(guid); info->guid = guid; diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 89acb7f..9d6ea1a 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1683,7 +1683,6 @@ 'browser/webdata/token_service_table_unittest.cc', 'browser/webdata/web_apps_table_unittest.cc', 'common/cancelable_task_tracker_unittest.cc', - 'common/child_process_logging_mac_unittest.mm', 'common/chrome_paths_unittest.cc', 'common/cloud_print/cloud_print_helpers_unittest.cc', 'common/chrome_content_client_unittest.cc', diff --git a/chrome/common/child_process_logging.h b/chrome/common/child_process_logging.h index d267e38..21a12bb 100644 --- a/chrome/common/child_process_logging.h +++ b/chrome/common/child_process_logging.h @@ -12,7 +12,6 @@ #include "base/basictypes.h" #include "base/debug/crash_logging.h" #include "base/strings/string16.h" -#include "url/gurl.h" class CommandLine; @@ -50,7 +49,6 @@ namespace child_process_logging { #if defined(OS_POSIX) && !defined(OS_MACOSX) // These are declared here so the crash reporter can access them directly in // compromised context without going through the standard library. -extern char g_active_url[]; extern char g_channel[]; extern char g_client_id[]; extern char g_extension_ids[]; @@ -79,10 +77,6 @@ static const size_t kSwitchLen = 64; static const size_t kPrinterInfoStrLen = 64; #endif -// Sets the URL that is logged if the child process crashes. Use GURL() to clear -// the URL. -void SetActiveURL(const GURL& url); - // Sets the Client ID that is used as GUID if a Chrome process crashes. void SetClientId(const std::string& client_id); @@ -121,22 +115,6 @@ void SetExperimentList(const std::vector<string16>& state); void SetChannel(const std::string& channel); #endif -// Simple wrapper class that sets the active URL in it's constructor and clears -// the active URL in the destructor. -class ScopedActiveURLSetter { - public: - explicit ScopedActiveURLSetter(const GURL& url) { - SetActiveURL(url); - } - - ~ScopedActiveURLSetter() { - SetActiveURL(GURL()); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedActiveURLSetter); -}; - // Set/clear information about currently accessed printer. class ScopedPrinterInfoSetter { public: @@ -154,29 +132,13 @@ class ScopedPrinterInfoSetter { } // namespace child_process_logging -#if defined(OS_MACOSX) - -namespace child_process_logging { - -void SetActiveURLImpl(const GURL& url, - base::debug::SetCrashKeyValueFuncT set_key_func, - base::debug::ClearCrashKeyValueFuncT clear_key_func); - -extern const size_t kMaxNumCrashURLChunks; -extern const size_t kMaxNumURLChunkValueLength; -extern const char* kUrlChunkFormatStr; - -} // namespace child_process_logging - -#endif // defined(OS_MACOSX) - #if defined(OS_WIN) namespace child_process_logging { // Sets up the base/debug/crash_logging.h mechanism. void Init(); -} // namespace child_process_loggging +} // namespace child_process_logging #endif // defined(OS_WIN) #endif // CHROME_COMMON_CHILD_PROCESS_LOGGING_H_ diff --git a/chrome/common/child_process_logging_mac.mm b/chrome/common/child_process_logging_mac.mm index 6877e0d..da7c7fe 100644 --- a/chrome/common/child_process_logging_mac.mm +++ b/chrome/common/child_process_logging_mac.mm @@ -16,7 +16,6 @@ #include "chrome/common/metrics/variations/variations_util.h" #include "chrome/installer/util/google_update_settings.h" #include "gpu/config/gpu_info.h" -#include "url/gurl.h" namespace child_process_logging { @@ -25,9 +24,6 @@ using base::debug::ClearCrashKeyValueFuncT; using base::debug::SetCrashKeyValue; using base::debug::ClearCrashKey; -const size_t kMaxNumCrashURLChunks = 8; -const size_t kMaxNumURLChunkValueLength = 255; -const char* kUrlChunkFormatStr = "url-chunk-%d"; const char* kGuidParamName = "guid"; const char* kGPUVendorIdParamName = "gpu-venid"; const char* kGPUDeviceIdParamName = "gpu-devid"; @@ -44,50 +40,11 @@ const char* kPrinterInfoNameFormat = "prn-info-%zu"; static const size_t kClientIdSize = 32 + 1; static char g_client_id[kClientIdSize]; -void SetActiveURLImpl(const GURL& url, - SetCrashKeyValueFuncT set_key_func, - ClearCrashKeyValueFuncT clear_key_func) { - // First remove any old url chunks we might have lying around. - for (size_t i = 0; i < kMaxNumCrashURLChunks; i++) { - // On Windows the url-chunk items are 1-based, so match that. - clear_key_func(base::StringPrintf(kUrlChunkFormatStr, i + 1)); - } - - const std::string& raw_url = url.possibly_invalid_spec(); - size_t raw_url_length = raw_url.length(); - - // Bail on zero-length URLs. - if (raw_url_length == 0) { - return; - } - - // Parcel the URL up into up to 8, 255 byte segments. - size_t offset = 0; - for (size_t i = 0; - i < kMaxNumCrashURLChunks && offset < raw_url_length; - ++i) { - - // On Windows the url-chunk items are 1-based, so match that. - std::string key = base::StringPrintf(kUrlChunkFormatStr, i + 1); - size_t length = std::min(kMaxNumURLChunkValueLength, - raw_url_length - offset); - std::string value = raw_url.substr(offset, length); - set_key_func(key, value); - - // Next chunk. - offset += kMaxNumURLChunkValueLength; - } -} - void SetClientIdImpl(const std::string& client_id, SetCrashKeyValueFuncT set_key_func) { set_key_func(kGuidParamName, client_id); } -void SetActiveURL(const GURL& url) { - SetActiveURLImpl(url, SetCrashKeyValue, ClearCrashKey); -} - void SetClientId(const std::string& client_id) { std::string str(client_id); ReplaceSubstringsAfterOffset(&str, 0, "-", ""); diff --git a/chrome/common/child_process_logging_mac_unittest.mm b/chrome/common/child_process_logging_mac_unittest.mm deleted file mode 100644 index bdd93b9..0000000 --- a/chrome/common/child_process_logging_mac_unittest.mm +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2011 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/common/child_process_logging.h" - -#include <map> -#include <string> - -#import <Foundation/Foundation.h> - -#include "base/debug/crash_logging.h" -#include "base/logging.h" -#include "base/strings/stringprintf.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -typedef PlatformTest ChildProcessLoggingTest; - -namespace { - -// Class to mock breakpad's setkeyvalue/clearkeyvalue functions needed for -// SetActiveRendererURLImpl. -// The Keys are stored in a static dictionary and methods are provided to -// verify correctness. -class MockBreakpadKeyValueStore { - public: - MockBreakpadKeyValueStore() { - // Only one of these objects can be active at once. - DCHECK(dict == NULL); - dict = new std::map<std::string, std::string>; - } - - ~MockBreakpadKeyValueStore() { - // Only one of these objects can be active at once. - DCHECK(dict != NULL); - delete dict; - dict = NULL; - } - - static void SetKeyValue(const base::StringPiece& key, - const base::StringPiece& value) { - DCHECK(dict != NULL); - (*dict)[key.as_string()] = value.as_string(); - } - - static void ClearKeyValue(const base::StringPiece& key) { - DCHECK(dict != NULL); - dict->erase(key.as_string()); - } - - size_t CountDictionaryEntries() { - return dict->size(); - } - - bool VerifyDictionaryContents(const std::string& url) { - using child_process_logging::kMaxNumCrashURLChunks; - using child_process_logging::kMaxNumURLChunkValueLength; - using child_process_logging::kUrlChunkFormatStr; - - size_t num_url_chunks = CountDictionaryEntries(); - EXPECT_LE(num_url_chunks, kMaxNumCrashURLChunks); - - std::string accumulated_url; - for (size_t i = 0; i < num_url_chunks; ++i) { - // URL chunk names are 1-based. - std::string key = base::StringPrintf(kUrlChunkFormatStr, i + 1); - std::string value = (*dict)[key]; - EXPECT_GT(value.length(), 0u); - EXPECT_LE(value.length(), - static_cast<size_t>(kMaxNumURLChunkValueLength)); - accumulated_url += value; - } - - return url == accumulated_url; - } - - private: - static std::map<std::string, std::string>* dict; - DISALLOW_COPY_AND_ASSIGN(MockBreakpadKeyValueStore); -}; - -// static -std::map<std::string, std::string>* MockBreakpadKeyValueStore::dict; - -} // namespace - -// Call through to SetActiveURLImpl using the functions from -// MockBreakpadKeyValueStore. -void SetActiveURLWithMock(const GURL& url) { - using child_process_logging::SetActiveURLImpl; - - base::debug::SetCrashKeyValueFuncT setFunc = - MockBreakpadKeyValueStore::SetKeyValue; - base::debug::ClearCrashKeyValueFuncT clearFunc = - MockBreakpadKeyValueStore::ClearKeyValue; - - SetActiveURLImpl(url, setFunc, clearFunc); -} - -TEST_F(ChildProcessLoggingTest, TestUrlSplitting) { - using child_process_logging::kMaxNumCrashURLChunks; - using child_process_logging::kMaxNumURLChunkValueLength; - - const std::string short_url("http://abc/"); - std::string long_url("http://"); - std::string overflow_url("http://"); - - long_url += std::string(kMaxNumURLChunkValueLength * 2, 'a'); - long_url += "/"; - - int max_num_chars_stored_in_dump = kMaxNumURLChunkValueLength * - kMaxNumCrashURLChunks; - overflow_url += std::string(max_num_chars_stored_in_dump + 1, 'a'); - overflow_url += "/"; - - // Check that Clearing NULL URL works. - MockBreakpadKeyValueStore mock; - SetActiveURLWithMock(GURL()); - EXPECT_EQ(0u, mock.CountDictionaryEntries()); - - // Check that we can set a URL. - SetActiveURLWithMock(GURL(short_url.c_str())); - EXPECT_TRUE(mock.VerifyDictionaryContents(short_url)); - EXPECT_EQ(1u, mock.CountDictionaryEntries()); - SetActiveURLWithMock(GURL()); - EXPECT_EQ(0u, mock.CountDictionaryEntries()); - - // Check that we can replace a long url with a short url. - SetActiveURLWithMock(GURL(long_url.c_str())); - EXPECT_TRUE(mock.VerifyDictionaryContents(long_url)); - SetActiveURLWithMock(GURL(short_url.c_str())); - EXPECT_TRUE(mock.VerifyDictionaryContents(short_url)); - SetActiveURLWithMock(GURL()); - EXPECT_EQ(0u, mock.CountDictionaryEntries()); - - - // Check that overflow works correctly. - SetActiveURLWithMock(GURL(overflow_url.c_str())); - EXPECT_TRUE(mock.VerifyDictionaryContents( - overflow_url.substr(0, max_num_chars_stored_in_dump))); - SetActiveURLWithMock(GURL()); - EXPECT_EQ(0u, mock.CountDictionaryEntries()); -} diff --git a/chrome/common/child_process_logging_posix.cc b/chrome/common/child_process_logging_posix.cc index a9dd3dc..fa1748b 100644 --- a/chrome/common/child_process_logging_posix.cc +++ b/chrome/common/child_process_logging_posix.cc @@ -18,14 +18,12 @@ namespace child_process_logging { // Account for the terminating null character. -static const size_t kMaxActiveURLSize = 1024 + 1; static const size_t kClientIdSize = 32 + 1; static const size_t kChannelSize = 32; // We use static strings to hold the most recent active url and the client // identifier. If we crash, the crash handler code will send the contents of // these strings to the browser. -char g_active_url[kMaxActiveURLSize]; char g_client_id[kClientIdSize]; char g_channel[kChannelSize] = ""; @@ -59,11 +57,6 @@ static const size_t kMaxVariationChunksSize = kMaxVariationChunkSize * kMaxReportedVariationChunks + 1; char g_variation_chunks[kMaxVariationChunksSize] = ""; -void SetActiveURL(const GURL& url) { - base::strlcpy(g_active_url, url.possibly_invalid_spec().c_str(), - arraysize(g_active_url)); -} - void SetClientId(const std::string& client_id) { std::string str(client_id); ReplaceSubstringsAfterOffset(&str, 0, "-", std::string()); diff --git a/chrome/common/child_process_logging_win.cc b/chrome/common/child_process_logging_win.cc index 1d73174..8e6c9b5 100644 --- a/chrome/common/child_process_logging_win.cc +++ b/chrome/common/child_process_logging_win.cc @@ -16,15 +16,11 @@ #include "chrome/common/metrics/variations/variations_util.h" #include "chrome/installer/util/google_update_settings.h" #include "gpu/config/gpu_info.h" -#include "url/gurl.h" namespace child_process_logging { namespace { -// exported in breakpad_win.cc: void __declspec(dllexport) __cdecl SetActiveURL. -typedef void (__cdecl *MainSetActiveURL)(const wchar_t*); - // exported in breakpad_win.cc: void __declspec(dllexport) __cdecl SetClientId. typedef void (__cdecl *MainSetClientId)(const wchar_t*); @@ -77,22 +73,6 @@ void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings, } // namespace -void SetActiveURL(const GURL& url) { - static MainSetActiveURL set_active_url = NULL; - // note: benign race condition on set_active_url. - if (!set_active_url) { - HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName); - if (!exe_module) - return; - set_active_url = reinterpret_cast<MainSetActiveURL>( - GetProcAddress(exe_module, "SetActiveURL")); - if (!set_active_url) - return; - } - - (set_active_url)(UTF8ToWide(url.possibly_invalid_spec()).c_str()); -} - void SetClientId(const std::string& client_id) { std::string str(client_id); // Remove all instance of '-' char from the GUID. So BCD-WXY becomes BCDWXY. diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index 1eb9c10..46f4069 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc @@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/cpu.h" +#include "base/debug/crash_logging.h" #include "base/file_util.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" @@ -18,6 +19,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_version_info.h" +#include "chrome/common/crash_keys.h" #include "chrome/common/pepper_flash.h" #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" @@ -385,7 +387,8 @@ bool GetBundledPepperFlash(content::PepperPluginInfo* plugin) { namespace chrome { void ChromeContentClient::SetActiveURL(const GURL& url) { - child_process_logging::SetActiveURL(url); + base::debug::SetCrashKeyValue(crash_keys::kActiveURL, + url.possibly_invalid_spec()); } void ChromeContentClient::SetGpuInfo(const gpu::GPUInfo& gpu_info) { diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc index 691e87754..eae2403 100644 --- a/chrome/common/crash_keys.cc +++ b/chrome/common/crash_keys.cc @@ -45,8 +45,8 @@ COMPILE_ASSERT(kMediumSize <= kSingleChunkLength, size_t RegisterChromeCrashKeys() { base::debug::CrashKey keys[] = { - // TODO(rsesek): Remove when done testing. Needed so arraysize > 0. - { "rsesek_key", kSmallSize }, + { kActiveURL, kLargeSize }, + // content/: { "ppapi_path", kMediumSize }, { "subresource_url", kLargeSize }, @@ -72,6 +72,8 @@ size_t RegisterChromeCrashKeys() { return base::debug::InitCrashKeys(keys, arraysize(keys), kSingleChunkLength); } +const char kActiveURL[] = "url-chunk"; + #if defined(OS_MACOSX) namespace mac { diff --git a/chrome/common/crash_keys.h b/chrome/common/crash_keys.h index 4111eb6..941a828 100644 --- a/chrome/common/crash_keys.h +++ b/chrome/common/crash_keys.h @@ -15,6 +15,9 @@ size_t RegisterChromeCrashKeys(); // Crash Key Name Constants //////////////////////////////////////////////////// +// The URL of the active tab. +extern const char kActiveURL[]; + #if defined(OS_MACOSX) namespace mac { |