summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-04 23:51:33 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-04 23:51:33 +0000
commitac77fbc08a0bedbadb29372a8fe1fe2fc4fbdbb6 (patch)
treebf658fd019d8e1bd7d85fcf266df298d730fca7e
parent6b050c31bd9ac75c9b31f7a70e07018af739a5ce (diff)
downloadchromium_src-ac77fbc08a0bedbadb29372a8fe1fe2fc4fbdbb6.zip
chromium_src-ac77fbc08a0bedbadb29372a8fe1fe2fc4fbdbb6.tar.gz
chromium_src-ac77fbc08a0bedbadb29372a8fe1fe2fc4fbdbb6.tar.bz2
Linux: Record the list of plugins loaded in browser process crash reports.
BUG=none TEST=none Review URL: http://codereview.chromium.org/459015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33888 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/DEPS1
-rw-r--r--chrome/app/breakpad_linux.cc55
-rw-r--r--chrome/app/breakpad_linux.h2
-rw-r--r--chrome/browser/crash_handler_host_linux.cc2
-rw-r--r--webkit/glue/plugins/plugin_list.cc31
-rw-r--r--webkit/glue/plugins/plugin_list.h17
-rw-r--r--webkit/glue/plugins/plugin_list_win.cc12
7 files changed, 105 insertions, 15 deletions
diff --git a/chrome/app/DEPS b/chrome/app/DEPS
index ef4974d..5bdf2b6 100644
--- a/chrome/app/DEPS
+++ b/chrome/app/DEPS
@@ -4,4 +4,5 @@ include_rules = [
"+chrome/installer",
"+sandbox",
"+tools/memory_watcher",
+ "+webkit/glue/plugins", # For GetPluginList() on Linux.
]
diff --git a/chrome/app/breakpad_linux.cc b/chrome/app/breakpad_linux.cc
index 80fc81f..891201e0 100644
--- a/chrome/app/breakpad_linux.cc
+++ b/chrome/app/breakpad_linux.cc
@@ -33,6 +33,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/installer/util/google_update_settings.h"
+#include "webkit/glue/plugins/plugin_list.h"
static const char kUploadURL[] =
"https://clients2.google.com/cr/report";
@@ -205,6 +206,11 @@ pid_t HandleCrashDump(const BreakpadInfo& info) {
// BOUNDARY \r\n (7, 8)
//
// zero or more:
+ // Content-Disposition: form-data; name="plugin-chunk-1" \r\n \r\n (0..5)
+ // abcdef \r\n (6, 7)
+ // BOUNDARY \r\n (8, 9)
+ //
+ // zero or more:
// Content-Disposition: form-data; name="url-chunk-1" \r\n \r\n (0..5)
// abcdef \r\n (6, 7)
// BOUNDARY \r\n (8, 9)
@@ -229,6 +235,7 @@ pid_t HandleCrashDump(const BreakpadInfo& info) {
static const char dump_msg[] = "upload_file_minidump\"; filename=\"dump\"";
static const char content_type_msg[] =
"Content-Type: application/octet-stream";
+ static const char plugin_chunk_msg[] = "plugin-chunk-";
static const char url_chunk_msg[] = "url-chunk-";
static const char process_time_msg[] = "ptime";
static const char process_type_msg[] = "ptype";
@@ -388,6 +395,51 @@ pid_t HandleCrashDump(const BreakpadInfo& info) {
sys_writev(fd, iov, 9);
}
+ // For browser process.
+ if (info.plugin_list_length) {
+ unsigned i = 0, done = 0, plugin_length = info.plugin_list_length;
+ static const unsigned kMaxPluginChunkSize = 64;
+ static const unsigned kMaxPluginLength = 8 * kMaxPluginChunkSize;
+ if (plugin_length > kMaxPluginLength)
+ plugin_length = kMaxPluginLength;
+
+ while (plugin_length) {
+ char num[16];
+ const unsigned num_len = my_int_len(++i);
+ my_itos(num, i, num_len);
+
+ iov[0].iov_base = const_cast<char*>(form_data_msg);
+ iov[0].iov_len = sizeof(form_data_msg) - 1;
+ iov[1].iov_base = const_cast<char*>(plugin_chunk_msg);
+ iov[1].iov_len = sizeof(plugin_chunk_msg) - 1;
+ iov[2].iov_base = num;
+ iov[2].iov_len = num_len;
+ iov[3].iov_base = const_cast<char*>(quote_msg);
+ iov[3].iov_len = sizeof(quote_msg);
+ iov[4].iov_base = const_cast<char*>(rn);
+ iov[4].iov_len = sizeof(rn);
+ iov[5].iov_base = const_cast<char*>(rn);
+ iov[5].iov_len = sizeof(rn);
+
+ const unsigned len = plugin_length > kMaxPluginChunkSize ?
+ kMaxPluginChunkSize : plugin_length;
+ iov[6].iov_base = const_cast<char*>(info.plugin_list + done);
+ iov[6].iov_len = len;
+ iov[7].iov_base = const_cast<char*>(rn);
+ iov[7].iov_len = sizeof(rn);
+ iov[8].iov_base = mime_boundary;
+ iov[8].iov_len = sizeof(mime_boundary) - 1;
+ iov[9].iov_base = const_cast<char*>(rn);
+ iov[9].iov_len = sizeof(rn);
+
+ sys_writev(fd, iov, 10);
+
+ done += len;
+ plugin_length -= len;
+ }
+ }
+
+ // For rendererers and plugins.
if (info.crash_url_length) {
unsigned i = 0, done = 0, crash_url_length = info.crash_url_length;
static const unsigned kMaxCrashChunkSize = 64;
@@ -593,6 +645,7 @@ static bool CrashDone(const char* dump_path,
memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4);
path[dump_path_len + 1 + minidump_id_len + 4] = 0;
+ std::string* plugin_list = NPAPI::PluginList::GetLoadedPlugins();
BreakpadInfo info;
info.filename = path;
info.process_type = "browser";
@@ -603,6 +656,8 @@ static bool CrashDone(const char* dump_path,
info.guid_length = google_update::posix_guid.length();
info.distro = base::linux_distro.data();
info.distro_length = base::linux_distro.length();
+ info.plugin_list = plugin_list->data();
+ info.plugin_list_length = plugin_list->length();
info.upload = upload;
HandleCrashDump(info);
diff --git a/chrome/app/breakpad_linux.h b/chrome/app/breakpad_linux.h
index fef9079..4e52257 100644
--- a/chrome/app/breakpad_linux.h
+++ b/chrome/app/breakpad_linux.h
@@ -23,6 +23,8 @@ struct BreakpadInfo {
unsigned guid_length;
const char* distro;
unsigned distro_length;
+ const char* plugin_list;
+ unsigned plugin_list_length;
bool upload;
};
diff --git a/chrome/browser/crash_handler_host_linux.cc b/chrome/browser/crash_handler_host_linux.cc
index dc803ec..b779a5f9 100644
--- a/chrome/browser/crash_handler_host_linux.cc
+++ b/chrome/browser/crash_handler_host_linux.cc
@@ -233,6 +233,8 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) {
info.guid_length = strlen(guid);
info.distro = distro;
info.distro_length = strlen(distro);
+ info.plugin_list = "";
+ info.plugin_list_length = 0;
info.upload = upload;
HandleCrashDump(info);
}
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc
index 338b1f0..2109951 100644
--- a/webkit/glue/plugins/plugin_list.cc
+++ b/webkit/glue/plugins/plugin_list.cc
@@ -15,6 +15,13 @@
#include "webkit/glue/webkit_glue.h"
#include "googleurl/src/gurl.h"
+#if defined(USE_LINUX_BREAKPAD)
+namespace {
+// Comma-separated list of loaded plugin filenames.
+std::string loaded_plugin_list;
+} // anonymous namespace
+#endif
+
namespace NPAPI {
base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED);
@@ -74,7 +81,14 @@ bool PluginList::ReadPluginInfo(const FilePath &filename,
// Not an internal plugin.
*entry_points = NULL;
- return PluginLib::ReadWebPluginInfo(filename, info);
+ bool ret = PluginLib::ReadWebPluginInfo(filename, info);
+
+#if defined(USE_LINUX_BREAKPAD)
+ if (ret)
+ loaded_plugin_list.append(filename.BaseName().value() + ",");
+#endif
+
+ return ret;
}
bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi,
@@ -161,6 +175,10 @@ void PluginList::LoadPlugins(bool refresh) {
internal_plugins = internal_plugins_;
}
+#if defined(USE_LINUX_BREAKPAD)
+ loaded_plugin_list.clear();
+#endif
+
base::TimeTicks start_time = base::TimeTicks::Now();
std::vector<WebPluginInfo> new_plugins;
@@ -348,4 +366,13 @@ void PluginList::Shutdown() {
// TODO
}
-} // namespace NPAPI
+#if defined(USE_LINUX_BREAKPAD)
+// static
+// WARNING: This is called when we are in the middle of a browser crash.
+// This function may not call into libc nor allocate memory.
+std::string* PluginList::GetLoadedPlugins() {
+ return &loaded_plugin_list;
+}
+#endif
+
+} // namespace NPAPI
diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h
index ddb30cf..822ac05 100644
--- a/webkit/glue/plugins/plugin_list.h
+++ b/webkit/glue/plugins/plugin_list.h
@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef WEBKIT_GLUE_PLUGIN_PLUGIN_LIST_H__
-#define WEBKIT_GLUE_PLUGIN_PLUGIN_LIST_H__
+#ifndef WEBKIT_GLUE_PLUGINS_PLUGIN_LIST_H_
+#define WEBKIT_GLUE_PLUGINS_PLUGIN_LIST_H_
-#include <set>
#include <string>
#include <vector>
@@ -24,8 +23,7 @@ struct DefaultLazyInstanceTraits;
} // namespace base
-namespace NPAPI
-{
+namespace NPAPI {
#define kDefaultPluginLibraryName FILE_PATH_LITERAL("default_plugin")
#define kGearsPluginLibraryName FILE_PATH_LITERAL("gears")
@@ -132,6 +130,11 @@ class PluginList {
void LoadPlugin(const FilePath& filename,
std::vector<WebPluginInfo>* plugins);
+#if defined(USE_LINUX_BREAKPAD)
+ // Get a comma separated string with the list of successfully loaded plugins.
+ static std::string* GetLoadedPlugins();
+#endif
+
private:
// Constructors are private for singletons
PluginList();
@@ -222,6 +225,6 @@ class PluginList {
DISALLOW_COPY_AND_ASSIGN(PluginList);
};
-} // namespace NPAPI
+} // namespace NPAPI
-#endif // WEBKIT_GLUE_PLUGIN_PLUGIN_LIST_H__
+#endif // WEBKIT_GLUE_PLUGINS_PLUGIN_LIST_H_
diff --git a/webkit/glue/plugins/plugin_list_win.cc b/webkit/glue/plugins/plugin_list_win.cc
index 8b1fb01..b762a8f 100644
--- a/webkit/glue/plugins/plugin_list_win.cc
+++ b/webkit/glue/plugins/plugin_list_win.cc
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "webkit/glue/plugins/plugin_list.h"
+
#include <tchar.h>
-#include "webkit/glue/plugins/plugin_list.h"
+#include <set>
#include "base/basictypes.h"
#include "base/command_line.h"
@@ -193,7 +195,6 @@ void GetJavaDirectory(std::set<FilePath>* plugin_dirs) {
// value under the Java version key.
std::wstring java_plugin_directory;
if (java_key.ReadValue(kRegistryJavaHome, &java_plugin_directory)) {
-
// 4. The new plugin resides under the 'bin/new_plugin'
// subdirectory.
DCHECK(!java_plugin_directory.empty());
@@ -206,10 +207,9 @@ void GetJavaDirectory(std::set<FilePath>* plugin_dirs) {
}
}
-}
+} // anonymous namespace
-namespace NPAPI
-{
+namespace NPAPI {
void PluginList::PlatformInit() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
@@ -355,4 +355,4 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
return true;
}
-} // namespace NPAPI
+} // namespace NPAPI